1. 程式人生 > >【OpenCV3.3】編譯原始碼並搭建VS2017+Windows開發環境

【OpenCV3.3】編譯原始碼並搭建VS2017+Windows開發環境

         OpenCV 3.3在8月3號正式Release,帶來了許多優化改進和新特性,包括備受關注的深度神經網路(DNN)模組被正式引入主倉庫,標誌著OpenCV對DNN有了更深層次的優化與支援; 支援通過巨集ENABLE_CXX11啟用對C++ 11特性的支援;預設包含大量SSE4.X和AVX/AVX2指令集優化;內建Intel IPP版本升級至2017.2,官方測試顯示有近15%的效能提升...等等,更多細節可以參考http://opencv.org/opencv-3-3.html,另外如果你現有程式碼基於OpenCV 3.x的話,建議進行版本升級~

        編譯OpenCV的原始碼並不複雜,或者說十分簡單(相對於部分老專案而言),並且對Visual Studio的支援也很友好,但首次編譯的話對整個流程以及過程中一些開關可能會存在一些疑問。如果你不想自行編譯也可以使用官方預編譯好的檔案,但是有些模組可能是用不到的,所以我們還是希望能儘可能自定義模組。

        本文假設讀者已經安裝了 CMake 和 Python (2.x或3.x)

     一、準備資源

  1. opencv-3.3.0-vc14.exe
    ,建議使用sourceforge下載,因為相比github這玩意有直鏈並且有不同映象可選,可以直接使用第三方下載器下載,速度比較快。

     二、準備原始碼

         直接執行下載好的exe,選擇解壓到的目錄,並提取sources資料夾,目錄結構大概如下:

     三、生成專案

         開啟CMake GUI,設定好目錄選擇Configure,然後選好IDE(Visual Studio 2017 WIN64)並Finish,等待初始配置完成(生成cvconfig.h)...


         正常情況下直到Configuring done是不會發生錯誤的,然後上面配置項是紅色的,提示有些東西需要人工改動,基本步驟就是檢視輸出,如果發現有外部庫找不到,比如"A library with XXX API not found

"或者"Could NOT find XXX (missing XXX)"之類的,根據需求把相應的庫的路徑加上,或者不需要的話直接去掉相關依賴的編譯,還可以做到0 warnings多好的事情~

         這裡大概有幾個提示:

  1. 首先因為我們是當成庫使用,不會去除錯OpenCV本身,所以把和最後開發無關的開關關掉,比如BUILD_DOCS,BUILD_EXAMPLES,BUILD_XXX_TESTS,BUILD_opencv_ts(一些單元測試程式碼),BUILD_PACKAGE (CPACK_BINARY_XXX,CPACK_SOURCE_XXX),INSTALL_XXX
  2. 前面說了C++ 11特性支援,當然是選擇開啟它,ENABLE_CXX11
  3. 為了方便專案配置和除錯,在生產環境中建議開啟BUILD_opencv_world,把各OpenCV模組編譯成一個世界模組,這樣最後生成的只有一個.lib或者.dll(後者需要開啟BUILD_SHARED_LIBS開關),但在發行版本中建議按需引入相應模組以減少體積(除非你每個模組都有使用到)。
  4. 如果你不涉及音視訊處理,可以關掉相關模組,大概包括BUILD_opencv_video,BUILD_opencv_videoio,BUILD_opencv_videostab,WITH_1394,WITH_GSTREAMER_XXX

部分編譯開關解釋

