opencv3.4.8编译opencv-contrib并使用sift

下载源码

在github上,下载opencv3.4.8源码和opencv-contrib3.4.8源码
自己解压
网址自己找

安装下载cmake

网址自己找

使用cmake编译源码

记得一开始选好平台x64还是win32(我这x64),还有自己的vs平台(我这vs2015)
进去界面
上边文件夹是源码的文件夹(opencv3.4.8的)
下边是自己要编译到的文件夹(新建)
选好之后进行config

相关配置

  • (cuda)、world、enable_nonfree勾上,特别是这个enable_nonfree,没勾上害我整个过程来了很多遍
  • 设置extra:opencv_contrib-3.4.8\modules,注意转义字符双斜线
  • 注意config或者generate(我忘了是哪一步了)是否有报错,python的可不管,但是如有其他的需要仔细看一下:有时候编译过程中boostdesc_bgm还有vgg_generated_*下载失败,我直接自行从网上下载,网上有好心人挂到百度云上了,然后将文件夹内的文件复制到opencv_contrib-3.4.8/modules/xfeatures2d/src中,以及build\downloads\xfeatures2d 那个ippicv_windows包也很大很难下载,也可以自行下载,然后放到opencv3.4.8\3rdparty\ippicv\downloads\windows-04e81ce5d0e329c3fbc606ae32cad44d下替换即可!
  • 如果找不到这个缺失的文件可以找你新建的这个目录下,有个CMakeDownloadLog.txt,这个记录了缺少那些文件,应该从哪个网址下载之类的,你可以用xdown或者迅雷从哪个网址试试,我就是这么下载下来的,里边还说了那个文件夹下缺少,你可以自行下载后放进去,有的可能需要校验信息,之后把校验信息放到文件名中去,这个从原网址下载的应该问题不大,不放心的可以下个hash1.0.4试试,之后再修改名字。如果真不行,我记得这个部分有个博客,我暂时找不到了,可以再找找看看。
    *之后只要再进行config的时候不报错了,也就是CMakeDownloadLog.txt这个文件中没有那些需要下载的信息了,就是这部分没啥问题了

generate并open project编译

如果安装了相应版本的vs,就可以直接打开项目
进去后把ALL_Build和Install都重新生成一下,如果用release的话记得把环境改成release之后再点Install重新生成一下

使用

如果vs的除了python的之外都没有报错,那么就恭喜,可以用了(如果有报错说明cmake那里出问题了,再回去编译吧)
生成的编译好的opencv在你新建的这个文件夹下的install文件夹内
之后可以试试:

环境变量

把install\x64\vc14\bin添加到环境变量

工程属性

