opencv4中的sift、surf受专利保护,不能直接使用,所以需要自己动手编译相关的库。
1. 下载opencv与opencv-contrib代码,其中下载的版本为4.1.2,另外还需要cmake工具。它们具体的下载地址如下:
Opencv: https://github.com/opencv/opencv/releases
Opencv_contrib: https://github.com/opencv/opencv_contrib/releases
Cmake: https://cmake.org/download/
2. make工作,需要编译opencv与opencv-contrib。添加额外的功能,如sift和surf等收费功能,需要勾选OPENCV_ENABLE_NONFREE,配置OPENCV_EXTRA_MODULES_PATH。
于是opencv4.1.2-cmake中就有相关的编译文件。
注意:在configure过程中会出现问题,比如找不到ippicv、ffmpeg与xfeatures2d相关文件,主要的原因是网址访问错误导致的原因,服务器连接不上需要修改:
把raw.githubusercontent.com修改为raw.staticdn.net
具体修改的cmake文件:
*\opencv_contrib-4.1.2\modules\xfeatures2d\cmake:
download_boostdesc.cmake download_vgg.cmake
*\opencv-4.1.2\3rdparty\ffmpeg:ffmpeg.cmake
*\opencv-4.1.2\3rdparty\ippicv: ippicv.cmake
3. vs编译。打开make工作输出的文件目录,用vs打开OpenCV.sln工程,点击生成->批生成->选中ALL_BUILD与INSTALL,然后生成。(编译生成需要花一定的时间)
PS: 编译过程中会找不到python37_d.lib或python36_d.lib或python27_d.lib。
需要打开opencv工程中的binding/opencv_python3/外部依赖项/pyconfig.h,修改python37_d.lib为python37.lib,已经注释掉 #Py_DEBUG
4. 编译结果验证。编译成功之后make目录中就会有install目录,该目录就是opencv的函数库。
First of all:配置opencv的环境变量,在PATH中添加*\cmake\install\x64\vc16\bin
(1) 创建空的C++工程;
(2) 打开该工程的属性,配置VC++目录中的包含目录与库目录
(3) 链接器->输入->添加依赖库,这里为*\opencv4.1.2-cmake\install\x64\vc16\lib\的lib文件,其中release是不带d的lib文件,debug是带d的lib文件。
PS: 文件比较多,可以在cmd中输入dir /b *d.lib>debug.txt dir /b *412.lib>release.txt,方可得到debug和release模式不同的依赖项。如果觉得复制这些lib名称比较麻烦,还可以将这些lib编译成一个lib文件,也就是opencv_world,因此需要在cmake中勾选BUILD_opencv_world。
5. 测试sift特征
(1) 创建.cpp相关代码文件;
(2) 代码如下:
#include
#include
int main(int argc, char** argv) {
cv::Mat box = imread("1.png");
cv::Mat box_in_sence = imread("2.png");
// 创建SIFT对象
cv::xfeatures2d::SIFT detector = cv::xfeatures2d::SIFT::create();
std::vector kpts_01, kpts_02;
cv::Mat descriptors1, descriptors2;
detector->detectAndCompute(box, cv::Mat(), kpts_01, descriptors1);
detector->detectAndCompute(box_in_sence, cv::Mat(), kpts_02, descriptors2);
// 定义描述子匹配 - 暴力匹配
cv::Ptr matcher = Dcv::escriptorMatcher::create(cv::DescriptorMatcher::BRUTEFORCE);
std::vector< cv::DMatch > matches;
matcher->match(descriptors1, descriptors2, matches);
// 绘制匹配
cv::Mat img_matches;
cv::drawMatches(box, kpts_01, box_in_sence, kpts_02, matches, img_matches);
cv::imshow("Matches", img_matches);
cv::imwrite("D:/result.png", img_matches);
cv::waitKey(0);
return 0;
}
(3) 效果图