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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM