opencv3.4+contribute编译及官方自带samples编译

环境:win10专业版+opencv3.4+contrib+VS2015

圣诞前夕,opencv悄悄发布了3.4版本,和3并没有很大的区别,听说是优化了DNN,这个还没用过,正好换了电脑,新电脑上还没来得及配置opencv,昨天下午闲了,我是没想到一下子能编译成功的,因为之前用到sift的时候试了几次都不行,今天却是出奇的顺利,除了有一个小地方自己粗心填错路径之外,其他的都很顺利,因为没想到能配置成功,也就没有截图,我待会稍微重新截一次来写。

准备工作

  1. 首先去官网上下载opencv主库zip文件,也可直接去github上下载,推荐这样,直接下载最新版本的opencv主库和contrib,链接。 下载下来的是源代码,需要编译才能使用,把两个zip文件解压,建议新建opencv/source文件夹,都解压到这个文件夹里。
  2. 下载cmake,去官网下载就可以了,我这里网有问题,官网的下不来,我另外下载的3.8版本。

cmake编译

cmake的界面长这个样子。

cmake

source code填写opencv主库的路径,路径下是有cmakelist文件的。 下面一个路径填写编译结果放的地方,这个自己设置就行了,建议opencv文件夹下新建一个build文件夹,放在这里面就可以了。 然后点击第一次configure,这个稍微时间长点,中间还要下载一点东西,都是自动完成的,保证联网。 完了之后上面会有一篇红色,不用担心,找到OPENCV_EXTRA_MODULES_PATH,然后把\opencv_contrib-master\modules 的路径填进去,可以进行第二次configure,configure done提示出现后,就基本完成一半的工作了。

然后点击generate,提示完成之后大功告成一半。

done

生成库文件

然后打开build文件夹,打开这个工程文件:

opencv

allbuild

debug

这里分别选择debug和release,我是64位生成的,然后ALL_BUILD左键分别生成,这个时间也比较久,机器好的话就比较快。出现 成功xx个,失败0个就OK了。这个时候主要的任务已经完成了。会在build的install文件下生成链接库,就可以直接用了。剩下的过程就很简单了。

VS一次性配置OpenCV

  1. 环境变量配置 我的电脑--属性--高级系统设置--环境变量:

path 点开path:

opencv_bin 这里的路径只是一个演示(我写这个的时候用的是笔记本,笔记本配置的opencv不是自己编译来的那个)这里应该填的是:\opencv\build\install\x64\vc14\bin,这个build文件夹就是刚才新建的存放编译文件的那个。 然后一路“确定”退出环境变量设置。

  1. 配置项目环境。 2.1 打开VS,新建c++空项目。

c++空项目 确定即可。 2.2:打开属性列表 视图--其他窗口--属性管理器,然后可以在右边(随设置不同而不同)看到属性管理器,长这样:

属性管理器 需要配置的是这两个红色的(其实是一个东西)。 2.3:配置。 双击打开:

目录

① 包含目录:

\opencv\build\install\include 
\opencv\build\install\include\opencv 
\opencv\build\install\include\opencv2

② 库目录: \opencv\new_build\install\x64\vc14\lib ③ 附加依赖项 链接器--输入:

附加依赖项

然后把lib里面所有的都添加进去,我配置的openc3.4还没有找到网上有人写,所以都是自己一个一个敲上去的:

opencv_aruco340.lib
opencv_bgsegm340.lib
opencv_bioinspired340.lib
opencv_calib3d340.lib
opencv_ccalib340.lib
opencv_core340.lib
opencv_datasets340.lib
opencv_dnn340.lib
opencv_dpm340.lib
opencv_face340.lib
opencv_features2d340.lib
opencv_flann340.lib
opencv_fuzzy340.lib
opencv_highgui340.lib
opencv_img_hash340.lib
opencv_imgcodecs340.lib
opencv_imgproc340.lib
opencv_line_descriptor340.lib
opencv_ml340.lib
opencv_objdetect340.lib
opencv_optflow340.lib
opencv_phase_unwrapping340.lib
opencv_photo340.lib
opencv_plot340.lib
opencv_reg340.lib
opencv_rgbd340.lib
opencv_saliency340.lib
opencv_shape340.lib
opencv_stereo340.lib
opencv_stitching340.lib
opencv_structured_light340.lib
opencv_superres340.lib
opencv_surface_matching340.lib
opencv_text340.lib
opencv_tracking340.lib
opencv_video340.lib
opencv_videoio340.lib
opencv_videostab340.lib
opencv_xfeatures2d340.lib
opencv_ximgproc340.lib
opencv_xobjdetect340.lib
opencv_xphoto340.lib

有说添加完环境变量后要重启一下电脑,我没有重启也可以,至此就大功告成了。接下来就是激动人心的测试阶段了。

测试

随便在网上找了一段sift的代码来测试,sift是在contrib里的,所以都可以测试一下。 代码:

