opencv_contrib安裝筆記


近來由於需要用到 opencv 的SIFT特徵,但是SIFT等功能已經移入了opencv_contrib 中,所以需要重新編譯opencv和opencv_contrib。

一、下載與安裝

  1. 下載特定版本的 opencvopencv_contrib,兩者版本要一致。但是由於國內下載GitHub 有時候會非常慢,所以可以下載碼雲上面的庫(opencv碼雲庫opencv_contrib碼雲庫)。


    下載 CMake(https://cmake.org/download/)
  2. 下載並安裝 visual studio ,安裝時添加使用C++的桌面開發
  3. 安裝 CMake ,用CMake編譯opencv和opencv_contrib

    opencv 的 Windows安裝包實質上是一個自解壓文件,雙擊解壓即可。

二、編譯 opencv


注意 source code 裏面指向的不是opencv的解壓目錄而是裏面的source目錄。
如圖所示, source 文件夾下面有一個CMakeList.txt文件,如果路徑錯誤,就會報CMake Error: The source directory "/opencv" does not appear to contain CMakeLists.txt.錯誤。

build 目錄爲自己建立的空目錄
點擊“ config ”

如下,看到自己安裝的 visual studio 版本,點擊finish。

開始編譯,等待。

運氣不好的話下方出現紅色字體,就是有錯誤出現。如下圖所示,是一些文件下載失敗

IPPICV: Download failed: 28;"Timeout was reached"
FFMPEG: Download failed: 6;"Couldn't resolve host name"
FFMPEG: Download failed: 6;"Couldn't resolve host name"
FFMPEG: Download failed: 6;"Couldn't resolve host name"

打開日誌文件,使用裏面的地址從瀏覽器裏面下載文件。

文件下載之後,放置在文件相應位置,並修改文件名。

可以看到原本路徑下文件下載失敗,所以是 0KB ,所以需要手動下載下來進行替換。
替換之後:

由於這幾個文件可能下載起來比較慢,這裏提供網盤鏈接:

ippicv_2019 鏈接: https://pan.baidu.com/s/1vk0QUsiEeZvbwxcbM1dXcA 提取碼:izh2
ippicv_2017 鏈接: https://pan.baidu.com/s/1enrzXCm_BCgSOw-vnMJMpg 提取碼:dsit
opencv_ffmpeg.dll 鏈接: https://pan.baidu.com/s/1qa4maq1mBKlCLJCTSRZ4PA 提取碼:cdes
opencv_ffmpeg_64.dll 鏈接: https://pan.baidu.com/s/1WaL0h8NhmA2yW941-00_OQ 提取碼:ryhy

當 CMake 界面上下兩塊都沒有紅色部分,且下方出現了Configuring done,點擊generate按鈕

直到下方出現
Configuring done Generating done
此時說明 opencv 基本庫編譯完成。

三、編譯 opencv_contrib

在 search 對話框中輸入OPENCV_EXTRA_MODULES_PATH,找到OPENCV_EXTRA_MODULES_PATH後在value中填入編譯opencv_contrib解壓目錄中的modules路徑(注意此處路徑的反斜槓\要改成正斜槓/,反斜槓\有轉義字符的意思)。目錄錯誤則會出現Error in configuration process, project files may be invalid彈窗錯誤提醒。


以下爲路徑錯誤時的彈窗:

在搜索欄中輸入 OPENCV_ENABLE_NONFREE ,在value值中點擊選中。如果沒有選中,那麼類似SIFT這種已經被申請專利的方法就無法使用。
然後點擊 configure

在下方出現 Configuring done 之後,點擊Generate

和 opencv 基本庫編譯一樣,CMake下方出現Configuring done Generating done,說明opencv_contrib 編譯完成。

四、 visual studio 編譯

然後點擊 Open Project ,會使用之前選擇的特定版本visual studio打開。

選擇 生成->批生成

在彈出的窗口裏面選擇的 debug 和release的ALL_BUILD和INATALL,然後點擊“生成”。

該過程會需要較長時間。

五、配置 opencv 環境

配置系統環境變量

生成結束之後,需要修改環境變量。

環境變量在“此電腦”->“屬性”->“高級系統設置”->“環境變量”,在用戶變量裏面的 Path 變量後面添加之前CMake設置的build目錄\install\x64\vc16\bin,確定,退出。

如果 visual studio 在修改環境變量之前就打開了,需要重啓visual studio

重新配置項目環境

visual studio 中右擊項目->“屬性”,

首先可以選擇“所有配置” “所有平臺”,編輯包含目錄和庫目錄
包含目錄編輯爲

生成的 build 目錄\install\include
生成的 build 目錄\install\include\opencv2

庫目錄編輯爲:

生成的 build 目錄\install\x64\vc16\lib




編輯包含目錄和庫目錄之後,需要添加附加依賴項,此時需要分別針對 debug 和release兩種模式添加。
打開 生成的build目錄\install\x64\vc16\lib可以發現每個lib文件都有兩種,一種是以d.lib結尾,另一種只比前一種少了一個d,只以.lib結尾。debug模式需要d.lib結尾文件,release模式需要.lib結尾文件,任何一種模式配置錯誤,就不能以該模式運行opencv。

所以需要在編輯附加依賴項時添加各自需要的文件名。



可以通過命令行整理,也可以用下面的:
debug 模式:

opencv_aruco410d.lib
opencv_bgsegm410d.lib
opencv_bioinspired410d.lib
opencv_calib3d410d.lib
opencv_ccalib410d.lib
opencv_core410d.lib
opencv_datasets410d.lib
opencv_dnn410d.lib
opencv_dnn_objdetect410d.lib
opencv_dpm410d.lib
opencv_face410d.lib
opencv_features2d410d.lib
opencv_flann410d.lib
opencv_fuzzy410d.lib
opencv_gapi410d.lib
opencv_hfs410d.lib
opencv_highgui410d.lib
opencv_imgcodecs410d.lib
opencv_imgproc410d.lib
opencv_img_hash410d.lib
opencv_line_descriptor410d.lib
opencv_ml410d.lib
opencv_objdetect410d.lib
opencv_optflow410d.lib
opencv_phase_unwrapping410d.lib
opencv_photo410d.lib
opencv_plot410d.lib
opencv_quality410d.lib
opencv_reg410d.lib
opencv_rgbd410d.lib
opencv_saliency410d.lib
opencv_shape410d.lib
opencv_stereo410d.lib
opencv_stitching410d.lib
opencv_structured_light410d.lib
opencv_superres410d.lib
opencv_surface_matching410d.lib
opencv_text410d.lib
opencv_tracking410d.lib
opencv_video410d.lib
opencv_videoio410d.lib
opencv_videostab410d.lib
opencv_xfeatures2d410d.lib
opencv_ximgproc410d.lib
opencv_xobjdetect410d.lib
opencv_xphoto410d.lib


release 模式:

opencv_aruco410.lib
opencv_bgsegm410.lib
opencv_bioinspired410.lib
opencv_calib3d410.lib
opencv_ccalib410.lib
opencv_core410.lib
opencv_datasets410.lib
opencv_dnn410.lib
opencv_dnn_objdetect410.lib
opencv_dpm410.lib
opencv_face410.lib
opencv_features2d410.lib
opencv_flann410.lib
opencv_fuzzy410.lib
opencv_gapi410.lib
opencv_hfs410.lib
opencv_highgui410.lib
opencv_imgcodecs410.lib
opencv_imgproc410.lib
opencv_img_hash410.lib
opencv_line_descriptor410.lib
opencv_ml410.lib
opencv_objdetect410.lib
opencv_optflow410.lib
opencv_phase_unwrapping410.lib
opencv_photo410.lib
opencv_plot410.lib
opencv_quality410.lib
opencv_reg410.lib
opencv_rgbd410.lib
opencv_saliency410.lib
opencv_shape410.lib
opencv_stereo410.lib
opencv_stitching410.lib
opencv_structured_light410.lib
opencv_superres410.lib
opencv_surface_matching410.lib
opencv_text410.lib
opencv_tracking410.lib
opencv_video410.lib
opencv_videoio410.lib
opencv_videostab410.lib
opencv_xfeatures2d410.lib
opencv_ximgproc410.lib
opencv_xobjdetect410.lib
opencv_xphoto410.lib

六、測試

配置完成之後使用以下代碼測試(修改爲自己的圖片路徑):

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

using namespace std;
using namespace cv;

int main()
{
	cv::Mat imageL = cv::imread("origin_1.jpg");
	cv::Mat imageR = cv::imread("origin_2.jpg");
	/*imshow("1", imageL);
	imshow("2", imageR);
	waitKey();
	return 0;*/



	//提取特徵點方法
	//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. OpenCV 學習筆記 06 SIFT 使用中出現版權問題 error: (-213:The function/feature is not implemented)
  2. OpenCV3.1.0 安裝配置與 OpenCV_contrib庫配置
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章