Windows10配置OpenCV CMake开发环境(IDE:Clion)

之前一直在Ubuntu16.04环境下使用OpenCV开发,但是需要来回切换双系统,或者打开虚拟机,很不方便,于是将开发平台转移到了Win10平台。

OpenCV有Windows环境下的安装包,但是是使用msvc编译器编译的,不能够跨平台,于是萌生了在Windows下使用MinGW编译OpenCV的想法。

下面是从编译OpenCV的过程,如果觉得麻烦可以直接看最后,下载我已经编译好的OpenCV4.3.0的包,可以直接使用。

下载OpenCV、contrib

首先从github上下载OpenCV和contrib包,鉴于一系列原因直接从github下载速度会很慢,可以从release上复制下载链接,复制到这个网址,然后下载会很快。

安装MinGW、CMake

在Windows环境下,我们要像在Ubuntu环境下cmake然后make去编译一个开源包,需要下载MinGW编译器,它给我们封装好了gcc和g++等编译器。

MinGW安装网上教程很多,但如果在线安装可能会非常费时,我把我安装好的文件夹分享出来,大家可以直接把该文件夹解压缩后复制到一个地方,并且把其中的bin目录添加到环境变量中。我把里面的mingw32-make.exe重命名为了make,以后可以直接输入make来编译。

MinGW蓝奏云网盘分享网址

还需要安装CMake,这个直接从官网下载安装最新版本安装即可。

编译OpenCV

上面已经配置好后MinGW后,我们可以开始编译OpenCV。

打开cmake-gui,上面两个路径自己选择,一个是源码路径,下面是build的路径。

cmake-gui参数设置:

  • CMAKE_INSTALL_PREFIX:设置为自定义安装的路径。
  • BUILD_opencv_world:我打了勾,这样最后生成的dll只有一个world,简洁。
  • OPENCV_ENABLE_NONFREE:打勾
  • OPENCV_EXTRA_MODULES_PATH:设置为contrib包中modules文件夹的路径

然后点击configure,在配置过程中会下载一些文件(见下),由于一些原因会下载失败,这时候需要我们自己下载然后放到指定的文件夹下(opencv_contrib-4.3.0\modules\xfeatures2d\src)。

boostdesc_bgm.i
boostdesc_bgm_bi.i
boostdesc_bgm_hd.i
boostdesc_lbgm.i
boostdesc_binboost_064.i
boostdesc_binboost_128.i
boostdesc_binboost_256.i
vgg_generated_120.i
vgg_generated_64.i
vgg_generated_80.i
vgg_generated_48.i

我把上面这些文件放在网盘中,分享网址

还有一个文件可能会下载失败,那就是opencv_videoio_ffmpeg.dll,同理,我把该文件放在网盘,分享网址。放置的文件夹可以查看build文件夹下的CMakeDownloadLog.txt文件,里面会详细介绍该文件从哪里下载放置在哪个位置,我们复制过去就行。同时需要注意的是,文件名字可能要改变,要加上前面的哈希值,但我们只需要把cmake下载的文件名字复制过去就行。

按理来说应该configure没问题了,点击generate生成makefile。

打开cmd,把路径转到build路径下,输入make -j8,我电脑cpu是8核。输入该命令的前提是上面步骤把MinGW中的bin目录添加到了系统环境变量。如果你没有把mingw32-make改为make,改名字,那么你应该输入mingw32-make -j8

等待make编译。

make完成后,输入make install,安装完成,所有的库文件和头文件都在自定义安装路径下面。

最后把安装文件夹下的\x64\mingw\bin路径添加到系统环境变量。

安装完成,测试一个surf例程试试。

问题:

编译过程中可能会出现HDF5包的错误,我电脑中装了anaconda3,在cmake时添加了anaconda中hdf5的路径,因此编译报错(很奇怪,无论是windows还是Ubuntu只要添加了anaconda中包的路径就报错,可能版本太低)。

这时我们需要自己去官网下载HDF5包去编译。我把我下载过的HDF5包传到网盘,分享网址,解压缩后使用cmake设置好安装路径,然后configure和generate,done好后打开cmd在build文件夹下输入make编译,编译成功后,输入make install会将编译好后的文件复制到自定义安装的路径下面。

然后再重新打开opencv的cmake配置,将hdf5库路径和头文件路径设置为刚刚安装好后的路径。再次对opencv进行make,直至成功。

OpenCV MinGW编译包

如果您觉得上述步骤太麻烦,可以直接拷贝我已经编译好后的opencv文件夹,分享网址。我的文件夹如下:
在这里插入图片描述
把bin目录添加到环境变量即可

Clion测试

在Ubuntu下我喜欢使用clion编程,Windows环境同样也可以使用。前面安装了MinGW工具后,安装Clion时会自动把MinGW编译器添加到路径中。如果先安装的clion后安装的MinGW,那么需要自己添加MinGW工具。

编写CMakeLists.txt,指定OpenCV路径:

cmake_minimum_required(VERSION 3.15)
project(opencv_test_cmake)

