/******************************************************
*欢迎到www.opencvchina.com下载源代码和资料
* Code by Utkarsh Sinha
* Based on JIFT by Jun Liu
* Visit http://aishack.in/ for more indepth articles and tutorials
* on artificial intelligence
* Use, reuse, modify, hack, kick. Do whatever you want with
* this code :)
******************************************************/
#include "stdafx.h"
#include <stdio.h>
#include "SIFT.h"
#define SIGMA_ANTIALIAS 0.5
#define SIGMA_PREBLUR 1.0
#define CURVATURE_THRESHOLD 5.0
#define CONTRAST_THRESHOLD 0.03 // in terms of 255
#define M_PI 3.1415926535897932384626433832795
#define NUM_BINS 36
#define MAX_KERNEL_SIZE 20
#define FEATURE_WINDOW_SIZE 16
#define DESC_NUM_BINS 8
#define FVSIZE 128
#define FV_THRESHOLD 0.2
// SaveFloatingPointImage()
// The standard HighGUI functions can save only 8bit images. This
// function converts a floating point image (with values 0..1) into
// a normal 8bit image (with values 0..255), and then saves it.
void SaveFloatingPointImage(const char *filename, IplImage* img)
{
IplImage* dup = cvCreateImage(cvGetSize(img), 8, 1);
cvCvtScale(img, dup, 255.0);
cvSaveImage(filename, dup);
cvReleaseImage(&dup);
}
// Constructor: Give a preloaded image and provide the desired number
// of octaves and intervals
SIFT::SIFT(IplImage* img, int octaves, int intervals)
{
// Store the image internally
m_srcImage = cvCloneImage(img);
// Set the number of octaves and intervals
m_numOctaves = octaves;
m_numIntervals = intervals;
// Proceed to initialize the algorithm
GenerateLists();
}
// Constructor: Give a filename and the desired number of octaves
// and intervals
SIFT::SIFT(const char* filename, int octaves, int intervals)
{
// Load the image
m_srcImage = cvLoadImage(filename);
// Set the number of octaves and intervals
m_numOctaves = octaves;
m_numIntervals = intervals;
// Proceed to initialize the algorithm
GenerateLists();
}
// AllocateMemory()
// This function allocates memory for the scale space (the multiple gaussian images,
// the difference of guassian images)
void SIFT::GenerateLists()
{
// A variable for the loops
unsigned int i=0;
// Create a 2D array of gaussian blurred images
m_gList = new IplImage**[m_numOctaves];
for(i=0;i<m_numOctaves;i++)
m_gList[i] = new IplImage*[m_numIntervals+3];
// Create a 2D array to store images generated after the
// DoG operation
m_dogList = new IplImage**[m_numOctaves];
for(i=0;i<m_numOctaves;i++)
m_dogList[i] = new IplImage*[m_numIntervals+2];
// Create a 2D array that will hold if a particular point
// is an extrema or not
m_extrema = new IplImage**[m_numOctaves];
for(i=0;i<m_numOctaves;i++)
m_extrema[i] = new IplImage*[m_numIntervals];
// Create a 2D array of decimal numbers. It holds the sigma
// used to blur the gaussian images.
m_absSigma = new double*[m_numOctaves];
for(i=0;i<m_numOctaves;i++)
m_absSigma[i] = new double[m_numIntervals+3];
}
// Destructor
// Cleanup after you're done
SIFT::~SIFT()
{
unsigned int i, j;
for(i=0;i<m_numOctaves;i++)
{
// Release all images in that particular octave
for(j=0;j<m_numIntervals+3;j++) cvReleaseImage(&m_gList[i][j]);
for(j=0;j<m_numIntervals+2;j++) cvReleaseImage(&m_dogList[i][j]);
for(j=0;j<m_numIntervals;j++) cvReleaseImage(&m_extrema[i][j]);
// Delete memory for that array
delete [] m_gList[i];
delete [] m_dogList[i];
delete [] m_extrema[i];
delete [] m_absSigma[i];
}
// Delete the 2D arrays
delete [] m_gList;
delete [] m_dogList;
delete [] m_extrema;
delete [] m_absSigma;
//printf("欢迎到www.opencvchina.com下载更多源代码和资料");
}
// DoSift()
// This function does everything in sequence.
void SIFT::DoSift()
{
BuildScaleSpace();
DetectExtrema();
AssignOrientations();
ExtractKeypointDescriptors();
}
// BuildScaleSpace()
// This function generates all the blurred out images for each octave
// and also the DoG images
void SIFT::BuildScaleSpace()
{
printf("Generating scale space...\n");
// For loops
unsigned int i,j;
// floating point grayscale image
IplImage* imgGray = cvCreateImage(cvGetSize(m_srcImage), IPL_DEPTH_32F , 1);
IplImage* imgTemp = cvCreateImage(cvGetSize(m_srcImage), 8 , 1);
// Create a duplicate. We don't want to mess the original
// If the image is colour, it is converted to grayscale
if(m_srcImage->nChannels==3)
{
cvCvtColor(m_srcImage, imgTemp, CV_BGR2GRAY);
}
else
{
cvCopy(m_srcImage, imgTemp);
}
// Finally, generate the floating point image... convert 0..255 range into 0..1
for(int x=0;x<imgTemp->width;x++)
{
for(int y=0;y<imgTemp->height;y++)
{
cvSetReal2D(imgGray, y, x, cvGetReal2D(imgTemp, y, x)/255.0);
}
}
// Lowe claims blur the image with a sigma of 0.5 and double it's dimensions
// to increase the number of stable keypoints
cvSmooth(imgGray, imgGray, CV_GAUSSIAN, 0, 0, SIGMA_ANTIALIAS);
// Create an image double the dimensions, resize imgGray and store it in m_gList[0][0]
m_gList[0][0] = cvCreateImage(cvSize(imgGray->width*2, imgGray->height*2), IPL_DEPTH_32F , 1);
cvPyrUp(imgGray, m_gList[0][0]);
// Preblur this base image
cvSmooth(m_gList[0][0], m_gList[0][0], CV_GAUSSIAN, 0, 0, SIGMA_PREBLUR);
// SaveFloatingPointImage("C:\\SIFT Test\\Gaussian\\g_octave_0_scale_0.jpg", m_gList[0][0]);
double initSigma = sqrt(2.0f);
// Keep a track of the sigmas
m_absSigma[0][0] = initSigma * 0.5;
// Now for the actual image generation
for(i=0;i<m_numOctaves;i++)
{
// Reset sigma for each octave
double sigma = initSigma;
CvSize currentSize = cvGetSize(m_gList[i][0]);
for(j=1;j<m_numIntervals+3;j++)
{
// Allocate memory
m_gList[i][j] = cvCreateImage(currentSize, 32, 1);
// Calculate a sigma to blur the current image to get the next one
double sigma_f = sqrt(pow(2.0,2.0/m_numIntervals)-1) * sigma;
sigma = pow(2.0,1.0/m_numIntervals) * sigma;
// Store sigma values (to be used later on)
m_absSigma[i][j] = sigma * 0.5 * pow(2.0f, (float)i);
// Apply gaussian smoothing)
cvSmooth(m_gList[i][j-1], m_gList[i][j], CV_GAUSSIAN, 0, 0, sigma_f);
// Calculate the DoG image
m_dogList[i][j-1] = cvCreateImage(currentSize, 32, 1);
cvSub(m_gList[i][j-1], m_gList[i][j], m_dogList[i][j-1]);
// Save the images generated for fun :)
/*char* filename = new char[200];
sprintf(filename, "C:\\SIFT Test\\Gaussian\\g_octave_%d_scale_%d.jpg", i, j);
SaveFloatingPointImage(filename, m_gList[i][j]);
sprintf(filename, "C:\\SIFT TEST\\DOG\\dog_octave_%d_scale_%d.jpg", i, j-1);
SaveFloatingPointImage(filename, m_dogList[i][j-1]);*/
}
// If we're not at the last octave
if(i<m_numOctaves-1)
{
// Reduce size to half
currentSize.width/=2;
currentSize.height/=2;
// Allocate memory and resample the image
m_gList[i+1][0] = cvCreateImage(currentSize, 32, 1);
cvPyrDown(m_gList[i][0], m_gList[i+1][0]);
m_absSigma[i+1][0] = m_absSigma[i][m_numIntervals];
// Store the image
/*char* filename = new char[200];
sprintf(filename, "C:\\SIFT Test\\Gaussian\\g_octave_%d_scale_0.jpg", i+1);
SaveFloatingPointImage(filename, m_gList[i+1][0]);*/
}
}
}
// DetectExtrema()
// Locates extreme points (maxima and minima)
// Relatively simple stuff
void SIFT::DetectExtrema()
{
printf("Detecting extrema...\n");
// Looping variables
unsigned int i, j, xi, yi;
// Some variables we'll use later on
double curvature_ratio, curvature_threshold;
IplImage *middle, *up, *down;
int scale;
double dxx, dyy, dxy, trH, detH;
unsigned int num=0; // Number of keypoins detected
unsigned int numRemoved=0; // The number of key points rejected because they failed a test
curvature_th
SIFT.zip_SIFT 特征点_SIFT特征_feature extract_特征匹配_特征提取
版权申诉
5星 · 超过95%的资源 14 浏览量
2022-07-15
10:31:58
上传
评论
收藏 12KB ZIP 举报
御道御小黑
- 粉丝: 58
- 资源: 1万+
最新资源
- 论文(最终)_20240430235101.pdf
- 基于python编写的Keras深度学习框架开发,利用卷积神经网络CNN,快速识别图片并进行分类
- 最全空间计量实证方法(空间杜宾模型和检验以及结果解释文档).txt
- 5uonly.apk
- 蓝桥杯Python组的历年真题
- 2023-04-06-项目笔记 - 第一百十九阶段 - 4.4.2.117全局变量的作用域-117 -2024.04.30
- 2023-04-06-项目笔记 - 第一百十九阶段 - 4.4.2.117全局变量的作用域-117 -2024.04.30
- 前端开发技术实验报告:内含4四实验&实验报告
- Highlight Plus v20.0.1
- 林周瑜-论文.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