Ubuntu16.04源碼編譯安裝opencv4.1.2+opencv_contrib的C++接口

0. 安裝一些必要的包

sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev

1. 下載opencv/opencv_contrib源代碼

這里直接從opencv的github倉庫clone最新的opencv源代碼到本地:

cd /home/yan/
git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git

在本地目錄home/yan/下面將會得到兩個文件夾:

yan@yanubuntu:~$ ll | grep opencv
drwxrwxr-x 15 yan  yan    4096 9月  14 14:09 opencv/
drwxrwxr-x  7 yan  yan    4096 9月  14 09:38 opencv_contrib/

2. cmake生成MakeFile文件

依次執(zhí)行以下命令:

cd /home/yan/opencv/
mkdir build
cd build

接下來是cmake命令:

cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=/home/yan/opencv_contrib/modules -D PYTHON_DEFAULT_EXECUTABLE=/usr/bin/python3 -D BUILD_opencv_python3=ON -D BUILD_opencv_python2=OFF -D PYTHON3_EXCUTABLE=/usr/bin/python3 -D PYTHON3_INCLUDE_DIR=/usr/include/python3.5m -D WITH_CUDA=OFF -D OPENCV_GENERATE_PKGCONFIG=ON ..

對cmake的某些參數(shù)作解釋:

cmake 
-D CMAKE_BUILD_TYPE=Release 
-D CMAKE_INSTALL_PREFIX=/usr/local 
# 如果要安裝opencv_contrib模塊宵统,需要指定對應(yīng)的modules文件夾位置
-D OPENCV_EXTRA_MODULES_PATH=/home/yan/opencv_contrib/modules
# 基本用不到python2趣钱,因此這里只編譯python3的opencv版本 
-D PYTHON_DEFAULT_EXECUTABLE=/usr/bin/python3 
-D BUILD_opencv_python3=ON 
-D BUILD_opencv_python2=OFF 
-D PYTHON3_EXCUTABLE=/usr/bin/python3 
-D PYTHON3_INCLUDE_DIR=/usr/include/python3.5m
# 不需要使用opencv的GPU加速,將CUDA選項關(guān)掉 
-D WITH_CUDA=OFF 
# 這個選項非常重要星岗,會生成一個被pkg-config模塊使用的opencv4.pc文件,編譯opencv的c++項目時可能會用到
-D OPENCV_GENERATE_PKGCONFIG=ON 

cmake過程中會下載某些文件戒洼,比較慢俏橘,請耐心等待。

3. make & make install

cmake完成后圈浇,依次執(zhí)行:

make -j8
sudo make install

make編譯過程也比較慢寥掐,通過 -j8 實現(xiàn)多線程加速。

4. 后處理

打開home目錄下的.bashrc文件:

sudo vim ~/.bashrc

在最后添加如下環(huán)境變量:

export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig

該目錄下面有一個opencv4.pc文件磷蜀,查看一下里面有哪些內(nèi)容:

yan@yanubuntu:~$ ls /usr/local/lib/pkgconfig/
libspatialindex.pc  opencv4.pc
yan@yanubuntu:~$ cat /usr/local/lib/pkgconfig/opencv4.pc 
# Package Information for pkg-config

prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv4/opencv
includedir_new=${prefix}/include/opencv4

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 4.1.2
Libs: -L${exec_prefix}/lib -lopencv_stitching -lopencv_gapi -lopencv_bgsegm -lopencv_img_hash -lopencv_xfeatures2d -lopencv_shape -lopencv_superres -lopencv_freetype -lopencv_aruco -lopencv_dnn_objdetect -lopencv_ccalib -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_stereo -lopencv_tracking -lopencv_datasets -lopencv_plot -lopencv_rgbd -lopencv_fuzzy -lopencv_line_descriptor -lopencv_reg -lopencv_hfs -lopencv_bioinspired -lopencv_surface_matching -lopencv_optflow -lopencv_ximgproc -lopencv_quality -lopencv_dpm -lopencv_highgui -lopencv_xobjdetect -lopencv_saliency -lopencv_hdf -lopencv_text -lopencv_dnn -lopencv_ml -lopencv_face -lopencv_objdetect -lopencv_videostab -lopencv_video -lopencv_calib3d -lopencv_videoio -lopencv_imgcodecs -lopencv_features2d -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core
Libs.private: -ldl -lm -lpthread -lrt
Cflags: -I${includedir_old} -I${includedir_new}

