windows 10 + vs2015+ opencv3.0.0 +附加模塊opencv_contrib編譯和配置

原文出處:http://blog.csdn.net/chentravelling/article/details/59540828

0.前言

將基於低版本OpenCV(比如2.3.1)的程序,在vs2015+opencv3.0的環境下編譯會報錯: 
“未聲明的標識符:SiftFeatureDetector ” 
“未聲明的標識符BruteForceMatcher” 

查閱才知,sift、surf等等已經被移到opencv_contrib模塊,如果需要在高版本opencv中使用到opencv_contrib模塊,則需要自己進行編譯。其編譯和配置流程,在github.com:opencv/opencv_contrib的README裏寫了: 
這裏寫圖片描述 
那麼現在開始自行編譯和配置吧。根據本文內容,成功率應該是99.99%,中途可能會遇到很多問題,我也會再總結一篇。 
通過不懈努力,最終成果如下: 
這裏寫圖片描述

一.準備:系統環境和工具

1)系統:win 10 64位 
2)opencv:3.0.0 
3)opencv_contrib:3.0.0 
4)visual studio:2015 
5)CMake:3.8.0

1.安裝CMake3.8.0

根據使用的操作系統選擇相應的版本進行下載和安裝即可(點擊下載): 
這裏寫圖片描述

2.下載opencv3.0.0

點擊到官網下載

3.安裝opencv3.0.0

將opencv安裝到指定目錄,比如:H:\opencv

4.下載opencv_contrib3.0.0

附加模塊opencv_contrib最好下載與opencv爲同一版本的。 
這裏寫圖片描述

5.解壓opencv_contrib 3.0.0

將下載好的附加模塊 opencv_contrib-3.0.0.zip 解壓到指定位置,比如:C:\Users\september\Desktop\opencv_contrib-3.0.0 
解壓後,opencv_contrib-3.0.0的結構目錄如下:

這裏寫圖片描述

二.編譯

1.打開cmake

2.輸入opencv源文件路徑

在where is the source code輸入opencv地址/sources地址, 比如:H:/opencv/sources

3.輸入保存編譯結果的路徑

在where to build the libraries輸入保存編譯結果的地址, 比如:H:/opencv/mybuild 
比如下圖:

這裏寫圖片描述

4.第一次編譯

(1)點擊configure,選擇本機的編譯器,最後四位數字才代表vs的版本,比如圖中的2015,代表的是visual studio 2015。 
這裏寫圖片描述 
(2)點擊finish,開始第一次編譯。 
如果編譯器的版本選錯,第一次編譯時會出錯: 
no cmake_c_compiler could be found. 
no cmake_cxx_compiler could be found.
 
第一次編譯完成後會顯示編譯opencv所需要的參數,如圖: 
這裏寫圖片描述

5.第二次編譯

(1)在參數列表中,將Name爲OPENCV_EXTRA_MODULES_PATH的Value設置爲opencv_contrib-3.0.0的路徑/modules,例如:C:/Users/september/Desktop/opencv_contrib-3.0.0/modules 
可以在search欄中搜索OPENCV_EXTRA_MODULES_PATH變量,如下圖。 
這裏寫圖片描述 
(2)點擊configure,直到configure done。 
重點:configure done後,一定要檢查一下參數列表,如果參數列表還有紅色標記的條目,就再嘗試幾次configure,直到所有條目都是白色爲止。

可能錯誤1:unknown cmake command "ocv_define_module"之類的,即存在未知的命令。
原因:可能是opencv版本和opencv_contrib版本不一致,換成一致的就行(本人遇到這個問題的時候,是這樣解決的)

可能錯誤2:在ICV: Downloading ippicv_windows_20141027.zip...時報錯
    CMake Error at 3rdparty/ippicv/downloader.cmake:97 (message):
    Call Stack (most recent call first):
    3rdparty/ippicv/downloader.cmake:108 (_icv_downloader)cmake/OpenCVFindIPP.cmake:212 (include)cmake/OpenCVFindLibsPerf.cmake:12 (include)
    CMakeLists.txt:454 (include)
    解決:手動下載ippicv_windows_20141027.zip,保存在opencv/sources/3rdparty/ippicv/downloads/windows-b59f865d1ba16e8c84124e19d78eec57


(3)點擊generate,直到generate done 
generate done後,會在where to build the binaries中設置的目錄中生成編譯結果。 
這裏寫圖片描述

(4)【該步驟是個人建議】檢查一下附加模版是否成功編譯並加入到opencv中。如果附加模塊opencv_contrib並未成功編譯到opencv中,那後面再忙活都是白乾。因爲後面的步驟都比較費時,而且最終到了使用SIFT的時候纔會發現附加模塊增加失敗,而且難以鎖定原因,必須返回來逐步檢查。所以個人建議不要跳過這一步,很簡單。 
如下圖,進入where to build the binaries中設置的目錄,然後進入modules,查看一下是否有xfeatures2d這類的文件。這類文件是屬於附加模版opencv_contrib的,如果沒有,請檢查一下CMake中參數列表裏,OPENCV_EXTRA_MODULES_PATH的Value是否爲opencv_contrib-3.0.0的路徑/modules,如果不是,請重新設置OPENCV_EXTRA_MODULES_PATH的Value爲opencv_contrib-3.0.0的路徑/modules,然後重新configure、generate。如果附加模塊opencv_contrib並未成功編譯到opencv中,那後面就夠忙活的了,後面更費時,而且最終會配置失敗,還難以想到 
這裏寫圖片描述

三.生成庫文件

1.打開OpenCV.sln

方式1:在CMake界面點擊open project 
方式2:進入where to build the binaries中設置的路徑下找到OpenCV.sln,並點擊即可,此時本機的vs會打開OpenCV項目方案。

2.生成.dll和.lib文件

OpenCV.sln項目加載完後(項目個數應該在130~140左右),右鍵點擊CMakeTargets,然後選擇生成。這步完成後,在where to build the binaries中設置的路徑下會多一個install文件,其中就是我們需要的配置文件了。

這裏寫圖片描述

四.配置

接下來的配置,就和以往配置opencv的流程一樣,只是現在是使用自己編譯的包含了附加模塊的opencv。

1.系統環境變量

計算機-環境變量-path中增加:where to build the binaries中設置的路徑\install\x86\vc14\bin 
這裏寫圖片描述

2.配置新建的工程

(1)VC++目錄-包含目錄

<where to build the binaries中設置的路徑>\install\include
<where to build the binaries中設置的路徑>\install\include\opencv
<where to build the binaries中設置的路徑>\install\include\opencv2
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

如下圖: 
這裏寫圖片描述 
(2)VC++目錄-庫目錄

<where to build the binaries中設置的路徑>\install\x86\vc14\lib
<where to build the binaries中設置的路徑>\install\x86\vc14\staticlib
  • 1
  • 2
  • 1
  • 2

如下圖:

這裏寫圖片描述 
(3)鏈接器-輸入-附加依賴項: 
可能因爲不同的人編譯時添加的附加模塊不一樣而造成最終的.lib不一樣,所以附加依賴項裏添加的.lib文件都需要出現在:< where to build the binaries中設置的路徑>\install\x86\vc14\lib中,否則在編譯程序的時候會出現XXX.lib加載失敗、丟失、找不到之類的錯誤,因爲這個.lib根本不存在,但是可能被添加在附加依賴項裏了。比如我的: 
opencv_bgsegm300d.lib 
opencv_calib3d300d.lib 
opencv_ccalib300d.lib 
opencv_core300d.lib 
opencv_datasets300d.lib 
opencv_face300d.lib 
opencv_features2d300d.lib 
opencv_flann300d.lib 
opencv_hal300d.lib 
opencv_highgui300d.lib 
opencv_imgcodecs300d.lib 
opencv_imgproc300d.lib 
opencv_line_descriptor300d.lib 
opencv_ml300d.lib 
opencv_objdetect300d.lib 
opencv_optflow300d.lib 
opencv_photo300d.lib 
opencv_reg300d.lib 
opencv_rgbd300d.lib 
opencv_saliency300d.lib 
opencv_shape300d.lib 
opencv_stitching300d.lib 
opencv_superres300d.lib 
opencv_surface_matching300d.lib 
opencv_text300d.lib 
opencv_tracking300d.lib 
opencv_ts300d.lib 
opencv_video300d.lib 
opencv_videoio300d.lib 
opencv_videostab300d.lib 
opencv_xfeatures2d300d.lib 
opencv_ximgproc300d.lib 
opencv_xobjdetect300d.lib 
opencv_xphoto300d.lib

五.測試

前面的四大部分完成了opencv和opencv_contrib的編譯和配置,也完成了項目的配置,現在就是檢驗的時候了。

1.添加源碼

在項目源文件中新建main.cpp:

#include <iostream>  
#include <opencv2\opencv.hpp>  
#include <opencv2\xfeatures2d.hpp>
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;


int main()
{
    Mat firstImage = imread("26.jpg");
    Mat secondImage = imread("27.jpg");
    if (firstImage.empty() || secondImage.empty())
    {
        cout << "error" << endl;
        return 0;
    }

    //resize(firstImage,firstImage,Size(800,1000),0,0,1);  
    //resize(secondImage,secondImage,Size(800,1000),0,0,1);  

    ////////////////////////////////////////////////////////////////////////////////  
    //第一步:獲取SIFT特徵  
////////////////////////////////////////////////////////////////////////////////  
    //difine a sift detector  
    Ptr<SIFT> sift = SIFT::create();
    //sift->detect();
    //SiftFeatureDetector siftDetector;
    //store key points  
    vector<KeyPoint> firstKeypoint, secondKeypoint;
    //detect image with SIFT,get key points  
    sift->detect(firstImage, firstKeypoint);
    sift->detect(secondImage, secondKeypoint);
    Mat firstOutImage, secondOutImage;
    //draw key points at the out image and show to the user  
    drawKeypoints(firstImage, firstKeypoint, firstOutImage, Scalar(255, 0, 0));
    drawKeypoints(secondImage, secondKeypoint, secondOutImage, Scalar(0, 255, 0));
    imshow("first", firstOutImage);
    imshow("second", secondOutImage);
    Mat firstDescriptor, secondDescriptor;
    sift->compute(firstImage,firstKeypoint,firstDescriptor);
    sift->compute(secondImage,secondKeypoint,secondDescriptor);
    Ptr<DescriptorMatcher > matcher = DescriptorMatcher::create("BruteForce");
    Mat masks;
    vector<DMatch> matches;
    matcher->match(firstDescriptor, secondDescriptor, matches, masks);


    ////////////////////////////////////////////////////////////////////////////////  
    //第二步:RANSAC方法剔除outliner  
////////////////////////////////////////////////////////////////////////////////  
    Mat matcheImage;
    //將vector轉化成Mat  
    Mat firstKeypointMat(matches.size(), 2, CV_32F), secondKeypointMat(matches.size(), 2, CV_32F);
    for (int i = 0; i<matches.size(); i++)
    {
        firstKeypointMat.at<float>(i, 0) = firstKeypoint[matches[i].queryIdx].pt.x;
        firstKeypointMat.at<float>(i, 1) = firstKeypoint[matches[i].queryIdx].pt.y;
        secondKeypointMat.at<float>(i, 0) = secondKeypoint[matches[i].trainIdx].pt.x;
        secondKeypointMat.at<float>(i, 1) = secondKeypoint[matches[i].trainIdx].pt.y;
    }
    //Calculate the fundamental Mat;  
    vector<uchar> ransacStatus;
    Mat fundamentalMat = findFundamentalMat(firstKeypointMat, secondKeypointMat, ransacStatus, FM_RANSAC);
    cout << fundamentalMat << endl;
    //Calculate the number of outliner points;  
    int outlinerCount = 0;
    for (int i = 0; i<matches.size(); i++)
    {
        if (ransacStatus[i] == 0)
        {
            outlinerCount++;
        }
    }
    //Calculate inliner points;  
    vector<Point2f> firstInliner;
    vector<Point2f> secondInliner;
    vector<DMatch> inlinerMatches;
    int inlinerCount = matches.size() - outlinerCount;
    firstInliner.resize(inlinerCount);
    secondInliner.resize(inlinerCount);
    inlinerMatches.resize(inlinerCount);
    int index = 0;
    for (int i = 0; i<matches.size(); i++)
    {
        if (ransacStatus[i] != 0)
        {
            firstInliner[index].x = firstKeypointMat.at<float>(i, 0);
            firstInliner[index].y = firstKeypointMat.at<float>(i, 1);
            secondInliner[index].x = secondKeypointMat.at<float>(i, 0);
            secondInliner[index].y = secondKeypointMat.at<float>(i, 1);
            inlinerMatches[index].queryIdx = index;
            inlinerMatches[index].trainIdx = index;
            index++;
        }
    }
    vector<KeyPoint> inlinerFirstKeypoint(inlinerCount);
    vector<KeyPoint> inlinerSecondKeypoint(inlinerCount);
    KeyPoint::convert(firstInliner, inlinerFirstKeypoint);
    KeyPoint::convert(secondInliner, inlinerSecondKeypoint);
    //cout<<fundamentalMat<<endl;  
    //select 50 keypoints  
    //matches.erase(matches.begin()+50,matches.end());  
    //inlinerMatches.erase(inlinerMatches.begin()+50,inlinerMatches.end());  
    drawMatches(firstImage, inlinerFirstKeypoint, secondImage, inlinerSecondKeypoint, inlinerMatches, matcheImage);
    imshow("ransacMatches", matcheImage);
    drawMatches(firstImage, firstKeypoint, secondImage, secondKeypoint, matches, matcheImage);
    imshow("matches", matcheImage);
    waitKey(0);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111

2.運行

這裏寫圖片描述

到此,windows 10 + vs2015+ opencv3.0.0 的環境下,使用opencv_contrib附加模塊就完美解決了,SIFT、SURF也能正常使用了。整個編譯、配置過程,會遇到各種各樣的問題,總之,堅持不懈吧~誰讓opencv不是咱自己寫的呢~

發佈了9 篇原創文章 · 獲贊 13 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章