模組 功能
BUILD_OPENEXR
WIHT_IPP 新增Intel IPP演算法加速支援,包含SSE、AVX/AVX2等SIMD系列指令集優化以及Intel的黑科技,在AMD核上同樣可用,但是加速效果不如Intel CPU明顯
WITH_1394 新增對計算機標準介面IEEE1394的支援,俗稱火線介面,是由APPLE和TI公司開始的高速序列介面標準,主要用於視訊的採集,在INTEL高階主機板與數碼攝像機(DV)上可見
WITH_GSTREAMER 新增開源多媒體框架的支援,其目標在於簡化音/視訊應用程式開發,支援範圍從簡單的Ogg/Vorbis音訊播放、音/視訊流技術到複雜的混合音訊、視訊(非線性編輯)處理等
WITH_VTK
OPENCV_ENABLE_NONFREE 啟用專利保護演算法的支援,如SIFT和SURF,從功能上來說這兩個演算法屬於opencv_features2d模組,但由於它們都是受專利保護的,想在專案中可能需要專利方許可)
部分OpenCV模組介紹
模組 功能
opencv_core 包含核心功能尤其是底層資料結構和演算法實現,定義基本資料結構(包括重要的Mat)及被其他模組所使用的基本函式
opencv_imgproc 即Image Processing影象處理,包括濾波(線性、非線性)、幾何變換、顏色空間變換、直方圖、形狀描述子等
opencv_highgui 高層使用者介面(UI)及與QT框架的整合,包含讀寫影象、視訊以及操作使用者圖形介面相關的函式
opencv_imgcodecs 編解碼影象的封裝介面,支援的格式取決於編譯時指定的解碼器,比如BUILD_TIFF開啟對TIFF影象的編解碼支援
opencv_feature2d 用於2D特徵檢測(角點物件和平面物件)、特徵描述與匹配,包含各種介面統一的特徵值檢測器及描述子
opencv_calib3d 攝像機校準,包含相機標定(去除相機自身缺陷導致的畫面形變),3D資訊重建,姿態估計,雙目幾何及立體視覺函式等
opencv_photo 包含計算攝影學,涉及修復/去噪/高動態範圍(HDR)影象等
opencv_stitching 用於影象拼接、製作全景圖
opencv_videoio 對於視訊捕獲和視訊編碼器是一個易用介面
opencv_videostab Video Stabilization,視訊穩像
opencv_video 提供視訊分析功能(運動分析估計、背景分離、目標跟蹤、卡爾曼濾波等)
opencv_objdetect 用於物件檢測,包含Haar分類器、SVM檢測器、文字檢測以及預定義檢測器例項(例如人臉、眼、車等檢測)
opencv_ml 機器學習模組,包括統計模型、K最近鄰、支援向量機、決策樹、神經網路等經典的機器學習演算法。
opencv_flann Fast Library for Approximate Nearest Neighbors,最近鄰庫,包含聚類(K-means)、搜尋(KDTree)和計算幾何等
opencv_shape 形狀距離和匹配演算法模組,用於描述形狀、比較形狀,依賴於opencv_video
opencv_superres 基於視訊的超解析度重建,即從許多幀連續的低解析度影象中重建出高解析度影象,恢復單幀低解析度影象中丟掉的細節

        知道了上述內容也就對OpenCV整體框架有所瞭解了,自定義完OpenCV編譯模組後我們再次點選Configure修改配置CMake應該就沒錯誤輸出也不顯示紅色了,然後點選Generate生成VS2017專案檔案,最後Open Project開啟就能回到熟悉的VS環境中了,直接右鍵解決方案等它Build完就好了(ps: 生成的檔案放在 build\lib\ 和 build\bin\ 目錄下,最後通過INSTALL這個專案把相關檔案(.h、.dll、.lib等)拷貝到CMAKE_INSTALL_PREFIX目錄,如果你沒有Build INSTALL這個專案是不會拷貝的,跟make之後沒執行make install情況一樣)。

     四、專案配置

        VS作為幾乎公認的宇宙最強IDE大笑,在專案配置上具有十分友好的使用者介面,支援匯出專案模版或者繼承專案屬性表.props,避免專案的重新配置以及過度依賴系統環境變數。因為繼承專案屬性表方式相對而言比較靈活,這裡大概講講怎樣配置一個OpenCV的公共專案屬性表,以後新建專案或者移動OpenCV目錄只需要引用或者修改這個檔案就行了,不需要改動其它配置。

  1. 在VS主介面選擇View->Property Manager開啟屬性管理器檢視,選擇你要配置的任一個專案,選中全部配置(Debug & Release,這是為了讓全部配置都繼承同一個屬性表),右鍵,在彈出的框選擇Add New Project Property Sheet進行新建屬性表 (可以看到引用現有屬性表操作類似,但是我們還沒有屬性表,所以得新建一個):
  2. 然後右鍵我們剛才新建的屬性表開啟屬性設定,可以看到和專案屬性設定介面差不多,就是多了個User Macros,這是用來新增自定義變數的,我們隨便新增一個OPENCV_INSTALL_DIR,結果如下:

  3. 接著在VC++ Directories分別設定IncludeLibrary目錄 (Evaluated value如果沒顯示出路徑,請檢查上一步操作新增的變數名是否正確儲存了;此外記得勾選從父專案繼承,Inherit from parent or project defaults):
    Include目錄: $(OPENCV_INSTALL_DIR)\include
    Library目錄: $(OPENCV_INSTALL_DIR)\$(PlatformShortName)\vc15\lib  (vc15比較坑,因為並沒有巨集的值是vc15或15)

    Include目錄配置示例

    Library目錄配置示例

  4. 最後記得儲存就好了,以後新專案只需要引用剛才新建的屬性表就好了。然後在專案中引用相應的lib,但是lib有兩種版本,這裡提供一個很方便的巨集:
    #ifdef _DEBUG
    # define RLIB_IMPORT_LIBRARY(a)       __pragma(comment(lib, a "d.lib"))
    #else
    # define RLIB_IMPORT_LIBRARY(a)       __pragma(comment(lib, a ".lib"))
    #endif // _DEBUG
    
    // 用法如下
    RLIB_IMPORT_LIBRARY("opencv_world320") // world 其實是 All In One
    // RLIB_IMPORT_LIBRARY("opencv_core330")
    // RLIB_IMPORT_LIBRARY("opencv_highgui330")
    // RLIB_IMPORT_LIBRARY("opencv_imgproc330")
    // RLIB_IMPORT_LIBRARY("opencv_imgcodecs330")
    // RLIB_IMPORT_LIBRARY("opencv_features2d330")
    // RLIB_IMPORT_LIBRARY("opencv_calib3d330")
    // RLIB_IMPORT_LIBRARY("opencv_objdetect330")
    
    最後一個問題就是如果你編譯的不是靜態庫而是DLL的話,建議把路徑 D:\OpenCV3.3\build\install\x64\vc15\bin 加到系統環境變數PATH裡,方便除錯,省得每次拷貝DLL到應用程式目錄。

     五、參考文獻

          太多了,這裡就不一一列舉了,衷心感謝相關作者的分享。