保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

目录

0.写作背景

1.安装visual studio

2.下载OpenCV相关的源码

下载OpenCV原始的源码

下载OpenCV contrib的源码

下载安装cmake

3.cmake编译OpenCV

初始编译

CmakeDownload的bug修复

OpenCV-crontrib编译:

Generate生成代码

VS生成代码:

报错修复

4.Visual Studio配置变量

5.Case测试:

初始测试

SIFT算子测试

SURF算子测试

6.总结

7.参考链接:

8.预告:关于修改源码

0.写作背景

OpenCV可能是目前使用最广泛的开源图像处理工具了,尤其是在科研领域。

在读研期间进行图像拼接相关的科研工作时候,我遇到了和OpenCV相关很棘手的两个问题:

1.为什么的我的OpenCV安装不成功???

2.为什么我的OpenCV不能修改源码?

那个时候CSDN上的相关资料也不多,甚至现在关于OpenCV安装的很多问题,CSDN上说的也不算很清楚。与此同时那段时间也是自己比较艰难的一段时间,在OpenCV上花了很多时间和精力才终于解决了上述两个问题。我在此分享一下如何解决这两个问题。

本篇主要详细记录一下如何在Windows 操作系统下,搭建Visual Studio+OpenCV+OpenCV contrib的运行环境。

1.安装visual studio

关于安装visual studio,最保险的方法首先去官网下载安装器:

下载 Visual Studio Tools – 免费安装 Windows、Mac、Linux

暂时使用Community版本就好,尤其是对学生or个人用户而言。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

然后安装的时候,参考第一个”参考链接”(我自己安装的时候忘记截图了啦真的是很对不起了啦,谁要是质疑我就很机车了啦):

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

然后只要选择”使用C++的桌面开发”就好。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

然后一路默认安装就好。

本地随便建一个新项目运行:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

选择”控制台应用”:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

项目建立之后,点击”本地Windows调试器”:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

然后就可以运行输出HelloWorld了:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

2.下载OpenCV相关的源码

下载OpenCV原始的源码

既然要下载源码了,我们还是去OpenCV的官网,下载最新的release版本:

Releases – OpenCV

截止至2022年4月4号,最新的Release版本是OpenCV – 4.5.5。我们下载Sources(后面修改源码需要用到):

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

下载之后解压到特定文件夹,当前case之中我解压到了E:\Downloads\opencv-4.5.5

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

下载OpenCV contrib的源码

然后我们去下载OpenCV contrib,官网链接:

GitHub – opencv/opencv_contrib: Repository for OpenCV’s extra modules

Q:为什么要下载OpenCV contrib呢?

A:因为自从OpenCV 3.0之后,很多经典的算法,比如sift和surf特征点检测算法,由于专利原因,已经不包含在OpenCV的源码当中了,需要下载OpenCV contrib包才能继续使用。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

OpenCV contrib的版本记得要和OpenCV版本符合哦(例如上图我们选择的是4.X版本)。还是要下载源码哦。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

下载完解压,本文的路径为:E:\Downloads\opencv_contrib-4.x

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

下载安装cmake

之后我们还需要去下载cmake 用于编译OpenCV。

这里别下载错了下载成source了。在安装OpenCV的过程之中,我们只需要使用Cmake的gui程序图像化运行就好,不需要去管cmake的源码。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

下载完解压,本文的解压地址为:E:\Downloads\cmake-3.23.0-windows-x86_64。在bin目录下运行cmake-gui.exe即可。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

3.cmake编译OpenCV

前置工作结束就需要开始编译OpenCV了。

初始编译

1.第一步先按下图操作:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

2.弹窗出来的配置,按照自己的开发环境配置即可(本文的环境是VS 2022,平台是X64平台),然后点击”Finish”即可:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

3.cmake的窗口开始打印信息:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

打印出来的信息中如果出现python、matlab相关的报错,例如下图,直接pass。(Python……ptsd,想到python就ptsd……想起某人爱用python造轮子……)

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

