OpenCV過(guò)渡指南

2018-08-28 18:38 更新

變更概述

本文檔面向希望將代碼遷移到OpenCV 3.0的軟件開發(fā)人員。

與2.4版本相比,OpenCV 3.0引入了許多新的算法和功能。一些模塊已被重寫,有些模塊已經(jīng)重組。雖然2.4中的大部分算法仍然存在,但接口可能不同。

本節(jié)介紹一般最顯著的更改,所有細(xì)節(jié)和過(guò)渡操作的示例在文檔的下一部分。

Contrib倉(cāng)庫(kù)

https://github.com/opencv/opencv_contrib

這是所有新的,實(shí)驗(yàn)的和非免費(fèi)的算法的地方。與主庫(kù)相比,支持小組沒有受到太多的關(guān)注,但社區(qū)努力保持良好的狀態(tài)。

要使用contrib存儲(chǔ)庫(kù)構(gòu)建OpenCV ,請(qǐng)將以下選項(xiàng)添加到cmake命令中:

-DOPENCV_EXTRA_MODULES_PATH=<path-to-opencv_contrib>/modules
標(biāo)題布局

在2.4中,所有頭都位于相應(yīng)的模塊子文件夾(opencv2 / <module> / <module> .hpp)中,3.0中有頂級(jí)模塊頭,其中包含大部分模塊功能:opencv2 / <module> .hpp和all C風(fēng)格的API定義已被移動(dòng)到單獨(dú)的標(biāo)題(例如opencv2 / core / core_c.h)。

算法接口

一般算法使用模式已經(jīng)改變了:現(xiàn)在它必須在包裹在智能指針cv :: Ptr的堆上創(chuàng)建。版本2.4允許堆棧和堆分配,直接或通過(guò)智能指針。

get和set方法已經(jīng)從cv :: Algorithm類以及CV_INIT_ALGORITHM宏中刪除。在3.0中,所有屬性都已轉(zhuǎn)換為getProperty / setProperty純虛擬方法。因此,它是不是能夠創(chuàng)建和使用CV ::算法通過(guò)名稱實(shí)例(使用通用的算法::創(chuàng)建(字符串)方法),應(yīng)該顯式調(diào)用相應(yīng)的工廠方法。

更改模塊
  • ml模塊已被重寫
  • highgui模塊已經(jīng)分為幾部分:imgcodecs,videoio和highgui本身
  • features2d模塊已被重組(某些功能檢測(cè)器已被移動(dòng)到opencv_contrib / xfeatures2d模塊)
  • 傳統(tǒng)的,非自由的模塊已被刪除。一些算法已被移動(dòng)到不同的位置,一些算法被完全重寫或刪除
  • CUDA API已經(jīng)更新(gpu模塊 - >幾個(gè)cuda模塊,命名空間gpu - >命名空間cuda)
  • OpenCL API已更改(ocl模塊已被刪除,單獨(dú)的ocl :: implementation - > Transparent API)
  • 其他一些方法和類已被重定位

過(guò)渡提示

本節(jié)通過(guò)實(shí)例介紹具體的操作。

準(zhǔn)備2.4

在最新的2.4.11 OpenCV版本中進(jìn)行的一些更改允許您準(zhǔn)備當(dāng)前的代碼庫(kù)進(jìn)行遷移:

  • cv :: makePtr函數(shù)現(xiàn)在可用
  • opencv2 / <module> .hpp頭已創(chuàng)建

新標(biāo)題布局

注意: OpenCV 3.0中進(jìn)行了旨在簡(jiǎn)化遷移的更改,因此不需要以下說(shuō)明,但建議。

  • 更換舊模塊標(biāo)題的內(nèi)含物
// old header
#include "opencv2/<module>/<module>.hpp"
// new header
#include "opencv2/<module>.hpp"

現(xiàn)代使用算法

  • 必須使用cv :: makePtr函數(shù)或相應(yīng)的靜態(tài)工廠方法(如果可用)創(chuàng)建算法實(shí)例:
// good ways
Ptr<SomeAlgo> algo = makePtr<SomeAlgo>(...);
Ptr<SomeAlgo> algo = SomeAlgo::create(...);

其他方式已棄用:

