小白记录:《Opencv3 编程入门》P417关于SIFT算法及示例程序

一.关于SIFT算法的工作原理这里参考这个博客
SIFT特征提取分析及Opencv API调用
https://blog.csdn.net/kuweicai/article/details/78876707

二.测试程序示例

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <iostream>
using namespace std;
using namespace cv;
using namespace xfeatures2d;

int main(int argc, char** argv)
{
	Mat srcImage = imread("E:\\pictures\\29.1.jpg");
 	if (srcImage.empty())
 	{
 		cout << "图片读取错误!" << endl;
  		return -1;
 	}
 	namedWindow("原图", WINDOW_AUTOSIZE);
 	imshow("原图", srcImage);

	int numFeatures = 1000;
 	Ptr<SIFT> detector = SIFT::create(numFeatures);
 	vector<KeyPoint> keypoints;
 	detector->detect(srcImage, keypoints, Mat());
 	cout << "总特征点数:" << keypoints.size() << endl;

	Mat keypoint_img;
 	drawKeypoints(srcImage, keypoints, keypoint_img, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
 	namedWindow("效果图", WINDOW_AUTOSIZE);
 	imshow("效果图", keypoint_img);

	waitKey(0);
 	return 0;
}

输出结果:
在这里插入图片描述
在这里插入图片描述
三.书上的代码:综合示例程序:SIFT配合暴力匹配进行关键点描述和提取
(因版本的不同,所以个别地方程序书写不一样,这里贴上改完后的,方便自己查阅)
运行下面程序时我的环境配置:VS2019+Opencv4.1.1_contrib

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <iostream>
using namespace std;
using namespace cv;
using namespace xfeatures2d;

int main()
{
	Mat trainImage = imread("E:\\pictures\\36.jpg"), trainImage_gray;
 	imshow("原始图", trainImage);
 	cvtColor(trainImage, trainImage_gray, COLOR_BGR2GRAY);

	//【2】检测SIFT关键点、提取训练图像描述符
 	vector<KeyPoint> train_keyPoint;
 	Mat trainDescription;
 	Ptr<SIFT> featureDetector = SIFT::create();
 	//SiftFeatureDetector featureDetector;
 	featureDetector->detect(trainImage_gray, train_keyPoint);
 	Ptr<SIFT> featureExtractor = SIFT::create();
 	//SiftDescriptorExtractor featureExtractor;
 	featureExtractor->compute(trainImage_gray, train_keyPoint, trainDescription);

	// 【3】进行基于描述符的暴力匹配
 	BFMatcher matcher;
 	vector<Mat> train_desc_collection(1, trainDescription);
 	matcher.add(train_desc_collection);
 	matcher.train();

	//【4】创建视频对象、定义帧率
 	VideoCapture cap(0);
 	unsigned int frameCount = 0;//帧数

	//【5】不断循环,直到q键被按下
 	while (char(waitKey(1)) != 'q')
 	{
 		//<1>参数设置
  		double time0 = static_cast<double>(getTickCount());//记录起始时间
  		Mat captureImage, captureImage_gray;
  		cap >> captureImage;//采集视频到testImage中
  		if (captureImage.empty())
  			continue;

		//<2>转化图像到灰度
  		cvtColor(captureImage, captureImage_gray, COLOR_BGR2GRAY);

		//<3>检测SURF关键点、提取测试图像描述符
  		vector<KeyPoint> test_keyPoint;
  		Mat testDescriptor;
  		featureDetector->detect(captureImage_gray, test_keyPoint);
  		featureExtractor->compute(captureImage_gray, test_keyPoint, testDescriptor);

		//<4>匹配训练和测试描述符
  		vector<vector<DMatch> > matches;
  		matcher.knnMatch(testDescriptor, matches, 2);

		// <5>根据劳氏算法(Lowe's algorithm),得到优秀的匹配点
  		vector<DMatch> goodMatches;
  		for (unsigned int i = 0; i < matches.size(); i++)
  		{
  			if (matches[i][0].distance < 0.6 * matches[i][1].distance)
    			goodMatches.push_back(matches[i][0]);
  		}

		//<6>绘制匹配点并显示窗口
  		Mat dstImage;
  		drawMatches(captureImage, test_keyPoint, trainImage, train_keyPoint, goodMatches, dstImage);
  		imshow("匹配窗口", dstImage);

		//<7>输出帧率信息
  		cout << "\t>当前帧率为:" << getTickFrequency() / (getTickCount() - time0) << endl;
 	}
	return 0;
}
发布了25 篇原创文章 · 获赞 0 · 访问量 458

猜你喜欢

转载自blog.csdn.net/qq_45445740/article/details/103483356