set(CMAKE_CXX_STANDARD 14)
# 这里需要指定自己的OpenCV路径
set(OpenCV_DIR E:/Software/OpenCV4.3.0/install)
find_package( OpenCV REQUIRED )
include_directories(${OpenCV_INCLUDE_DIRS})
message(${OpenCV_INCLUDE_DIRS})
message(${OpenCV_LIBS})
add_executable(opencv_test_cmake main.cpp)
target_link_libraries( opencv_test_cmake ${OpenCV_LIBS})

然后编写main文件,从网上找一个surf程序,试一下是否安装成功。

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

using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;

Mat Flannfeaturecompare(Mat srcImage1, Mat srcImage2)
{
    int hessPara = 400;
    Ptr<SURF> detector = SURF::create(hessPara);
    vector<KeyPoint> keypoints1, keypoints2;
    Mat descriptors1, descriptors2;
    detector->detectAndCompute(srcImage1, Mat(), keypoints1, descriptors1);
    detector->detectAndCompute(srcImage2, Mat(), keypoints2, descriptors2);
    FlannBasedMatcher matcher;
    //FlannBasedMatcher matcher(new flann::LshIndexParams(20, 10, 2));
    vector<DMatch> matches;
    //BFMatcher matcher;
    matcher.match(descriptors1, descriptors2, matches);
    double max_dist = 0;
    double min_dist = 1000;
    //距离判断--最优匹配点
    for (int i = 0; i < descriptors1.rows; i++)
    {
        double dist = matches[i].distance;
        if (dist < min_dist)
            min_dist = dist;
        if (dist > max_dist)
            max_dist = dist;
    }
    cout << "max_dist=" << max_dist << endl << "min_dist=" << min_dist << endl;
    //最佳匹配点
    vector<DMatch> matchVec;
    for (int i = 0; i < descriptors1.rows; i++)
    {
        if (matches[i].distance < 5 * min_dist)
        {
            matchVec.push_back(matches[i]);     //push_back 将满足条件的值赋值给matchVec数组
        }
    }
    Mat matchMat, matchMat2;
    drawMatches(srcImage1, keypoints1, srcImage2, keypoints2, matchVec, matchMat, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
    //imshow("matchMat", matchMat);
    //特征点一致性检测
    vector<Point2f> obj, scene;
    for (int i = 0; i < matchVec.size(); i++)
    {
        obj.push_back(keypoints1[matchVec[i].queryIdx].pt);   //为前图进行特征点索引  pt代表point(pt.x,pt.y);
        scene.push_back(keypoints2[matchVec[i].trainIdx].pt);  //为模板进行特征点索引
    }
    Mat H = findHomography(obj, scene, RANSAC);  //随机点匹配
    vector<Point2f> objCorner(4), sceneCors(4);
    objCorner[0] = Point(0, 0);
    objCorner[1] = Point(srcImage1.cols, 0);
    objCorner[2] = Point(srcImage1.cols, srcImage1.rows);
    objCorner[3] = Point(0, srcImage1.rows);
    perspectiveTransform(objCorner, sceneCors, H);  //映射矩阵
    Point2f offset((float)srcImage1.cols, 0);   //偏移量的增加
    //line(matchMat, sceneCors[0] + offset, sceneCors[1] + offset, Scalar(0, 255, 0), 2);
    //line(matchMat, sceneCors[1] + offset, sceneCors[2] + offset, Scalar(0, 255, 0), 2);
    //line(matchMat, sceneCors[2] + offset, sceneCors[3] + offset, Scalar(0, 255, 0), 2);
    //line(matchMat, sceneCors[3] + offset, sceneCors[0] + offset, Scalar(0, 255, 0), 2);
    float min_x = 1000, min_y = 1000;
    float max_x = 0, max_y = 0;
    for (int i = 0; i < 4; i++)
    {
        if (sceneCors[i].x < min_x)
            min_x = sceneCors[i].x;
        if (sceneCors[i].y < min_y)
            min_y = sceneCors[i].y;
        for (int j = i; j < 3; j++)
        {
            float max_dis_x = abs(sceneCors[i].x - sceneCors[j + 1].x);
            if (max_dis_x > max_x)
                max_x = max_dis_x;
            float max_dis_y = abs(sceneCors[i].y - sceneCors[j + 1].y);
            if (max_dis_y > max_y)
                max_y = max_dis_y;
        }

    }
    //通过两张图片进行对比特征点匹配
    //添加偏移量区域图的横向坐标偏移
    rectangle(matchMat, Rect(min_x + srcImage1.cols, min_y, max_x, max_y), Scalar(0, 0, 255), 2, 8, 0);
    Mat dst = srcImage2.clone();
    rectangle(dst,
              Rect(sceneCors[0].x, sceneCors[0].y, sceneCors[1].x - sceneCors[0].x, sceneCors[3].y - sceneCors[0].y),
              Scalar(0, 0, 255), 2, 8, 0);
    imshow("ObjectMat", matchMat);
    imshow("dst", dst);
    return matchMat;
}
int main()
{
    Mat Image1 = imread("1.jpg");
    Mat Image2 = imread("2.jpg");
    Mat feature = Flannfeaturecompare(Image1, Image2);
    waitKey(0);
    return 0;
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值