opencv4.pc文件(貌似opencv3.x之前是生成名為opencv.pc的文件召耘,這里編譯的是opencv4.1.2,因此變成了opencv4.pc)是在前面cmake時通過添加-D OPENCV_GENERATE_PKGCONFIG=ON選項自動生成的褐隆。

該文件實際上也就是指定了安裝opencv生成的 Include/包含目錄Libs/庫目錄 的路徑污它,以便在使用g++編譯包含opencv函數(shù)的c++代碼時,就可以使用 pkg-config 選項指定opencv庫的搜索路徑。

有了 opencv4.pc 文件衫贬,以及將該文件路徑添加到 PKG_CONFIG_PATH 環(huán)境變量之后德澈。就可以通過pkg-config命令來查看安裝的opencv的一些信息了,比如:

# 查看opencv的版本號
yan@yanubuntu:~$ pkg-config --modversion opencv4
4.1.2
# 查看opencv的Include目錄/頭文件路徑
yan@yanubuntu:~$ pkg-config --cflags opencv4
-I/usr/local/include/opencv4/opencv -I/usr/local/include/opencv4
# 查看opencv的Libs目錄/庫目錄
yan@yanubuntu:~$ pkg-config --libs opencv4
-L/usr/local/lib -lopencv_stitching -lopencv_gapi -lopencv_bgsegm -lopencv_img_hash -lopencv_xfeatures2d -lopencv_shape -lopencv_superres -lopencv_freetype -lopencv_aruco -lopencv_dnn_objdetect -lopencv_ccalib -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_stereo -lopencv_tracking -lopencv_datasets -lopencv_plot -lopencv_rgbd -lopencv_fuzzy -lopencv_line_descriptor -lopencv_reg -lopencv_hfs -lopencv_bioinspired -lopencv_surface_matching -lopencv_optflow -lopencv_ximgproc -lopencv_quality -lopencv_dpm -lopencv_highgui -lopencv_xobjdetect -lopencv_saliency -lopencv_hdf -lopencv_text -lopencv_dnn -lopencv_ml -lopencv_face -lopencv_objdetect -lopencv_videostab -lopencv_video -lopencv_calib3d -lopencv_videoio -lopencv_imgcodecs -lopencv_features2d -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core

5. 測試: 使用opencv顯示圖像

下面測試opencv的c++接口固惯,新建如下的DisplayImage.cpp文件:

// DisplayImage.cpp -- my first c++/opencv code in linux system

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;

int main()
{
    string img_path = "img.png";
    Mat image;
    image = imread(img_path);

    if(image.data == NULL)
    {
        cout<<"No image data \n";
        return -1;
    }
    namedWindow("DisplayImage", WINDOW_AUTOSIZE);
    imshow("DisplayImage", image);
    waitKey(0);

    return 0;
}

假設(shè)cpp文件所在的文件夾下包含一個名為 img.png 的圖片文件梆造。
下面介紹如何編譯cpp文件到可執(zhí)行文件。有幾種方式:

5.1 g++帶pkg-config參數(shù)

命令如下:

yan@yanubuntu:~/Desktop/c_plus_opencv_sample$ ls
DisplayImage.cpp  img.png
yan@yanubuntu:~/Desktop/c_plus_opencv_sample$ g++ DisplayImage.cpp -o DisplayImage.out $(pkg-config --cflags --libs opencv4) --std=c++11
yan@yanubuntu:~/Desktop/c_plus_opencv_sample$ ls
DisplayImage.cpp  DisplayImage.out  img.png

可以看到葬毫,編譯成功后镇辉,生成了可執(zhí)行文件DisplayImage.out。
運行可執(zhí)行文件DisplayImage.out:

yan@yanubuntu:~/Desktop/c_plus_opencv_sample$ ./DisplayImage.out

不出意外的話贴捡,圖片就顯示成功了:


這里是直接使用g++編譯cpp文件忽肛,解釋一下用到的編譯選項:

g++ DisplayImage.cpp 
# 通過 -o 選項,指定生成的可執(zhí)行文件的文件名栈暇,如果不指定的話麻裁,默認(rèn)會生成一個 *a.out*的可執(zhí)行文件
-o DisplayImage.out 
# 使用pkg-config選項指定cpp代碼中用到的所有opencv的包含文件以及庫文件,前面提到源祈,opencv4.pc中提供了這些路徑信息煎源。
$(pkg-config --cflags --libs opencv4) 
# 使g++編譯器支持c++11特性
# 如果沒有這個選項,會出現(xiàn)類似error信息: error: #error "OpenCV 4.x+ requires enabled C++11 support"
--std=c++11