这一步需要等到cmake初始编译完成。

CmakeDownload的bug修复

这一步很多博客都没有写清楚如何排查,导致很多新手在之后VisualStudio阶段导包的时候出错。

上一步完成之后,大部分情况下会报错。

不出意外会看到如下的报错信息。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

仔细阅读之后,我们应该查看一下CMakeDownloadLog.txt。

使用Notepad++或者其他软件打开CMakeDownloadLog.txt,

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

有时间的同学自己阅读和翻译。我直接说一下问题:Cmake去下载相关的包没有下载下来。

所以根据红框处的信息我们需要自行下载,方法:将链接输入到浏览器,然后就会自动下载。一些链接输入到浏览器之后,显示的是文本,那么就将文本拷贝到本地并重命名,如下图的cmake文件。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

这种情况,就ctrl+s保存,注意命名。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

此处我不把包上传到CSDN上,因为版本更新之后还是有可能遇到同样问题,希望后续OpenCV版本更新之后,大家能自行解决问题。

另外此处的链接可能会被屏蔽,大家自行找办法下载。

下载之后将这些包拷贝到.cache文件夹下,并且需要更改包的名字(cmake下载包之后将校验的hash码重命名到了包中),下图以ippcv包为例:

下载的包原名为:

ippicv_2020_win_intel64_20191018_general.zip

复制到CmakeDownloadLog.txt中的.cache文件夹下,并改名为:

879741a7946b814455eee6c6ffde2984-ippicv_2020_win_intel64_20191018_general.zip

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

其他的包同上。不赘述。

这些拷贝结束之后,我们重新configure:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

然后我们在看CmakeDownLoadLog.txt,已经不报错了:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

cmake也不标红和报错了:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

OpenCV-crontrib编译:

在cmake的OPENCV_EXTRA_MODULES_PATH之中输入之前下载的OpenCV-contrib的路径(精确到modules:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

再次configure,然后又看到一大堆报错:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

查看CmakeDownLoadLog.txt,是的,又来了:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

再次下载吧。(有一说一,多了好多微信二维码的内容,不愧是你,腾讯!不愧是你,化腾!)

下载完成,再次configure,并查看CmakeDownLoadLog.txt,好的不报错了。PS:如果过程中发现CmakeDownLoadLog.txt还是有报错,继续下载,继续复制。

另外在多次configure过程中,每次都会尝试从.cache文件中获取原始文件,再拷贝到build之后的文件夹下面,复制的过程也会打日志的。建议多点几次configure。

最后我们查看CmakeDownLoadLog.txt,我们会看到如下信息:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

终于都是match了,开心!

注:史前大坑:OPENCV_ENABLE_NONFREE一定要勾选上啊!否则Nonfree没法用。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

Generate生成代码

上述工作检查无误,到了这一步才可以点击Generate哦。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

VS生成代码:

找到build之后的OpenCV.sln文件,用VS打开。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

右键项目,并点击”重新生成解决方案”:

另外这里只是生成了debug版本,后面记得把Release版本也生成一下,Debug和Relea版本都生成之后,后续的代码才能在debug和release两个环境下运行。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

这一步会等很久,等待时间从2小时到12个小时不等。

(注:这里有点错误,参考了其他一些链接,实际上只需要对CMakeTargets文件夹下的Install进行重新生成即可,如下图,但是全部重新生成应该也不影响)。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

报错修复

之前安装OpenCV 3.X版本没有遇到过这个错误,这次遇到了,就尝试修复一下吧。参考链接4。

vs2022重新编译opencv-python cuda加速时报错_Harry Xu的博客-CSDN博客

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

解决方法的核心就是找到出错的文件,然后保存为Unicode格式的文件即可。

个人猜测这个问题不修复也不会怎么影响OpenCV大部分功能的使用。

然后重新生成,可以看到没有报错了(无论是debug还是release版本)。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

注:如果只重新生成INSTALL的话,之前的报错应该是不会出现的。

只重新生成INSTALL之后,可以看到170个项目都成功了。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

4.Visual Studio配置变量

我们首先创建一个空的”控制台应用”项目,就叫OpenCVtest。

然后先配置系统环境变量,Windows控制台搜索即可查询到。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

然后重启电脑才会生效。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

然后右键项目,更改属性:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

然后编辑VC++目录下的包含目录(其实就是英文版本的include path):

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

然后把install之后的include文件夹路径添加上去(注意,是install之后的include路径,不要填错成了其他的include路径)

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

然后我们编辑库目录(其实就是英文版的lib path)

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

把install之后的lin目录输入进去(再次强调是install之后的lib目录)

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

链接器->附加依赖项->编辑,输入所有的xxxxx/install\x64\vc16\lib中 所有 xxxd.lib文件名字:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

这里建议使用windows命令行操作获取所有的XXX455.lib文件名(455是opencv版本名字,不同版本的opencv安装后,敲命令行使用不同的版本号哦)。

操作命令如下:

dir *.*  /B  | findstr 455.lib

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

复制进去:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

然后我们开始测试。

5.Case测试:

为了验证我们安装OpenCV的效果,我们需要使用测试Case进行测试。

这里先测试OpenCV的基本功能,再使用SIFT算子和SURF算子进行测试。 由于SIFT算子和SURF算子都是OpenCV contrib里面才有的图像库,这两个算子能测试通过,说明OpenCV contrib安装完成(更正:opencv4.4之后sift又回到opencv普通库了……崩溃)。

初始测试

在项目中输入下述代码:

// OpenCVTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include
#include

int main()
{
    cv::Mat src = cv::imread("E:\\images\\00000.jpg");//图片路径
    if (src.empty())
    {
        std::cout << "pic is empty!\n";
        return -1;
    }
    cv::imshow("show", src);
    cv::waitKey(0);
    std::cout << "Hello World!\n";
}

运行结果:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

好了,说明能展示了。

SIFT算子测试

参考上述文章:

代码如下:

#include <opencv2 opencv.hpp>
#include <opencv2 xfeatures2d.hpp>
#include <opencv2 xfeatures2d nonfree.hpp> //OpenCV 4.2.0 &#x53CA;&#x4E4B;&#x540E;&#x7248;&#x672C;

int main()
{
    cv::Mat imageL = cv::imread("E:\\images\\3.jpg");
    cv::Mat imageR = cv::imread("E:\\images\\4.jpg");

    //&#x63D0;&#x53D6;&#x7279;&#x5F81;&#x70B9;&#x65B9;&#x6CD5;
    //SIFT
    //cv::Ptr<cv::xfeatures2d::sift> sift = cv::xfeatures2d::SIFT::create();
    cv::Ptr<cv::sift> sift = cv::SIFT::create(); //OpenCV 4.4.0 &#x53CA;&#x4E4B;&#x540E;&#x7248;&#x672C;
    //ORB
    //cv::Ptr<cv::orb> orb = cv::ORB::create();
    //SURF
    //cv::Ptr<cv::xfeatures2d::surf> surf = cv::xfeatures2d::SURF::create();

    //&#x7279;&#x5F81;&#x70B9;
    std::vector<cv::keypoint> keyPointL, keyPointR;
    //&#x5355;&#x72EC;&#x63D0;&#x53D6;&#x7279;&#x5F81;&#x70B9;
    sift->detect(imageL, keyPointL);
    sift->detect(imageR, keyPointR);

    //&#x753B;&#x7279;&#x5F81;&#x70B9;
    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);

    //&#x663E;&#x793A;&#x7A97;&#x53E3;
    cv::namedWindow("KeyPoints of imageL");
    cv::namedWindow("KeyPoints of imageR");

    //&#x663E;&#x793A;&#x7279;&#x5F81;&#x70B9;
    cv::imshow("KeyPoints of imageL", keyPointImageL);
    cv::imshow("KeyPoints of imageR", keyPointImageR);

    //&#x7279;&#x5F81;&#x70B9;&#x5339;&#x914D;
    cv::Mat despL, despR;
    //&#x63D0;&#x53D6;&#x7279;&#x5F81;&#x70B9;&#x5E76;&#x8BA1;&#x7B97;&#x7279;&#x5F81;&#x63CF;&#x8FF0;&#x5B50;
    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 &#x2013;>&#x662F;&#x6D4B;&#x8BD5;&#x56FE;&#x50CF;&#x7684;&#x7279;&#x5F81;&#x70B9;&#x63CF;&#x8FF0;&#x7B26;&#xFF08;descriptor&#xFF09;&#x7684;&#x4E0B;&#x6807;&#xFF0C;&#x540C;&#x65F6;&#x4E5F;&#x662F;&#x63CF;&#x8FF0;&#x7B26;&#x5BF9;&#x5E94;&#x7279;&#x5F81;&#x70B9;&#xFF08;keypoint)&#x7684;&#x4E0B;&#x6807;&#x3002;
    //int trainIdx &#x2013;> &#x662F;&#x6837;&#x672C;&#x56FE;&#x50CF;&#x7684;&#x7279;&#x5F81;&#x70B9;&#x63CF;&#x8FF0;&#x7B26;&#x7684;&#x4E0B;&#x6807;&#xFF0C;&#x540C;&#x6837;&#x4E5F;&#x662F;&#x76F8;&#x5E94;&#x7684;&#x7279;&#x5F81;&#x70B9;&#x7684;&#x4E0B;&#x6807;&#x3002;
    //int imgIdx &#x2013;>&#x5F53;&#x6837;&#x672C;&#x662F;&#x591A;&#x5F20;&#x56FE;&#x50CF;&#x7684;&#x8BDD;&#x6709;&#x7528;&#x3002;
    //float distance &#x2013;>&#x4EE3;&#x8868;&#x8FD9;&#x4E00;&#x5BF9;&#x5339;&#x914D;&#x7684;&#x7279;&#x5F81;&#x70B9;&#x63CF;&#x8FF0;&#x7B26;&#xFF08;&#x672C;&#x8D28;&#x662F;&#x5411;&#x91CF;&#xFF09;&#x7684;&#x6B27;&#x6C0F;&#x8DDD;&#x79BB;&#xFF0C;&#x6570;&#x503C;&#x8D8A;&#x5C0F;&#x4E5F;&#x5C31;&#x8BF4;&#x660E;&#x4E24;&#x4E2A;&#x7279;&#x5F81;&#x70B9;&#x8D8A;&#x76F8;&#x50CF;&#x3002;
    std::vector<cv::dmatch> matches;

    //&#x5982;&#x679C;&#x91C7;&#x7528;flannBased&#x65B9;&#x6CD5; &#x90A3;&#x4E48; desp&#x901A;&#x8FC7;orb&#x7684;&#x5230;&#x7684;&#x7C7B;&#x578B;&#x4E0D;&#x540C;&#x9700;&#x8981;&#x5148;&#x8F6C;&#x6362;&#x7C7B;&#x578B;
    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);

    //&#x8BA1;&#x7B97;&#x7279;&#x5F81;&#x70B9;&#x8DDD;&#x79BB;&#x7684;&#x6700;&#x5927;&#x503C;
    double maxDist = 0;
    for (int i = 0; i < despL.rows; i++)
    {
        double dist = matches[i].distance;
        if (dist > maxDist)
            maxDist = dist;
    }

    //&#x6311;&#x9009;&#x597D;&#x7684;&#x5339;&#x914D;&#x70B9;
    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;
}</cv::descriptormatcher></cv::dmatch></cv::keypoint></cv::xfeatures2d::surf></cv::orb></cv::sift></cv::xfeatures2d::sift></opencv2></opencv2></opencv2>