/***************************************************************************
*检测候选特征点周围一圈的像素值,如果候选点周围领域内有足够多的像素点与该候选点的灰度值差别够大,则认为该候选点为一个特征点。
*如果测试了候选点周围每隔90度角的4个点,应该至少有3个和候选点的灰度值差足够大,否则则不用再计算其他点,直接认为该候选点不是特征点。候选点周围的圆的选取半径是一个很重要的参数,
*http://www.tuicool.com/articles/NzE77nB
*http://blog.sina.com.cn/s/blog_a98e39a201017pgn.html
*http://www.xuebuyuan.com/582341.html
*http://blog.csdn.net/poem_qianmo/article/details/33320997
***************************************************************************/

#include <iostream>  
#include<opencv2\opencv.hpp>  
#include"opencv2/xfeatures2d.hpp"  

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

int main()
{
    Mat a = imread("1.jpg", 0);    //读取灰度图像  
    Mat b = imread("2.jpg", 0);

    Ptr<SURF> surf;                   //创建方式和opencv2中的不一样  
                                      //  Ptr<SIFT> sift;  
    surf = SURF::create(800);       //阈值  

    BFMatcher matcher;                //匹配器  
    Mat c, d;
    vector<KeyPoint> key1, key2;
    vector<DMatch> matches;

    //结果为一个Mat矩阵,它的行数与特征点向量中元素个数是一致的。每行都是一个N维描述子的向量  
    surf->detectAndCompute(a, Mat(), key1, c);      //检测关键点和匹配描述子  
    surf->detectAndCompute(b, Mat(), key2, d);

    matcher.match(c, d, matches);         // 匹配,得到匹配向量  

    sort(matches.begin(), matches.end());  // 匹配点排序  
    vector< DMatch > good_matches;            // 匹配两幅图像的描述子  
    int ptsPairs = min(50, (int)(matches.size() * 0.15));
    cout << ptsPairs << endl;
    for (int i = 0; i < ptsPairs; i++)       // 将匹配较好的特征点存入good_matches中  
    {
        good_matches.push_back(matches[i]);
    }
    Mat outimg;
    drawMatches(                               // 绘制匹配点  
        a,                                    // 原图像1  
        key1,                                 // 原图像1的特征点  
        b,                                    // 原图像2  
        key2,                                 // 原图像2的特征点  
        good_matches,                         // 原图像1的特征点匹配原图像2的特征点[matches[i]]  
        outimg,                               // 输出图像具体由flags决定  
        Scalar::all(-1),                    // 匹配的颜色(特征点和连线),若matchColor==Scalar::all(-1),颜色随机  
        Scalar::all(-1),                    // 单个点的颜色,即未配对的特征点,若matchColor==Scalar::all(-1),颜色随机  
        vector<char>(),                       // Mask决定哪些点将被画出,若为空,则画出所有匹配点  
        DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);  //Fdefined by DrawMatchesFlags  

    imshow("匹配图", outimg);
    waitKey();

    vector<Point2f> obj;
    vector<Point2f> scene;

    for (size_t i = 0; i < good_matches.size(); i++)
    {
        ////good_matches[i].queryIdx保存着第一张图片匹配点的序号,keypoints_1[good_matches[i].queryIdx].pt.x 为该序号对应的点的x坐标  
        obj.push_back(key1[good_matches[i].queryIdx].pt);
        scene.push_back(key2[good_matches[i].trainIdx].pt);
    }

    vector<Point2f> scene_corners(4);
    vector<Point2f> obj_corners(4);
    obj_corners[0] = Point(0, 0);
    obj_corners[1] = Point(a.cols, 0);
    obj_corners[2] = Point(a.cols, a.rows);
    obj_corners[3] = Point(0, a.rows);

    Mat H = findHomography(              // 在两个平面之间寻找单映射变换矩阵  
        obj,                            // 在原平面上点的坐标  
        scene,                          // 在目标平面上点的坐标  
        RANSAC);                        // 用于计算单映射矩阵的方法  

    perspectiveTransform(                // 向量组的透视变换  
        obj_corners,                    // 输入两通道或三通道的浮点数组,每一个元素是一个2D/3D 的矢量转换  
        scene_corners,                  // 输出和src同样的size和type  
        H);                             // 3x3 或者4x4浮点转换矩阵  


                                        // 绘制  
    line(outimg, scene_corners[0] + Point2f((float)a.cols, 0), scene_corners[1] + Point2f((float)a.cols, 0), Scalar(0, 255, 0), 2, LINE_AA);
    line(outimg, scene_corners[1] + Point2f((float)a.cols, 0), scene_corners[2] + Point2f((float)a.cols, 0), Scalar(0, 255, 0), 2, LINE_AA);
    line(outimg, scene_corners[2] + Point2f((float)a.cols, 0), scene_corners[3] + Point2f((float)a.cols, 0), Scalar(0, 255, 0), 2, LINE_AA);
    line(outimg, scene_corners[3] + Point2f((float)a.cols, 0), scene_corners[0] + Point2f((float)a.cols, 0), Scalar(0, 255, 0), 2, LINE_AA);
    imshow("匹配图", outimg);
    waitKey(0);
}