關(guān)于pkg-config工具的介紹請參考官網(wǎng)香缺。
以上面的cpp代碼為例手销,由于代碼中用到了opencv的兩個頭文件中定義的函數(shù):

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

因此,在g++編譯鏈接過程中图张,我們需要給編譯器提供opencv相關(guān)的包含文件路徑以及庫文件路徑锋拖,這樣g++才能生成完整的可執(zhí)行文件。
而pkg-config工具就是專門管理gcc/g++編譯過程中需要用到的依賴模塊路徑的:

  • 前面我們編譯opencv時生成了一個opencv4.pc文件祸轮,該文件包含了所有opencv的包含文件/庫文件路徑兽埃。
  • 通過將opencv4.pc文件的路徑添加到PKG_CONFIG_PATH 環(huán)境變量,pkg-config工具就掌握了opencv相關(guān)文件的所有路徑信息适袜。
  • g++ 編譯時柄错,通過提供 $(pkg-config --cflags --libs opencv4) 選項,pkg-config工具會提供g++所需的opencv相關(guān)依賴文件的路徑苦酱。

不僅是opencv售貌,其他所有的庫的路徑都可以通過pkg-config來統(tǒng)一管理。

2. 通過cmake + make生成可執(zhí)行文件

典型的c++項目的編譯方式應(yīng)該是使用cmake + make的方式疫萤。需要編寫一個 CMakeLists.txt 文件:

cmake_minimum_required(VERSION 2.8)
project(DisplayImage)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(DisplayImage DisplayImage.cpp)
target_link_libraries(DisplayImage ${OpenCV_LIBS})
SET( CMAKE_CXX_FLAGS "-std=c++11")

保存后執(zhí)行cmake生成MakeFIle文件,然后執(zhí)行make得到可執(zhí)行文件:

yan@yanubuntu:~/Desktop/c_plus_opencv_sample$ cmake .
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenCV: /usr/local (found version "4.1.2") 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/yan/Desktop/c_plus_opencv_sample
yan@yanubuntu:~/Desktop/c_plus_opencv_sample$ make
Scanning dependencies of target DisplayImage
[ 50%] Building CXX object CMakeFiles/DisplayImage.dir/DisplayImage.cpp.o
[100%] Linking CXX executable DisplayImage
[100%] Built target DisplayImage
yan@yanubuntu:~/Desktop/c_plus_opencv_sample$

5.3 使用IDE

之前在Windows系統(tǒng)中用過VS颂跨,在ubuntu系統(tǒng)中還沒有使用過集成開發(fā)環(huán)境(Integrated Development Environment,IDE)扯饶,不過應(yīng)該和VS差不多恒削,這應(yīng)該是最簡單的編譯方式了池颈,點擊 run 按鈕,所有的編譯鏈接執(zhí)行過程自動完成蔓同。

目前對在linux系統(tǒng)的c++開發(fā)基本不懂饶辙,以上內(nèi)容純屬搬磚。僅供參考斑粱。

6. 參考資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末弃揽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子则北,更是在濱河造成了極大的恐慌矿微,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尚揣,死亡現(xiàn)場離奇詭異涌矢,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)快骗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門娜庇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人方篮,你說我怎么就攤上這事名秀。” “怎么了藕溅?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵匕得,是天一觀的道長。 經(jīng)常有香客問我巾表,道長汁掠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任集币,我火速辦了婚禮考阱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鞠苟。我一直安慰自己羔砾,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布偶妖。 她就那樣靜靜地躺著,像睡著了一般政溃。 火紅的嫁衣襯著肌膚如雪趾访。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天董虱,我揣著相機(jī)與錄音扼鞋,去河邊找鬼申鱼。 笑死,一個胖子當(dāng)著我的面吹牛云头,可吹牛的內(nèi)容都是我干的捐友。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼溃槐,長吁一口氣:“原來是場噩夢啊……” “哼匣砖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起昏滴,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤猴鲫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后谣殊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拂共,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年姻几,在試婚紗的時候發(fā)現(xiàn)自己被綠了宜狐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛇捌,死狀恐怖抚恒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情豁陆,我是刑警寧澤柑爸,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站盒音,受9級特大地震影響表鳍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜祥诽,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一譬圣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧雄坪,春花似錦厘熟、人聲如沸虾标。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽恕刘。三九已至箩艺,卻和暖如春镀层,著一層夾襖步出監(jiān)牢的瞬間俘侠,已是汗流浹背酌泰。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工购撼, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留跪削,地道東北人谴仙。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像碾盐,于是被迫代替她去往敵國和親晃跺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容