原始图像如下:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

运行结果:

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

SURF算子测试

代码如下,参考了:

【OpenCV】OpenCV 4 下 SIFT、SURF的使用_魏Gordon的博客-CSDN博客_opencv4 surf

#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/xfeatures2d/nonfree.hpp"
#include "opencv2/xfeatures2d.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/imgproc.hpp"
#include
#include
#include
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;

int main()
{
    //【0】改变console字体颜色
    system("color 1F");

    //【1】载入原始图片
    Mat srcImage1 = imread("E:/images/3.jpg", 1);
    Mat srcImage2 = imread("E:/images/4.jpg", 1);
    Mat copysrcImage1 = srcImage1.clone();
    Mat copysrcImage2 = srcImage2.clone();

    if (!srcImage1.data || !srcImage2.data)
    {
        printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false;
    }

    //【2】使用SURF算子检测关键点
    int minHessian = 100;//SURF算法中的hessian阈值

    Ptr detector = SURF::create(minHessian);//定义一个SurfFeatureDetector(SURF) 特征检测类对象
    // Ptr detector = cv::xfeatures2d::SURF::create(400);

    vector keypoints_object, keypoints_scene;//vector模板类,存放任意类型的动态数组

    //【3】调用detect函数检测出SURF特征关键点,保存在vector容器中
    detector->detect(srcImage1, keypoints_object);
    detector->detect(srcImage2, keypoints_scene);

    //【4】计算描述符(特征向量)
    Ptr extractor = SURF::create();

    Mat descriptors_object, descriptors_scene;
    extractor->compute(srcImage1, keypoints_object, descriptors_object);
    extractor->compute(srcImage2, keypoints_scene, descriptors_scene);

    //【5】使用FLANN匹配算子进行匹配
    FlannBasedMatcher matcher;
    vector< DMatch > matches;
    matcher.match(descriptors_object, descriptors_scene, matches);
    double max_dist = 0; double min_dist = 100;//最小距离和最大距离

    //【6】计算出关键点之间距离的最大值和最小值
    for (int i = 0; i < descriptors_object.rows; i++)
    {
        double dist = matches[i].distance;
        if (dist < min_dist) min_dist = dist;
        if (dist > max_dist) max_dist = dist;
    }

    printf(">Max dist 最大距离 : %f \n", max_dist);
    printf(">Min dist 最小距离 : %f \n", min_dist);

    //【7】存下匹配距离小于3*min_dist的点对
    std::vector< DMatch > good_matches;
    for (int i = 0; i < descriptors_object.rows; i++)
    {
        if (matches[i].distance < 3 * min_dist)
        {
            good_matches.push_back(matches[i]);
        }
    }

    //绘制出匹配到的关键点
    Mat img_matches;
    drawMatches(srcImage1, keypoints_object, srcImage2, keypoints_scene,
        good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
        vector(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

    //定义两个局部变量
    vector obj;
    vector scene;

    //从匹配成功的匹配对中获取关键点
    for (unsigned int i = 0; i < good_matches.size(); i++)
    {
        obj.push_back(keypoints_object[good_matches[i].queryIdx].pt);
        scene.push_back(keypoints_scene[good_matches[i].trainIdx].pt);
    }
    vector listpoints;

    //Mat H = findHomography( obj, scene, CV_RANSAC );//计算透视变换
    Mat H = findHomography(obj, scene, RANSAC, 3, listpoints);//计算透视变换

    std::vector< DMatch > goodgood_matches;
    for (int i = 0; i < listpoints.size(); i++)
    {
        if ((int)listpoints[i])
        {

            goodgood_matches.push_back(good_matches[i]);

            cout << (int)listpoints[i] << endl;
        }

    }
    cout << "listpoints大小:" << listpoints.size() << endl;
    cout << "goodgood_matches大小:" << goodgood_matches.size() << endl;
    cout << "good_matches大小:" << good_matches.size() << endl;
    Mat Homgimg_matches;
    drawMatches(copysrcImage1, keypoints_object, copysrcImage2, keypoints_scene,
        goodgood_matches, Homgimg_matches, Scalar::all(-1), Scalar::all(-1),
        vector(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

    imshow("去除误匹配点后;", Homgimg_matches);

    //从待测图片中获取角点
    vector obj_corners(4);
    obj_corners[0] = cvPoint(0, 0); obj_corners[1] = cvPoint(srcImage1.cols, 0);
    obj_corners[2] = cvPoint(srcImage1.cols, srcImage1.rows); obj_corners[3] = cvPoint(0, srcImage1.rows);
    vector scene_corners(4);

    //进行透视变换
    perspectiveTransform(obj_corners, scene_corners, H);

    //绘制出角点之间的直线
    line(img_matches, scene_corners[0] + Point2f(static_cast(srcImage1.cols), 0), scene_corners[1] + Point2f(static_cast(srcImage1.cols), 0), Scalar(255, 0, 123), 4);
    line(img_matches, scene_corners[1] + Point2f(static_cast(srcImage1.cols), 0), scene_corners[2] + Point2f(static_cast(srcImage1.cols), 0), Scalar(255, 0, 123), 4);
    line(img_matches, scene_corners[2] + Point2f(static_cast(srcImage1.cols), 0), scene_corners[3] + Point2f(static_cast(srcImage1.cols), 0), Scalar(255, 0, 123), 4);
    line(img_matches, scene_corners[3] + Point2f(static_cast(srcImage1.cols), 0), scene_corners[0] + Point2f(static_cast(srcImage1.cols), 0), Scalar(255, 0, 123), 4);

    //显示最终结果
    imshow("效果图", img_matches);

    waitKey(0);
    return 0;
}

测试结果如下。

保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

在OpenCV4.X版本中,SURF依然是OpenCV contrib中的代码。SURF代码测试成功,说明我们的安装已经成功了。

看到这里的都不容易,大家休息一下吧,下一步就可以考虑修改源码啦。

6.总结

OpenCV的安装的确是一个非常复杂和麻烦的过程,即使我之前已经有了成功安装的经验,这一次安装(加写教程)还是花了我大约一天的时间。

在安装过程中,主要注意以下几点:

1.cmake阶段注意查看Cmake的报错信息,及时检查CMakeDownLog.txt文件;

2.根据日志文件自行下载相应的依赖;

3.最后的测试case能够跑通才算完成整个安装流程。

7.参考链接:

VS2019+OpenCV4.1.0安装及整合详细步骤 – 简书

OpenCV3.3+contrib+VS2017+CMake+Win10_码代马的博客-CSDN博客

OpenCV+opencv_contrib+VS2015+CMake+Win10编译过程_TechGreat的博客-CSDN博客_cmake opencv_contrib

vs2022重新编译opencv-python cuda加速时报错_Harry Xu的博客-CSDN博客 win10 +visual studio 2019 +opencv4.5.0+opencv_contrib4.5.0源码编译安装_语符律的博客-CSDN博客_win10安装opencv4.5

OpenCV3.4.0+Visual Studio2017配置 – 上中下,高平宽 – 博客园

opencv::sift特征提取 – osbreak – 博客园

【VS2017】【OpenCV4.0.0】调用SIFT出错_啊吼!的博客-CSDN博客

8.预告:关于修改源码

安装OpenCV已经这么费劲了,不如继续改改源码?

关于如何修改OpenCV的源码(以修改SURF算子为例),请参考下一篇文章:

OpenCV 修改源码:基于hpp文件,修改SURF算子(支持打断点、调试、debug)_树叶的叶and开心的开的博客-CSDN博客

Original: https://blog.csdn.net/yuhouwucaihong/article/details/123951403
Author: 二次元云南山歌爱好者
Title: 保姆级详细教程:Windows 安装 Visual Studio + OpenCV + OpenCV contrib

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/637995/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球