结果:

sift匹配结果

如果没有报错且成功出现结果,那么就好好享受opencv的魔力吧,编译之后opencv的所有源码都是可见的,用到什么函数的时候不懂只要在函数名上右键跳转,就可以抵达源代码欣赏(被虐)了。

samples编译

opencv自带了很多例程,编译出来大概近两百个,基本都是主库里的。下面说如何编译这些自带的samples,当然不编译的话也可以用,就是得手动地把cpp文件或者cpp的内容拷贝到自己新建的解决方案(项目里)。这些例程在: source/opencv/samples里。给的是一些cpp源文件,可以直接复制到自己的项目里,不过这样太麻烦了,编译生成独立的项目会更易于学习。

  1. 编译samples 首先打开cmake,source code填入sample所在的路径,这个路径下也是有cmakelist文件的。

samples 然后就可以点击第一次configure了,这个第一遍一般会报错,错误的原因是有一个文件路径找不到:

opencv_dir 把这个路径改成上面编译的那个build文件夹的路径重新configure就可以了。 然后点generate就可以了:

done 看到这里就说明成功生成了,这个图是我在笔记本上编译samples,用的还是3.3,不过编译过程是完全一样的。

  1. 生成解决方案。 2.1 打开解决方案。 camke的使命就完成了,现在在刚才生成目录下打开sample工程文件:

samples 2.2 打开之后可以直接生成解决方案了。 打开之后找到ALL_BUILD,右键生成,然后就是等待了:opencv3.3里是有164个例程,3.4多十个左右。

done 这样就是成功了,可以愉快的学习了。

solution 这个解决方案里有164个例程,打开都是可以看的,可以看到上面的几个是几种深度学习的实现,但是好像opencv还不能实现训练,只能去下载别人训练好的参数来跑(我也没试过,听说的)。 下面是一些常用的功能,要学习哪一个,把那个设置为启动项目(右键-设置为启动项目),就可以debug或release了。我发现这样的话图片的路径还是要自己手动设置的,但是已经不算麻烦了,具体看代码吧。 找了个不需要设置图片路径的kmease来测试:

kmease 完美。

summary

至此opencv opencv_contrib samples的编译和配置就完成了,昨天出奇的顺利,基本没有遇到什么障碍,可能是因为自己都配置过几次有些坑踩掉了,中间还是参考了一些博客,不过已经不记得了是哪些了,也比较乱,这里一并感谢了。最近有一段时间没有看opencv了,这样完了之后希望可以把opencv拾起来看一看,官方给的这些例程看一看跑一跑。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏GreenLeaves

C# 多线程学习系列四之取消、超时子线程操作

虽然ThreadPool、Thread能开启子线程将一些任务交给子线程去承担,但是很多时候,因为某种原因,比如子线程发生异常、或者子线程的业务逻辑不符合我们的预...

27520
来自专栏joycl

c#面试题汇总

下面的参考解答只是帮助大家理解,不用背,面试题、笔试题千变万化,不要梦想着把题覆盖了,下面的题是供大家查漏补缺用的,真正的把这些题搞懂了,才能“以不变应万变”。...

81610
来自专栏程序人生 阅读快乐

C#程序设计语言-第4版(美)

C#语言结合了快速应用开发语言的高效和C/C++语言的强大。本书全部内容更新到C# 4.0版,提供了C# 4.0语言的完整规范、参考资料、范例代码和来自12位卓...

23430
来自专栏老付的网络博客

详解.net中IL语言

中间语言,又称(IL语言)。充当Clr与.net 平台的中间语言,比如用C#编写程序,编译器首先是把C#代码转译成IL语言,最终由Clr解释执行,下面我们学习下...

21020
来自专栏GreenLeaves

C# 多线程五之Task(任务)

为什么MS要推出Task,而不推Thread和ThreadPool,以下是我的见解:

37610
来自专栏HUBU生信

使用c#,运用面向对象的思想构建的一个图书管理系统(无数据库)

26030
来自专栏GreenLeaves

C# Command命令(行为型模式)+队列 实现事务,带异步命令重试机制和生命周期

耦合是软件不能抵御变变化的根本性原因,不仅实体对象与实体对象之间有耦合关系(如创建性设计模式存在的原因),对象和行为之间也存在耦合关系.

11810
来自专栏程序员互动联盟

编程语言中,c#、Python、JavaScript哪一个更接近c语言?

不要尝试比较几种编程语言的优劣,任何一种编程语言都有其存在的价值,适合的就是最好的,现在编程领域Python,JAVA等等发展势头非常迅猛,但并不意味着所有的企...

36920
来自专栏landv

【转】vscode调试运行c#详细操作过程

//用于发布exe <RuntimeIdentifier>win10-x64</RuntimeIdentifier> 

2.6K30
来自专栏GreenLeaves

C# 多线程九之Timer类

相信写过定时任务的小伙伴都知道这个类,非常的轻量级,而且FCL中大量的类使用了这个方法,比如CancellationTokenSource的CancelAfte...

11230

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励