2015/12/25

Raspberry Pi:Raspbian編譯OpenCV原始碼

我的環境是Raspberry Pi 2、Raspbian Jessie(2015-11-21),自行編譯OpenCV(Open Source Computer Vision Library),我抓的版本是3.1.0。

先更新套件清單並升級:
$ sudo apt-get update
$ sudo apt-get dist-upgrade -y

若是直接安裝現成的套件,指令如下:
$ sudo apt-get install libopencv-dev

不過得到的OpenCV版本通常過舊,因此自行下載原始碼,手動建置編譯。從OpenCV官方的安裝步驟,得知需要先安裝一堆相依套件。

建置與編譯所需工具:
$ sudo apt-get install build-essential gcc cmake pkg-config

抓原始檔需要的工具:
$ sudo apt-get install git

Python相關:
$ sudo apt-get install python python-dev python-numpy

圖形視窗程式庫:
$ sudo apt-get install libgtk2.0-dev

音訊視訊的編解碼、錄製、轉換、串流:
$ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev

圖檔格式(選用性):
$ sudo apt-get install libjpeg-dev libpng-dev libtiff-dev libjasper-dev

IEEE 1394相機介面(選用性):
$ sudo apt-get install libdc1394-22-dev

TBB(Intel's Threading Building Blocks)(選用性):
$ sudo apt-get install libtbb2 libtbb-dev
出現錯誤訊息:
E: Unable to locate package libtbb2
E: Package 'libtbb-dev' has no installation candidate

大都沒問題,但是Raspbian沒有libtbb2和libtbb-dev這兩個套件,於是也必須自己編譯;照理說這是選用性功能,可有可無,但TBB是C/C++平行處理程式庫,有了它,OpenCV的速度會較快。

到TBB網站,查詢原始碼檔案的網址,下載並解壓縮,得到含原始碼檔案的目錄,切換進去:
$ wget
https://www.threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb44_20151115oss_src.tgz
$ tar zxvf tbb44_20151115oss_src.tgz
$ cd tbb44_20151115oss

開始建置,根據這篇,應加上參數:
$ make tbb CXXFLAGS="-DTBB_USE_GCC_BUILTINS=1 -D__TBB_64BIT_ATOMICS=0"

然後進入子目錄build,裡頭會有兩個目錄存放建置結果,其一以debug結尾、另一個以release結尾,切換到release那一個:
$ cd build
$ cd linux_armv7_gcc_cc4.9.2_libc2.19_kernel4.1.13_release

執行tbbvars.sh這支腳本程式檔,它會設定許多環境變數,之後的OpenCV才知道TBB在哪:
$ source tbbvars.sh

搞定TBB後,接著是OpenCV,原始碼檔案約580 MB,建置後需要約1.6 GB,請先確認儲存空間是否足夠。

以git下載位於GitHub的OpenCV原始碼,得到目錄opencv,切換進去:
$ git clone https://github.com/Itseez/opencv.git
$ cd opencv

目前處於最新的版本分支,到OpenCV官網查詢後,得知目前釋出的正式版本為3.1.0,所以決定切換到該分支:
$ git checkout 3.1.0

新增目錄build存放建置結果,切換進去:
$ mkdir build
$ cd build

先執行cmake產生建置需要的設定檔:
$ cmake -DWITH_TBB:BOOL=TRUE -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..

其中「-DWITH_TBB:BOOL=TRUE「代表我們想要使用TBB,「-D CMAKE_INSTALL_PREFIX=/usr/local」代表之後要安裝的路徑,最後的「..」代表原始碼所在路徑。

然後開始建置:
$ make -j4

由於Raspberry Pi的CPU速度很慢,根據其他人的經驗,約需要10小時。但我使用Pi 2,可下參數「-j4」充分利用四個核心,我大概花了3小時。

最後終於出現完成的訊息:
...
Linking CXX executable ../../bin/opencv_test_calib3d
[100%] Built target opencv_test_calib3d
Linking CXX shared module ../../lib/python3/cv2.cpython-34m.so
[100%] Built target opencv_python3
Linking CXX shared module ../../lib/cv2.so
[100%] Built target opencv_python2

然後安裝:
$ sudo make install

執行指令更新程式庫:
$ sudo ldconfig

試著檢查OpenCV的版本:
$ pkg-config --modversion opencv
3.1.0

耶!

然後是是撰寫C++程式,顯示一張圖檔。新增檔案test.cpp,準備一張圖檔test.png,程式內容如下:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char **argv)
{
    Mat image = imread("test.jpg", CV_LOAD_IMAGE_COLOR);
    namedWindow("test", WINDOW_AUTOSIZE);
    imshow("test", image);
    waitKey(0);
    return 0;
}