在测试工程中把c++目录中
包含目录设置:
install\include\opencv2
install\include\opencv
install\include
库目录:
install\x64\vc14\lib
链接器-输入:(这里将debug和release分开设置,我就把两个都设了一起,之后就是debug能用,release出问题,可能是release在用lib的时候加载成了debug的*d.lib,具体看这个博客https://blog.csdn.net/Winder_Sky/article/details/79380836)
lib在install\x64\vc14\lib
opencv_world348d.lib(debug的)
opencv_world348.lib(release的)

报错处理

可能一会跑代码的时候还会出现一个乱码的报错,意思好像是sift找不到,这就把install\x64\vc14\bin下的dll文件都拷到c:/windows/system32
(这个不知道可不可以在程序中加载,要不挺头疼的)

测试

使用代码测试,能跑起来就没问题了,暂时就想起这么多了,如果有什么忘记的之后再补

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
//#include <opencv2/>

using namespace std;
using namespace cv;

//这里进行dll库的引用 看看怎么不用直接添加到系统里就可以直接使用

int main()
{
	cv::Mat imageL = cv::imread("1.jpg");
	cv::Mat imageR = cv::imread("2.jpg");

	//提取特征点方法
	//SIFT
	cv::Ptr<cv::xfeatures2d::SIFT> sift = cv::xfeatures2d::SIFT::create();
	//ORB
	//cv::Ptr<cv::ORB> orb = cv::ORB::create();
	//SURF
	//cv::Ptr<cv::xfeatures2d::SURF> surf = cv::xfeatures2d::SURF::create();

	//特征点
	std::vector<cv::KeyPoint> keyPointL = {}, keyPointR = {};
	//单独提取特征点
	sift->detect(imageL, keyPointL);
	sift->detect(imageR, keyPointR);

	//画特征点
	cv::Mat keyPointImageL;
	cv::Mat keyPointImageR;
	drawKeypoints(imageL, keyPointL, keyPointImageL, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
	drawKeypoints(imageR, keyPointR, keyPointImageR, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

	//显示窗口
	cv::namedWindow("KeyPoints of imageL");
	cv::namedWindow("KeyPoints of imageR");

	//显示特征点
	cv::imshow("KeyPoints of imageL", keyPointImageL);
	cv::imshow("KeyPoints of imageR", keyPointImageR);

	//特征点匹配
	cv::Mat despL, despR;
	//提取特征点并计算特征描述子
	sift->detectAndCompute(imageL, cv::Mat(), keyPointL, despL);
	sift->detectAndCompute(imageR, cv::Mat(), keyPointR, despR);

	//Struct for DMatch: query descriptor index, train descriptor index, train image index and distance between descriptors.
	//int queryIdx –>是测试图像的特征点描述符( descriptor )的下标,同时也是描述符对应特征点(keypoint)的下标。
	//int trainIdx –> 是样本图像的特征点描述符的下标,同样也是相应的特征点的下标。
	//int imgIdx –>当样本是多张图像的话有用。
	//float distance –>代表这一对匹配的特征点描述符(本质是向量)的欧氏距离,数值越小也就说明两个特征点越相像。
	std::vector<cv::DMatch> matches;

	//如果采用 flannBased 方法 那么 desp通过orb的到的类型不同需要先转换类型
	if (despL.type() != CV_32F || despR.type() != CV_32F)
	{
		despL.convertTo(despL, CV_32F);
		despR.convertTo(despR, CV_32F);
	}

	cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("FlannBased");
	matcher->match(despL, despR, matches);

	//计算特征点距离的最大值 
	double maxDist = 0;
	for (int i = 0; i < despL.rows; i++)
	{
		double dist = matches[i].distance;
		if (dist > maxDist)
			maxDist = dist;
	}

	//挑选好的匹配点
	std::vector< cv::DMatch > good_matches;
	for (int i = 0; i < despL.rows; i++)
	{
		if (matches[i].distance < 0.5 * maxDist)
		{
			good_matches.push_back(matches[i]);
		}
	}



	cv::Mat imageOutput;
	cv::drawMatches(imageL, keyPointL, imageR, keyPointR, good_matches, imageOutput);

	cv::namedWindow("picture of matching");
	cv::imshow("picture of matching", imageOutput);
	cv::waitKey(0);
	return 0;
}

注意

问题1:在之后的操作中,我遇到了这个问题,一直困扰了一晚上,error lnk2019 class cv Mat __cdecl cv imread(class cv String const &,int)...找不到,就是不管怎么配置上述的那几个文件夹,还有设置环境变量,一直报的找不到opencv的库文件。这就证明其中肯定有个地方配置出问题了,但是是哪?经过一晚上的排查,发现不知为何,之前的配置中在 属性-C/C++-常规-附加包含目录 这里用的还是之前设置的一个早已不存在的目录,所以项目在找其中的问题的时候就首先找到这个地方标识的目录,没有在寻找VC++目录中我设置的文件。将其修改过来就好了,修改成opencv下的include目录即可。
这个问题可能是之前设置了默认配置文件导致的,以后在进行配置的时候尽可能检查全面,参考博客:https://blog.csdn.net/qq_21948547/article/details/106442731

参考博客:

https://blog.csdn.net/hellohake/article/details/104949245
https://blog.csdn.net/u011447369/article/details/107427137
https://blog.csdn.net/Winder_Sky/article/details/79380836

posted @ 2020-07-30 02:08  Philokami  阅读(935)  评论(0编辑  收藏  举报