【OpenCV】SIFT特征提取

本文详细介绍了图像处理中的关键算法,包括特征点提取、特征向量提取、特征向量匹配等步骤,并通过实例展示了如何使用SIFT算法进行特征点匹配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自己mark下

#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <vector>
#include <string>
#include <tchar.h>
#include <io.h>

using namespace cv;
using namespace std;


void getFiles( string path, string exd, vector<string>& files )
{
	//文件句柄
	long   hFile   =   0;
	//文件信息
	struct _finddata_t fileinfo;
	string pathName, exdName;


	if (0 != strcmp(exd.c_str(), ""))
	{
		exdName = "\\*." + exd;
	}
	else
	{
		exdName = "\\*";
	}
	
	if((hFile = _findfirst(pathName.assign(path).append(exdName).c_str(),&fileinfo)) !=  -1)
	{
		do
		{
			//如果是文件夹中仍有文件夹,迭代之
			//如果不是,加入列表
			if((fileinfo.attrib &  _A_SUBDIR))
			{
				if(strcmp(fileinfo.name,".") != 0  &&  strcmp(fileinfo.name,"..") != 0)
					getFiles( pathName.assign(path).append("/").append(fileinfo.name), exd, files );
			}
			else
			{
				if(strcmp(fileinfo.name,".") != 0  &&  strcmp(fileinfo.name,"..") != 0)
					files.push_back(pathName.assign(path).append("/").append(fileinfo.name));
			}
		}while(_findnext(hFile, &fileinfo)  == 0);
		_findclose(hFile);
	}
}
int _tmain(int argc, _TCHAR* argv[])
{
	char * filePath = "C:/数据集/图片集/Data";
	vector<string> files;
	//ofstream outfile("C:/abc.txt");
	//获取该路径下的所有jpg文件
	getFiles(filePath, "jpg", files);


	int size = files.size();
	for (int i = 0;i < size;i++)
	{
		cout<<files[i].c_str()<<endl;
		Mat input1 = imread(files[i].c_str(), CV_LOAD_IMAGE_GRAYSCALE);
			for (int i = 0;i < size;i++)
			{
				 Mat input2 = imread(files[i].c_str(), CV_LOAD_IMAGE_GRAYSCALE);
				 if (input1.empty()||input2.empty())
					{
						cout << "不能正常加载图片" << endl;
						system("pause");
						return -1;
					}
    /************************************************************************/
    /*下面进行提取特征点*/
    /************************************************************************/
    SiftFeatureDetector feature;
    vector<KeyPoint> kerpoints1;
    feature.detect(input1, kerpoints1);
    Mat output1;
    drawKeypoints(input1, kerpoints1, output1);
    vector<KeyPoint> kerpoints2;
    feature.detect(input2, kerpoints2);
    Mat output2;
    drawKeypoints(input2, kerpoints2, output2);
    //imshow("提取特征点后的box.png", output1);
    //imshow("提取特征点后的box_in_scene.png", output2);
    //imwrite("提取特征点后的box.png", output1);
    //imwrite("提取特征点后的box_in_scene.png", output2);
   // cout << "box提取的特征点数为:" << kerpoints1.size() << endl;
   // cout << "box_in_scene的特征点数为:" << kerpoints2.size() << endl;
    /************************************************************************/
    /* 下面进行特征向量提取 */
    /************************************************************************/
    SiftDescriptorExtractor descript;
    Mat description1;
    descript.compute(input1, kerpoints1, description1);
    Mat description2;
    descript.compute(input2, kerpoints2, description2);
    /************************************************************************/
    /* 下面进行特征向量临近匹配 */
    /************************************************************************/
    vector<DMatch> matches;
    FlannBasedMatcher matcher;
    Mat image_match;
    matcher.match(description1, description2, matches);
    /************************************************************************/
    /* 下面计算向量距离的最大值与最小值 */
    /************************************************************************/
    double max_dist = 0, min_dist = 100;
    for (int i = 0; i < description1.rows; i++)
    {
        if (matches.at(i).distance>max_dist)
        {
            max_dist = matches[i].distance;
        }
        if (matches[i].distance<min_dist)
        {
            min_dist = matches[i].distance;
        }
    }
    //cout << "最小距离为" << min_dist << endl;
    //cout << "最大距离为" << max_dist << endl;
    /************************************************************************/
    /* 得到距离小于而V诶最小距离的匹配 */
    /************************************************************************/
    vector<DMatch> good_matches;
    for (int i = 0; i < matches.size(); i++)
    {
        if (matches[i].distance<2*min_dist)
        {
            good_matches.push_back(matches[i]);
            //cout <<"第一个图中的"<< matches[i].queryIdx<<"匹配了第二个图中的"<<matches[i].trainIdx<<endl;
        }
    }
    //drawMatches(input1, kerpoints1, input2, kerpoints2, good_matches, image_match);
    //imshow("匹配后的图片", image_match);
    //imwrite("匹配后的图片.png", image_match);
    cout << "匹配的特征点数为:" << good_matches.size() << endl;


			ofstream outfile("D:/abc.txt",ios::app);
				outfile<<good_matches.size() <<" ";
			}
			ofstream outfile("D:/abc.txt",ios::app );
			outfile << ";" << endl;
				
	}	
//	Mat input1 = imread("C:/数据集/图片集/Data/001.jpg", CV_LOAD_IMAGE_GRAYSCALE);
//    Mat input2 = imread("C:/数据集/图片集/Data/002.jpg", CV_LOAD_IMAGE_GRAYSCALE);
	
    //waitKey(0);
	//system("pause");
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值