图像匹配之brute-force算法

 最近在做图像检索算法(visual search)研究。图像检索本质上还是图像匹配,因此特征提取,特征匹配等步骤都是图像检索算法的核心和难点。直到现在图像检索技术还是处于比较原始的阶段,这一点用google搜图或者百度搜图可以看到,搜索的返回效果不是很令人满意。特征提取的难点在于,针对不同的物体需要不同的特征进行描述。针对于同一种物体,同一种匹配算法,不同的特征可能带来很多的不一样。目前用的比较多的是SIFT特征,SIFT特征具有旋转不变性和尺度不变性等优点,是图像匹配的优先选择。因此这里我选择用SIFT特征进行实验。第二个难点是图像匹配,目前的算法主要还是借鉴于文本检索的词袋模型算法。 
  

         图像匹配本质上是特征匹配。因为我们总可以将图像表示成多个特征向量的组成,因此如果两幅图片具有相同的特征向量越多,则可以认为两幅图片的相似程度越高。而特征向量的相似程度通常是用它们之间的欧氏距离来衡量,欧式距离越小,则可以认为越相似。

      匹配主要是用opencv对图像进行暴力匹配。依次找出两幅图像中相似度最高的两个特征向量,并将他们连线。用的是opencv内置算法,opencv用的是sift特征和FLANN算法进行最近距离计算。先贴代码,再看实验结果

#include 
#include 
#include
#include  
using namespace cv;
using namespace std;
int main(int argc, const char* argv[])
{
	//read image into mem
	IplImage *img1 = cvLoadImage("input3.jpg");
	IplImage *img2 = cvLoadImage("input_compiler.jpg");
	const Mat input = Mat(img1,false); 
	const Mat input2 = Mat(img2,false);
	//

    SiftFeatureDetector detector;
    vector keypoints1,keypoints2;
	detector.detect(input2,keypoints2);
    detector.detect(input, keypoints1);

	SiftDescriptorExtractor extractor;

	Mat descriptor1,descriptor2;

	extractor.compute(input,keypoints1,descriptor1);
	extractor.compute(input2,keypoints2,descriptor2);

	BruteForceMatcher>matcher;
	vectormatches;
	matcher.match(descriptor1,descriptor2,matches);

	double max_dist=0,min_dist = 100;
	for(int i=0;i < descriptor1.rows;++i)
	{
		double dist = matches[i].distance;
		if(dist < min_dist)min_dist = dist;
		if(dist > max_dist)max_dist = dist;
	}
	cout< goodMatch;
	for(int i=0;i < descriptor1.rows;++i)
	{
		if(matches[i].distance <= 150)goodMatch.push_back(matches[i]);
	}

	Mat img_matches;
	drawMatches(input,keypoints1,input2,keypoints2,goodMatch,img_matches);
	imshow("sift_matches.jpg",img_matches);
	waitKey(0);
    // Add results to image and save.
    Mat output;
    drawKeypoints(input, keypoints1, output);
	
    imwrite("output1.jpg", output);
	
    return 0;
}

分别用几张图片进行实验,结果如下:


    
















 
  

你可能感兴趣的:(图像)