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文件夹就是刚才新建的存放编译文件的那个。
    然后一路“确定”退出环境变量设置。
  2. 配置项目环境。
    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,不过编译过程是完全一样的。

  2. 生成解决方案。
    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拾起来看一看,官方给的这些例程看一看跑一跑。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容