1. 程式人生 > >OpenCV庫檔案介紹

OpenCV庫檔案介紹

以前都是直接用opencv,都沒有仔細研究過,這次把庫檔案都介紹一下。

1、build和source

當我們安裝完opencv中,你會發現在opencv資料夾中有兩個資料夾,build和source,那它們分別是幹什麼的呢。

這裡寫圖片描述

首先說這兩者的關係,sources放的是opencv中的cpp檔案,相當於一個工廠,build放的是opencv中的h、hpp、lib檔案,相當於一個工具,opencv的開發者(當然開源後的使用者也可以)通過sources中的原始檔,構建出build中的庫檔案,然後使用者就可以連結這些庫,include<標頭檔案>。一般非開源的程式和庫是不開放sources的,而opencv作為一個開源庫,這些也是使用者可見的。

source裡面是各種各樣的函式實現,對於只想用opencv的人來說,只關心我怎麼用,於是開發者就會使用這些原始檔構建出庫,這些庫裡面包含了函式實現。這些庫就是各種lib,然後還有標頭檔案。

build裡面只有介面,沒有cpp中的實現什麼的,build是對使用者的,使用者只用知道介面就行了,不需要知道這個是怎麼做到的。當然因為opencv開源,所以使用者也可以直接檢視原始檔。

具體來說,soucees裡面放的是函式具體的實現,比如有gray方法,對一個mat的畫素怎麼使它變成灰度化。

使用者include<標頭檔案>,標頭檔案裡面是各種介面,比如gray,就是一個gray(MAt img),使用者連結這些庫,inluce<標頭檔案>,然後在程式中呼叫gray,然後程式執行的時候會進行連結時,在各種依賴庫中尋找gray的實現,因為我們連線了opencv的庫,所以在opencv的lib中就找到了gray的實現,然後就呼叫這個實現,然後就灰度化了,就是這個麼過程。

舉個不是很恰當的例子,build就像是賣給使用者的macbook,使用者只用知道怎麼用,這個作業系統很好用,不卡,不用知道這個作業系統怎麼實現了。怎麼實現的就在source裡面,非開源的程式和庫是不可能讓你看到source的。

2、build

在build資料夾中,如下,

這裡寫圖片描述
.

首先,doc資料夾下放的是各種關於opencv的文件;include資料夾下是所有的標頭檔案;其餘四個分別是:一個給java用的庫、一個給python用、一個給x86win用、一個給x64win用。兩個cmake檔案都是cmake的一些配置,很強大的編譯工具。

2.1 include

分為opencv和opencv2.

這裡寫圖片描述

這裡寫圖片描述
.

這裡借用部落格1部落格2的介紹。

1、opencv

其中cv.h中包含的標頭檔案:

#include "opencv2/core/core_c.h"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/tracking.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/flann/flann.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/legacy/compat.hpp"

cv.hpp中包含標頭檔案:

#include <cv.h>

也就是說cv.hpp是包含cv.h的,程式中凡用到cv.h的地方都可以用cv.hpp 替換,那麼為什麼又要設定hpp檔案呢?

hpp是Header Plus Plus的簡寫,與 .h 檔案類似。但與之不同的是,.hpp將*.cpp中的實現程式碼也寫入其中,使得定義與實現都包含在同一檔案中。這樣做帶來的好處顯而易見,無需再將cpp檔案新增到專案中編譯,減少了編譯次數,也不用釋出煩人的lib,dll 檔案,因此非常適合用來編寫公用的開源庫。

資料夾opencv中的標頭檔案都是類似的,均包含資料夾opencv2裡的標頭檔案。所以我們如果是從低版本的opencv學習過渡到高版本的opencv的話,如果不適應可以先以opencv資料夾裡的檔案呼叫為標準。如果熟悉opencv裡的函式分佈,也可以直接呼叫opencv2資料夾裡的具體標頭檔案,這樣在標頭檔案預編譯提高效率。

2、opencv2

先看opencv.hpp檔案:

#include "opencv2/core/core_c.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"

很明顯opencv.hpp的標頭檔案包含了opencv庫裡的所有標頭檔案。

接著看opencv_modules.hpp檔案:

#define HAVE_OPENCV_CALIB3D
#define HAVE_OPENCV_CONTRIB
#define HAVE_OPENCV_CORE
#define HAVE_OPENCV_FEATURES2D
#define HAVE_OPENCV_FLANN
#define HAVE_OPENCV_GPU
#define HAVE_OPENCV_HIGHGUI
#define HAVE_OPENCV_IMGPROC
#define HAVE_OPENCV_LEGACY
#define HAVE_OPENCV_ML
#define HAVE_OPENCV_NONFREE
#define HAVE_OPENCV_OBJDETECT
#define HAVE_OPENCV_OCL
#define HAVE_OPENCV_PHOTO
#define HAVE_OPENCV_STITCHING
#define HAVE_OPENCV_SUPERRES
#define HAVE_OPENCV_TS
#define HAVE_OPENCV_VIDEO
#define HAVE_OPENCV_VIDEOSTAB

其解釋如下:

【calib3d】:其實就是就是Calibration(校準)加3D這兩個詞的組合縮寫。這個模組主要是相機校準和三維重建相關的內容。基本的多視角幾何演算法,單個立體攝像頭標定,物體姿態估計,立體相似性演算法,3D資訊的重建等等。

【contrib】:也就是Contributed/Experimental Stuf的縮寫, 該模組包含了一些最近新增的不太穩定的可選功能,不用去多管。2.4.8之後有新型人臉識別, 立體匹配 ,人工視網膜模型等技術。

【core】: 核心功能模組,尤其是底層資料結構和演算法函式。包含如下內容:

  • OpenCV基本資料結構
  • 動態資料結構
  • 繪圖函式
  • 陣列操作相關函式
  • 輔助功能與系統函式和巨集

【imgproc】: Image和Processing這兩個單詞的縮寫組合。影象處理模組,這個模組包含了如下內容:

  • 線性和非線性的影象濾波
  • 影象的幾何變換
  • 其它(Miscellaneous)影象轉換
  • 直方圖相關
  • 結構分析和形狀描述
  • 運動分析和物件跟蹤
  • 特徵檢測

【features2】: d也就是Features2D, 2D功能框架 ,包含興趣點檢測子、描述子以及興趣點匹配框架。包含如下內容:

  • 特徵檢測和描述
  • 特徵檢測器(Feature Detectors)通用介面
  • 描述符提取器(Descriptor Extractors)通用介面
  • 描述符匹配器(Descriptor Matchers)通用介面
  • 通用描述符(Generic Descriptor)匹配器通用介面

【flann】: Fast Library for Approximate Nearest Neighbors,高維的近似近鄰快速搜尋演算法庫, 包含兩個部分:快速近似最近鄰搜尋和聚類。

【gpu】: 運用GPU加速的計算機視覺模組。

【highgui】: 也就是high gui,高層GUI圖形使用者介面,包含媒體的I / O輸入輸出, 視訊捕捉、影象和視訊的編碼解碼、圖形互動介面的介面等內容。

【legacy】: 一些已經廢棄的程式碼庫,保留下來作為向下相容,包含如下相關的內容。

  • 運動分析
  • 期望最大化
  • 直方圖
  • 平面細分(C API)
  • 特徵檢測和描述(Feature Detection and Description)
  • 描述符提取器(Descriptor Extractors)的通用介面
  • 通用描述符(Generic Descriptor Matchers)的常用介面

【ml】: Machine Learning,機器學習模組, 基本上是統計模型和分類演算法,包含如下內容。

  • 統計模型 (Statistical Models)
  • 一般貝葉斯分類器 (Normal Bayes Classifier)
  • K-近鄰 (K-NearestNeighbors)
  • 支援向量機 (Support Vector Machines)
  • 決策樹 (Decision Trees)
  • 提升(Boosting)
  • 梯度提高樹(Gradient Boosted Trees)
  • 隨機樹 (Random Trees)
  • 超隨機樹 (Extremely randomized trees)
  • 期望最大化 (Expectation Maximization)
  • 神經網路 (Neural Networks)
  • MLData

【nonfree】: 也就是一些具有專利的演算法模組 ,包含特徵檢測和GPU相關的內容。最好不要商用,可能會被告哦。

【objdetect】: 目標檢測模組,包含Cascade Classification(級聯分類)和Latent SVM這兩個部分。