以底下兩道指令之一進行編譯:
$ g++ -lopencv_core -lopencv_highgui -lopencv_imgcodecs tes.cpp
$ g++ `pkg-config --libs opencv` test.cpp

執行:
$ ./a.out

啊哈,成功囉。

試試Python程式,新增檔案test.py,與圖檔test.png放在一起,程式內容如下:
import cv2

img=cv2.imread('test.jpg')
cv2.imshow('test', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

然後執行:
$ python test.py

結果與先前的C++程式相同。

參考資料:

59 comments:

  1. 葉大師您好,根據這個Build安裝以後,我發現以前裝的simpleCV反而不能進入執行,看了錯誤訊息好像是跟opencv的某些物件有關,如果簡單的camera擷取跟相關python import simplecv不能用的話,那蠻可惜的,請問您是否有解決simplecv問題的方法,simplecv的安裝是參考連結的文章http://www.eeboard.com/bbs/thread-42743-1-1.html

    ReplyDelete
    Replies
    1. 什麼錯誤訊息?

      Delete
    2. 嗯~因為我的Pi2在家裡不在公司,實際上跑出來的錯誤訊息,等我實際回家跑過後,再看是貼圖或是把訊息寫在這裡

      Delete
    3. 這種大型套件,相依的部份很多,目錄、設定檔、路徑也都會影響。
      如果以套件安裝指令進行安裝,都會幫你搞定。
      如果你不需要最新版本,用原來的方式就好了。

      或可參考官方文件
      Installing SimpleCV on the Raspberry Pi
      https://github.com/sightmachine/SimpleCV/blob/develop/doc/HOWTO-Install%20on%20RaspberryPi.rst

      我有空的話再試試。

      Delete
    4. 既然你使用SimpleCV,應該不需要自行建置、安裝OpenCV,徒增困擾。
      因為SimpleCV各版本、不一定能與OpenCV最新版搭配使用。

      Delete
    5. 嗯嗯~首先感謝葉先生樹莓派的這個BLOG,我從中獲益良多,也從其中學得不少嵌入系統的技巧,跟系統構思,而會想到使用opencv部件,是剛好有影像辨識的專案在跑準備要進行,我在您參考資料連結中看到其中一個很不錯的例子,This•Raspberry Pi臉孔辨識藏寶盒 - Make 國際中文版。想先自己用自研的Pi2跑跑練習,而impleCV是之前做影像監控專案時,那時候寫程式建的,在此之前其實我有用過apt-get指令下過opencv,不過如您文章所述,版本過舊問題,所以一直閒置沒繼續,後來看到這篇安裝,覺得如獲至寶,就安裝成功了,但是相對的simplecv進不了他的debug console,每次打simplecv就出現了好幾條error message看來都跟opencv有關,詳情我可能回家下班再放上,我平時都有做image,所以退回前面的版本未安裝前應該是沒問題,不過還是蠻好奇為何會相衝突?詳情我在Pi2跑完再跟葉先生回覆說明。

      Delete
    6. 有篇參考文章
      http://tothinkornottothink.com/post/59305587476/raspberry-pi-simplecv-opencv-raspicam-csi

      http://raspberrypi.stackexchange.com/questions/6806/simplecv-installation-on-raspberry-pi
      都能成功安裝。

      不過我試了以後,指令simplecv會出現錯誤
      ImportError: Cannot load OpenCV library which is required by SimpleCV

      我的OpenCV版本3.1,SimpleCV版本1.3。

      找不出原因,只能猜測是因為OpenCV 版本3改了什麼東西,導致不相容。

      建議你試試OpenCV 2.4的版本,也就是上述參考資料、別人嘗試成功的版本。

      Delete
    7. 嗯~總算把整個錯誤訊息抓下來了如下:
      Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
      permitted by applicable law.
      Last login: Wed Dec 30 14:43:40 2015
      pi@raspberrypi ~ $ simplecv
      Traceback (most recent call last):
      File "/usr/local/bin/simplecv", line 9, in
      load_entry_point('SimpleCV==1.3', 'console_scripts', 'simplecv')()
      File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 356, in load_entry_point
      return get_distribution(dist).load_entry_point(group, name)
      File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 2476, in load_entry_point
      return ep.load()
      File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 2190, in load
      ['__name__'])
      File "/home/pi/Code/simpleCV/SimpleCV/__init__.py", line 3, in
      from SimpleCV.base import *
      File "/home/pi/Code/simpleCV/SimpleCV/base.py", line 60, in
      raise ImportError("Cannot load OpenCV library which is required by SimpleCV")
      ImportError: Cannot load OpenCV library which is required by SimpleCV
      其實結果跟葉大師遇到的情況一樣,我認為是某些設定跟部件Lib是相衝突的,
      但是翻閱國外其他樹莓派先進,似乎沒人提問過這個問題?....所以怎麼避開跟解這個現象的方法不明。

      Delete
    8. 他們應該都是用2.x版OpenCV。

      Delete
    9. 我剛又再試一遍,安裝既有的OpenCV套件,會是版本2.4.9,
      然後根據
      https://github.com/sightmachine/SimpleCV/blob/develop/doc/HOWTO-Install%20on%20RaspberryPi.rst
      安裝simplecv,並執行,發現可以。

      Delete
    10. 嗯嗯~謝謝葉大.我剛剛把SD卡還原了,如果2.4.9版可以,那麼我就接著跑跑看人臉辨識,其實我在最近的MagPi有看到有人提及用simpleCV做了人臉辨識,不過沒看到公開的程式碼,倒是opencv的範例比較齊全,可以再研究看看.另外祝葉大新年快樂,趕快跟喜歡的對象去跨年吧^_^

      Delete
  2. Dear 葉版主:
    在下"cmake -DWITH_TBB:BOOL=TRUE -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local .."
    指令時,出現了
    -- checking for module 'tbb'
    -- package 'tbb' not found
    這樣還會使用到TBB 這個module嗎?

    ReplyDelete
    Replies
    1. 'tbb' not found 找不到tbb,自然不會使用TBB囉。

      Delete
  3. git clone https://github.com/Itseez/opencv.git

    ReplyDelete
  4. 請問你是用什麼程式 寫c的

    ReplyDelete
    Replies
    1. 什麼?

      這篇文章裡有C++跟Python。

      Delete
  5. 請問raspberry pi model a+可以跑嗎?

    ReplyDelete
    Replies
    1. 理論上可以,咳咳,理論上什麼都可以。

      實際上沒試過,網路上也找不到。

      Delete
  6. This comment has been removed by the author.

    ReplyDelete
  7. git clone git@github.com:Itseez/opencv.git
    這邊應該要改成
    git clone https://github.com/Itseez/opencv.git

    ReplyDelete
    Replies
    1. 謝謝。

      如果你有git帳號並設定好的話,也是可以用
      git clone git@github.com:Itseez/opencv.git 下載。

      Delete
    2. 哦哦,原來是這樣~

      感謝葉難大大

      Delete
  8. Anonymous31/8/16 15:26

    葉老師你好
    請問 建置完成後 是否能把原先的資料夾以及檔案刪除呢?

    ReplyDelete
    Replies
    1. 安裝後可刪除原始檔案。

      Delete
    2. Anonymous31/8/16 16:49

      了解。
      不過看起來是只能刪opencv部分
      TBB似乎要留著?
      假設TBB不能刪,把它移到別的資料夾,要再做一次source tbbvars.sh是嗎?

      Delete
    3. 喔...對喔。
      自己試試看吧。呵。:D

      Delete
  9. This comment has been removed by the author.

    ReplyDelete
  10. This comment has been removed by the author.

    ReplyDelete
  11. 葉老師你好,
    我是剛接觸RPi3一個月的新手,不知道您有沒有接觸過uv4l(user space vide0 for linux)這個driver。
    之前利用OpenCV3 + Netbeans + Webcam(Logitech c310)擷取影像,有成功擷取;後來購買了CSI Raspicam後,依照網路上的方法安裝了uv4l-raspicam,在利用OpenCV3擷取影像有成功,但反而Webcam不能擷取影像了,有用指令找到Webcam的位置(/dev/videoX),並利用OpenCV3的指令選擇直接驅動Webcam,Webcam訊號燈有閃但是影像擷取不出來,不知道葉老師有什麼解法嗎?
    不好意思問了跟文章沒有相關的問題,小弟看了很多葉老師的文章學習RPi相關的知識,謝謝您的文章。

    ReplyDelete
    Replies
    1. 沒能力回答。
      可能出錯的地方很多。

      謝謝。

      Delete
    2. 雖然您打了很多字盡力描述,
      但隔空抓藥實在太難,系統設定、組態、指令參數、驅動程式模組等等,
      都有可能出錯。

      Delete
  12. 葉老師您好,

    我在樹莓派A+上安裝opencv3.1.0時,
    出現如下的訊息, CMakeFiles/Makefile2:1317:recipe for 'target' modules/core/CMakeFiles/pch_Generate_opencv_core.dir/all' failed
    不知道這該如何解決?

    ReplyDelete
    Replies
    1. 不知道。
      我猜是gcc g++的行為改變了。你的gcc/g++是哪一版?
      完整的錯誤訊息?

      Delete
  13. cc1plus: out of memory allocating 2544036 bytes after a total of 22085632 bytes
    modules/flann/CMakeFiles/pch_Generate_opencv_test_flann.dir/build.make:56: recipe for target 'modules/flann/test_precomp.hpp.gch/opencv_test_flann_Release.gch' failed
    make[2]: *** [modules/flann/test_precomp.hpp.gch/opencv_test_flann_Release.gch] Error 1
    CMakeFiles/Makefile2:1644: recipe for target 'modules/flann/CMakeFiles/pch_Generate_opencv_test_flann.dir/all' failed
    make[1]: *** [modules/flann/CMakeFiles/pch_Generate_opencv_test_flann.dir/all] Error 2
    make[1]: *** Waiting for unfinished jobs....
    [ 32%] Built target pch_Generate_opencv_test_core
    [ 32%] Built target pch_Generate_opencv_perf_imgproc
    [ 32%] Built target pch_Generate_opencv_test_imgproc
    Makefile:146: recipe for target 'all' failed
    make: *** [all] Error 2

    ReplyDelete
    Replies
    1. 葉老師抱歉, 我是昨天晚上9:32分時請教您的人, 如上是我的錯誤訊息

      Delete
    2. cc1plus: out of memory allocating 2544036 bytes after a total of 22085632 bytes
      看起來因為記憶體不足,
      你用哪塊板子?
      把記憶體分割多一點給CPU。

      Delete
    3. 沒見過有人在A+上編譯opencv。

      或許啟用swap可解決,但我不清楚。

      Delete
    4. 好的 我試試看 謝謝您

      Delete
  14. 葉老師您好:
    請問我用樹莓派RPi3,作業系統:ubuntu mate14.04按照您的文章進行編譯這個步驟
    開始建置:
    $ make -j4
    跑跑跑 通常編譯到85%就當機機或更少%就當機,無法編譯完成。
    請問通常是什麼問題,謝謝您。

    ReplyDelete
    Replies
    1. 當機?你是說整台機器當掉、重新開機嗎?
      還是make指定停掉?

      有錯誤訊息嗎?

      Delete
    2. 整台機器當機 滑鼠鍵盤失效 無法動作。

      Delete
    3. 建置到[85%] Built target.....
      系統時間停滯 放著也沒進度在跑!!

      Delete
    4. 目前在第三次建置看看,有沒有錯誤訊息 謝謝老師回覆

      Delete
    5. 建置第三次到13%就整個系統當機畫面停滯,我樹莓派有用個5v風扇進行散熱不曉得是否有影響系統店員穩定性,畫面右上角也沒出現彩紅方塊。

      Delete
  15. 葉老師您好:
    剛剛試一下當機之後沒辦法繼續建置下去,只能把build資料下刪除在建置一次看看。
    記憶卡配置:ADATA C10 -U1 32GB
    電源:東芝2A電源供應器
    謝謝您!!

    ReplyDelete
    Replies
    1. 錯誤訊息是什麼?

      Delete
    2. 沒有錯誤訊息!!

      Delete
    3. 真誇張。

      沒在rpi上用過ubuntu,
      只能想到是不是這個原因。

      好像有人成功,請參考
      http://speark.tistory.com/12

      Delete
    4. 恩 目前想到對策先建置前先把週邊配備先拔除試看看,謝謝老師。
      不然可能真的只能使用官方推薦的作業系統。

      Delete
  16. 感謝老師已經可以建置成功並可以運作。
    原因不是周邊設備關係,原來是make -j4開啟四核心全速跑會當機,可能過熱或耗電量增加死當。
    所以我就用雙核心make -j2 下去跑一切順暢成功100%,可能我的樹莓派3代體質不好QQ

    ReplyDelete
    Replies
    1. 多謝回報。

      > 可能我的樹莓派3代體質不好
      嗯,或許吧。
      也可能是記憶卡的部份。

      以指令/opt/vc/bin/vcgencmd measure_temp 可看溫度多少。

      Delete
  17. 感謝老師已經可以建置成功並可以運作。
    原因不是周邊設備關係,原來是make -j4開啟四核心全速跑會當機,可能過熱或耗電量增加死當。
    所以我就用雙核心make -j2 下去跑一切順暢成功100%,可能我的樹莓派3代體質不好QQ

    ReplyDelete
  18. Kevin chiang30/12/16 10:58

    請問葉老師:如果碰到利用您上述測試test.cpp編譯cpp,錯誤訊息如下:
    /tmp/ccF4130N.o: 於函式 main:
    test.cpp:(.text+0x34): 未定義參考到「cv::imread(cv::String const&, int)」
    test.cpp:(.text+0x5c): 未定義參考到「cv::namedWindow(cv::String const&, int)」
    test.cpp:(.text+0x98): 未定義參考到「cv::imshow(cv::String const&, cv::_InputArray const&)」
    test.cpp:(.text+0xb2): 未定義參考到「cv::waitKey(int)」
    /tmp/ccF4130N.o: 於函式 cv::String::String(char const*):
    test.cpp:(.text._ZN2cv6StringC2EPKc[_ZN2cv6StringC5EPKc]+0x28): 未定義參考到「cv::String::allocate(unsigned int)」
    /tmp/ccF4130N.o: 於函式 cv::String::~String():
    test.cpp:(.text._ZN2cv6StringD2Ev[_ZN2cv6StringD5Ev]+0xa): 未定義參考到「cv::String::deallocate()」
    /tmp/ccF4130N.o: 於函式 cv::Mat::~Mat():
    test.cpp:(.text._ZN2cv3MatD2Ev[_ZN2cv3MatD5Ev]+0x20): 未定義參考到「cv::fastFree(void*)」
    /tmp/ccF4130N.o: 於函式 cv::Mat::release():
    test.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x3e): 未定義參考到「cv::Mat::deallocate()」
    collect2: error: ld returned 1 exit status
    請問這是發生什麼問題??謝謝 python可以正常編譯!!
    目前安裝最新版本opencv 3.2.0

    ReplyDelete
    Replies
    1. 未定義參考到 undefined reference to
      編譯器找不到test.cpp裡呼叫使用的各個東西,包括imread、namedWindow,

      編譯指令有下對嗎?
      $ g++ -lopencv_core -lopencv_highgui -lopencv_imgcodecs tes.cpp

      Delete
    2. 謝謝葉老師回應!也祝福2017新年快樂!
      測試結果:Ubuntu MATE python可以運行 c/c++不能編譯
      Raspbian Jessie with PIXEL( 2016-11-25) python可以運行 c/c+可以運行
      以上是運作在Raspbery pi 3 使用open cv 3.1.0 !!
      用樹莓派編譯真的花不少時間!!

      Delete
    3. Ubuntu MATE 指令有下對
      $ g++ -lopencv_core -lopencv_highgui -lopencv_imgcodecs test.cpp
      不知道是否Ubuntu MATE沒有link到opencv library

      Delete
    4. 多謝回報。花了不少時間吧,呵。

      理論上,都是Linux系統,應該一樣。
      實際上,跟理論不同。

      Ubuntu的話,到網路上找找其他人的經驗吧,
      例如 http://answers.opencv.org/question/25642/how-to-compile-basic-opencv-program-in-c-in-ubuntu/

      Delete