OpenCV和opencv_contrib的编译

       在做特征匹配等图像处理的项目时,需要用到SURF和ORB等特征提取算法,这就需要用到配置xfeatures.hpp头文件以及相应的库。但是这一模块3.0版本以后以opencv_contrib模块独立出来,所以在使用这一模块时,需要对其进行编译。下面介绍OpenCV及其相应的opencv_contrib的编译步骤。

       首先进入OpenCV的github网页:OpenCV · GitHub ,打开界面如下:

                                                                      

          然后,分别点击opencv和opencv_contrib页面,并分别选择下载5.x版本的压缩包,下载页面如下:                                                                                                                                                                      

                    

        将两个下载好的压缩包解压到相应的文件夹下,然后新建build文件夹,存放编译的文件:

       打开cmake,然后在Where is the source code一栏填入opencv-5.x源代码的目录,在Where to build the binaries一栏填入新建的opencv-5.x-build目录,选择Visual Studio 17 2022,点击Configure:

                          

        Configure完毕后,出现如下界面,需要在BUILD_opencv_world一栏打勾,在OPENCV_EXTRA_MODULES_PATH一栏填入opencv_contrib-5.x下面modules所在目录,然后点击Generate:

                   

         Generate完成后,在“目的路径”----opencv-5.x-build目录下找到OpenCV.sln文件:

                                  

          选择VS 2022打开该工程文件,选择Release x64,点击 生成 >>>生成解决方案,开始编译。编译结束后,结果如下:

                                     

         然后,找到CMakeTargets目录,在INSTALL选型右键,选择 仅用于项目>>>仅生成INSTALL,即可编译生成dll相关文件,编译过程如下:

                        

         之后,就可以在项目属性里面编辑:在   VC++目录>>>包含目录   下填写:E:\opencv-5.x\opencv-5.x-build\install\include   E:\opencv-5.x\opencv-5.x-build\install\include\opencv2

         在   VC++目录>>>库目录   下填写:E:\opencv-5.x\opencv-5.x-build\install\x64\vc17\lib

         在   链接器>>>输入>>>附加依赖项   中填写:opencv_world500.lib,则完成一个项目的配置。

         下面以ORB匹配算法验证环境配置是否正确,实现ORB匹配算法的代码如下:

#include <opencv2\opencv.hpp>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>

#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\imgproc\types_c.h>

#include <opencv2\xfeatures2d.hpp>  
#include <opencv2\xfeatures2d\nonfree.hpp>

#include <cmath>
#include <vector>

using namespace cv;
using namespace std;

void main()
{
    double start = static_cast<double>(getTickCount());

    Mat src1, gray1, src2, gray2;
    src1 = imread("img_0.bmp");
    src2 = imread("img_1.bmp");

    cvtColor(src1, gray1, CV_BGR2GRAY);
    cvtColor(src2, gray2, CV_BGR2GRAY);

    morphologyEx(gray1, gray1, MORPH_GRADIENT, Mat());
    morphologyEx(gray2, gray2, MORPH_GRADIENT, Mat());

    vector<KeyPoint> keypoints1, keypoints2;
    Mat image1_descriptors, image2_descriptors;

    //采用ORB算法提取特征点  
    Ptr<ORB> orb = ORB::create(500);
    orb->setFastThreshold(0);

    orb->detectAndCompute(gray1, Mat(), keypoints1, image1_descriptors);
    orb->detectAndCompute(gray2, Mat(), keypoints2, image2_descriptors);

    BFMatcher matcher(NORM_HAMMING, true);   //汉明距离做为相似度度量  

    vector<DMatch> matches;
    matcher.match(image1_descriptors, image2_descriptors, matches);

    sort(matches.begin(), matches.end());

    Mat match_img;

    //保存匹配对序号  
    vector<int> queryIdxs(matches.size()), trainIdxs(matches.size());
    for (size_t i = 0; i < matches.size(); i++)
    {
        queryIdxs[i] = matches[i].queryIdx;
        trainIdxs[i] = matches[i].trainIdx;
    }

    Mat H12;  //变换矩阵  

    vector<Point2f> points1; KeyPoint::convert(keypoints1, points1, queryIdxs);
    vector<Point2f> points2; KeyPoint::convert(keypoints2, points2, trainIdxs);

    int ransacReprojThreshold = 5;  //拒绝阈值  
    H12 = findHomography(Mat(points1), Mat(points2), cv::RANSAC, ransacReprojThreshold);
    Mat points1t; vector<char> matchesMask(matches.size(), 0);
    perspectiveTransform(Mat(points1), points1t, H12);

    int mask_sum = 0;

    for (size_t i1 = 0; i1 < points1.size(); i1++)  //保存‘内点’  
    {
        if (norm(points2[i1] - points1t.at<Point2f>((int)i1, 0)) <= ransacReprojThreshold) //给内点做标记  
        {
            matchesMask[i1] = 1;
            mask_sum++;
        }
    }

    Mat Mat_img;
    drawMatches(src1, keypoints1, src2, keypoints2, matches, Mat_img, Scalar(0, 0, 255), Scalar::all(-1), matchesMask);

    imshow("result", Mat_img);

    imwrite("result.png", Mat_img);

    double time = ((double)getTickCount() - start) / getTickFrequency();
    cout << "The running time is:" << time << "seconds" << endl;

    cout << "The feature points found in picture 1:" << keypoints1.size() << endl;
    cout << "The feature points found in picture 2:" << keypoints2.size() << endl;
    cout << "The match results found in total:" << matches.size() << endl;
    cout << "The correct match results:" << mask_sum << endl;

    waitKey(0);
}

         现有一幅可见光图像及其相应的红外图像,若要实现两者之间的配准,运行上述代码,可得如下匹配结果:

                    

       编译得到的opencv_contrib模块完全可以用于目标配准的代码之中,则说明编译的opencv_contrib模块是可行的。

posted @ 2022-01-13 14:12  彩英-pink  阅读(1905)  评论(0编辑  收藏  举报