// bad ways
Ptr<SomeAlgo> algo = new SomeAlgo(...);
SomeAlgo * algo = new SomeAlgo(...);
SomeAlgo algo(...);
Ptr<SomeAlgo> algo = Algorithm::create<SomeAlgo>("name");
  • 應(yīng)通過(guò)相應(yīng)的虛擬方法訪問算法屬性,getSomeProperty / setSomeProperty,通用get / set方法已被刪除:
// good way
double clipLimit = clahe->getClipLimit();
clahe->setClipLimit(clipLimit);
// bad way
double clipLimit = clahe->getDouble("clipLimit");
clahe->set("clipLimit", clipLimit);
clahe->setDouble("clipLimit", clipLimit);
  • 刪除initModule_<moduleName>()呼叫

機(jī)器學(xué)習(xí)模塊

由于該模塊已被重寫,因此需要花費(fèi)一些時(shí)間來(lái)適應(yīng)您的軟件。所有算法都位于單獨(dú)的ml命名空間及其基類StatModel中。單獨(dú)的SomeAlgoParams類已被替換為一組相應(yīng)的getProperty / setProperty方法。

下表說(shuō)明了2.4和3.0機(jī)器學(xué)習(xí)類之間的對(duì)應(yīng)關(guān)系。

2.43.0
CvStatModelCV ::毫升:: StatModel
CvNormalBayesClassifierCV ::毫升:: NormalBayesClassifier
CvKNearestCV ::毫升:: KNearest
CvSVMCV ::毫升:: SVM
CvDTreeCV ::毫升:: DTrees
CV升壓CV ::毫升::升壓
CvGBTrees未實(shí)現(xiàn)
CvRTreesCV ::毫升::的rtrees
CvERTrees未實(shí)現(xiàn)
EMCV ::毫升:: EM
CvANN_MLPCV ::毫升:: ANN_MLP
未實(shí)現(xiàn)CV ::毫升::邏輯回歸
CvMLDataCV ::毫升:: TrainData

雖然在3.0版中重寫的ml算法可以讓您從xml / yml文件中加載舊的訓(xùn)練模型,但預(yù)測(cè)過(guò)程中的偏差是可能的。

points_classifier.cpp示例中的以下代碼段說(shuō)明了模型訓(xùn)練過(guò)程中的差異:

using namespace cv;
// ======== version 2.4 ========
Mat trainSamples, trainClasses;
prepare_train_data( trainSamples, trainClasses );
CvBoost  boost;
Mat var_types( 1, trainSamples.cols + 1, CV_8UC1, Scalar(CV_VAR_ORDERED) );
var_types.at<uchar>( trainSamples.cols ) = CV_VAR_CATEGORICAL;
CvBoostParams  params( CvBoost::DISCRETE, // boost_type
                       100, // weak_count
                       0.95, // weight_trim_rate
                       2, // max_depth
                       false, //use_surrogates
                       0 // priors
                     );
boost.train( trainSamples, CV_ROW_SAMPLE, trainClasses, Mat(), Mat(), var_types, Mat(), params );
// ======== version 3.0 ========
Ptr<Boost> boost = Boost::create();
boost->setBoostType(Boost::DISCRETE);
boost->setWeakCount(100);
boost->setWeightTrimRate(0.95);
boost->setMaxDepth(2);
boost->setUseSurrogates(false);
boost->setPriors(Mat());
boost->train(prepare_train_data()); // 'prepare_train_data' returns an instance of ml::TrainData class

特征檢測(cè)

一些算法(FREAK,BRIEF,SIFT,SURF)已被移動(dòng)到opencv_contrib存儲(chǔ)庫(kù),到xfeatures2d模塊,xfeatures2d命名空間。他們的界面也被改變了(繼承于cv::Feature2D基類)。

xfeatures2d模塊類的列表:

需要執(zhí)行以下步驟:

  1. 將opencv_contrib添加到編譯過(guò)程中
  2. 包含opencv2/xfeatures2d.h標(biāo)題
  3. 使用命名空間 xfeatures2d
  4. 用或替換operator()呼叫detect,compute或detectAndCompute如果需要

一些類現(xiàn)在使用一般方法detect,compute或detectAndCompute由Feature2D基類而不是自定義提供operator()

以下代碼片段說(shuō)明了區(qū)別(從video_homography.cpp示例):