【ocl】: 即OpenCL-accelerated Computer Vision,運用OpenCL加速的計算機視覺元件模組。

【photo】: 也就是Computational Photography,包含影象修復和影象去噪兩部分。

【stitching】: images stitching,影象拼接模組,包含如下部分。

  • 拼接流水線
  • 特點尋找和匹配影象
  • 估計旋轉
  • 自動校準
  • 圖片歪斜
  • 接縫估測
  • 曝光補償
  • 圖片混合

【superres】: SuperResolution,超解析度技術的相關功能模組。

【ts】: opencv測試相關程式碼,不用去管他。

【video】: 視訊分析元件,該模組包括運動估計,背景分離,物件跟蹤等視訊處理相關內容。

【Videostab】: Video stabilization,視訊穩定相關的元件。

2.2 X64和X86

首先,這裡面放的都是一些庫檔案,只不過X64面向64位,X86是32位的,然後以X64為例,

.
這裡寫圖片描述
.

這是代表編譯給不同版本的visual studio用的庫,這裡以vc12為例。

.
這裡寫圖片描述
.

bin資料夾下:dll檔案,動態連結庫。具體實現的內容。計算機環境變數中,這個路徑是要加到path中的。

lib資料夾下:配置opencv環境時,新增的lib庫。用來連結。

staticlib資料夾下:靜態庫。

靜態庫是編譯時就把整個函式載入進去,所以可執行檔案會變大。動態庫是編譯時加進去的是一個函式表,執行時才會從dll裡面載入對應的函式實現。

這裡參考於部落格給出一個關於dll和lib的解釋。

共有兩種庫:

  • 一種是LIB包含了函式所在的DLL檔案和檔案中函式位置的資訊(入口),程式碼由執行時載入在程序空間中的DLL提供,稱為動態連結庫dynamic link library。
  • 一種是LIB包含函式程式碼本身,在編譯時直接將程式碼加入程式當中,稱為靜態連結庫static link library。

共有兩種連結方式:

  • 動態連結使用動態連結庫,允許可執行模組(.dll檔案或.exe檔案)僅包含在執行時定位DLL函式的可執行程式碼所需的資訊。
  • 靜態連結使用靜態連結庫,連結器從靜態連結庫LIB獲取所有被引用函式,並將庫同程式碼一起放到可執行檔案中。

關於lib和dll的區別如下:

  • lib是編譯時用到的,dll是執行時用到的。如果要完成原始碼的編譯,只需要lib;如果要使動態連結的程式執行起來,只需要dll。

  • 如果有dll檔案,那麼lib一般是一些索引資訊,記錄了dll中函式的入口和位置,dll中是函式的具體內容;如果只有lib檔案,那麼這個lib檔案是靜態編譯出來的,索引和實現都在其中。使用靜態編譯的lib檔案,在執行程式時不需要再掛動態庫,缺點是導致應用程式比較大,而且失去了動態庫的靈活性,釋出新版本時要釋出新的應用程式才行。

  • 動態連結的情況下,有兩個檔案:一個是LIB檔案,一個是DLL檔案。LIB包含被DLL匯出的函式名稱和位置,DLL包含實際的函式和資料,應用程式使用LIB檔案連結到DLL檔案。在應用程式的可執行檔案中,存放的不是被呼叫的函式程式碼,而是DLL中相應函式程式碼的地址,從而節省了記憶體資源。DLL和LIB檔案必須隨應用程式一起發行,否則應用程式會產生錯誤。如果不想用lib檔案或者沒有lib檔案,可以用WIN32 API函式LoadLibrary、GetProcAddress裝載。

3、sources

這裡寫圖片描述

  • samples:是一些簡短的學習用例。
  • modules:包含了所有的原始檔。
  • doc:是一些文件,包含一些教程。
  • include:是所有的標頭檔案。包含opencv和opencv2。
  • 3rdparty:第三方庫,如ffmpeg視訊編碼等。
  • apps:一些應用,比如級聯分類器,haar特徵分類器。
  • cmake:編譯相關。
  • data:級聯分類器的一些資料。比如人臉檢測、人眼檢測等。
  • platform:平臺相關,iOS、Android、Linux、script、win。