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++程式相同。

參考資料:

39 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