using namespace cv;
// ====== 2.4 =======
#include "opencv2/features2d/features2d.hpp"
BriefDescriptorExtractor brief(32);
GridAdaptedFeatureDetector detector(new FastFeatureDetector(10, true), DESIRED_FTRS, 4, 4);
// ...
detector.detect(gray, query_kpts); //Find interest points
brief.compute(gray, query_kpts, query_desc); //Compute brief descriptors at each keypoint location
// ====== 3.0 =======
#include "opencv2/features2d.hpp"
#include "opencv2/xfeatures2d.hpp"
using namespace cv::xfeatures2d;
Ptr<BriefDescriptorExtractor> brief = BriefDescriptorExtractor::create(32);
Ptr<FastFeatureDetector> detector = FastFeatureDetector::create(10, true);
// ...
detector->detect(gray, query_kpts); //Find interest points
brief->compute(gray, query_kpts, query_desc); //Compute brief descriptors at each keypoint location

OpenCL的

所有專門的ocl實(shí)現(xiàn)都隱藏在一般的C ++算法接口之后。現(xiàn)在可以在運(yùn)行時(shí)動(dòng)態(tài)選擇功能執(zhí)行路徑:CPU或OpenCL; 這個(gè)機(jī)制也被稱為“透明API”。

新類cv :: UMat旨在以方便的方式隱藏與OpenCL設(shè)備的數(shù)據(jù)交換。

以下示例說(shuō)明了API修改(來(lái)自OpenCV站點(diǎn)):

  • OpenCL感知代碼OpenCV-2.x
// initialization
VideoCapture vcap(...);
ocl::OclCascadeClassifier fd("haar_ff.xml");
ocl::oclMat frame, frameGray;
Mat frameCpu;
vector<Rect> faces;
for(;;){
    // processing loop
    vcap >> frameCpu;
    frame = frameCpu;
    ocl::cvtColor(frame, frameGray, BGR2GRAY);
    ocl::equalizeHist(frameGray, frameGray);
    fd.detectMultiScale(frameGray, faces, ...);
    // draw rectangles …
    // show image …
}
  • OpenCL感知代碼OpenCV-3.x
// initialization
VideoCapture vcap(...);
CascadeClassifier fd("haar_ff.xml");
UMat frame, frameGray; // the only change from plain CPU version
vector<Rect> faces;
for(;;){
    // processing loop
    vcap >> frame;
    cvtColor(frame, frameGray, BGR2GRAY);
    equalizeHist(frameGray, frameGray);
    fd.detectMultiScale(frameGray, faces, ...);
    // draw rectangles …
    // show image …
}

CUDA

cuda模塊已經(jīng)分成幾個(gè)較小的部分:

gpu命名空間已被刪除,使用cv :: cuda命名空間。許多課程也已經(jīng)重新命名,例如:

文件格式

文檔已轉(zhuǎn)換為Doxygen格式。您可以在OpenCV參考文檔(OpenCV的寫作文檔)的教程部分找到更新的文檔寫作指南。

支持兩個(gè)版本

在某些情況下,可以支持兩種版本的OpenCV。

源代碼

要檢查應(yīng)用程序源代碼中的庫(kù)主要版本,應(yīng)使用以下方法:

#include "opencv2/core/version.hpp"
#if CV_MAJOR_VERSION == 2
// do opencv 2 code
#elif CV_MAJOR_VERSION == 3
// do opencv 3 code
#endif
注意
不要使用CV_VERSION_MAJOR,它對(duì)2.4和3.x分支有不同的含義!

構(gòu)建系統(tǒng)

通過(guò)檢查構(gòu)建系統(tǒng)中的庫(kù)版本,可以鏈接不同的模塊或啟用/禁用應(yīng)用程序中的某些功能。可以使用標(biāo)準(zhǔn)cmake或pkg-config變量:

  • OpenCV_VERSION 對(duì)于cmake將包含完整版本:“2.4.11”或“3.0.0”
  • OpenCV_VERSION_MAJOR 對(duì)于cmake將僅包含主版本號(hào):2或3
  • pkg-config文件有標(biāo)準(zhǔn)字段 Version

例:

if(OpenCV_VERSION VERSION_LESS "3.0")
# use 2.4 modules
else()
# use 3.x modules
endif()
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)