[Raspberry Pi]在Pi上編譯 OpenCV 和多語言支援(C++&Python2,3) (2019/9/20更)

[前言]

Raspberry Pi大約是我高中所推出的新產品
當時很榮幸能遇到一位相當有眼光的老師
帶領我們玩了大約一年的這塊強大的板子
想當初的科展,我跟同學製作了霹靂燈的小小專題
當然 這題目真的沒甚麼 我不否認
但那些評審教授們完完全全看都不想看的感覺
甚至給我的感覺是不屑的
結果現在大學都快畢業了
全世界都在物聯網物聯網
不知道那些教授們現在過得如何

Raspberry Pi的優勢真的很多
他作為一個基礎的產品真的相當優異
而現在 他也進階到了第三版本
效能有了大幅的提升(雖然還是不怎麼高)
這使得他能做的處理與運算又更多了
這次 就把OpenCV安裝上去吧!

[該準備的東西]

1.可正常使用的PI (可使用SSH連線與網路功能) (以下都簡稱PI)
2.你現在正在使用的電腦

PI的安裝過程就不詳述了

[Step by Step]


參考了一下 pyimagesearch 的文章
修正了一些該安裝的libs 以及補安裝一些東西 (用黃色標記)
有需要使用Python virtual environment 的人可以點進去看
我是不太需要拉 .. (因為我不太會用虛擬環境)
-2019/9/19


更新PI
sudo apt-get update
sudo apt-get upgrade

安裝小插件提升效率
sudo apt-get install htop //加強版的top(工作管理員)
// 新版OS已內建
sudo apt-get install tightvncserver //VNC server

安裝必要lib
sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install libgtk-3-dev //新增

安裝相關的lib
sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt-get install libxvidcore-dev libx264-dev
sudo apt-get install libgdk-pixbuf2.0-dev libpango1.0-dev //新增
sudo apt-get install libatlas-base-dev gfortran
sudo apt-get install python-dev python3-dev  // python

pip install numpy
pip3 install numpy
//numpy建議採用pip安裝

取得OpenCV 和 OpenCV Contrib
git clone https://github.com/opencv/opencv.git
cd opencv
git checkout 4.1.1
git clone https://github.com/opencv/opencv_contrib.git
cd opencv_contrib
git checkout 4.1.1
//可自行更改下載路徑 但別自己忘記了
建議這裡真的要確定兩個版本是一樣然後是你想要的版本

編譯OpenCV
//進入opencv 並新增build資料夾
cd opencv
mkdir build
cd build

//cmake參數 可依照個人需求作增減
cmake -D CMAKE_BUILD_TYPE=Release \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
-D BUILD_opencv_python2=ON \
-D BUILD_opencv_python3=ON \
-D INSTALL_PYTHON_EXAMPLES=OFF \
-D INSTALL_C_EXAMPLES=OFF \
-D BUILD_EXAMPLES=OFF \
-D ENABLE_NEON=ON \
-D ENABLE_VFPV3=ON \
-D OPENCV_ENABLE_NONFREE=ON \
-D CMAKE_SHARED_LINKER_FLAGS=-latomic \
-D OPENCV_GENERATE_PKGCONFIG=YES ..
//參數應該都滿好理解的 
//OPENCV_EXTRA_MODULES_PATH 要指到剛剛下載opencv_contrib的資料夾 特別注意!
//新增5個新flag

CMake執行的時間大約5分鐘以內
如果執行正確 下面會有configured successfully和generated successfully的字樣
但還需特別檢查幾個部分
1.確認OPENCV_EXTRA_MODULES_PATH是正確的 且版本與下載的OpenCV相符

2.Python2與3的各個路徑都是正確的
這裡主要檢查每個項目後面都是有路徑的 基本上這樣就沒問題


3.檢查GTK與 Non-free
新版的OpenCV似乎抓不到2.0版本的gtk 導致後續的編譯錯誤
以及Non-free algorithms是YES

4.檢查有最後這兩個done




確認無誤後就可以往下一步走了

make -j4  //多核編譯 可能需要加大SWAP記憶體 [註1]
//這個需要編譯一段時間 可以先去做別的事
sudo make install
sudo ldconfig
//需要c++環境的跳至[註2]

Done!
到這裡就完成編譯的工作了

接下來要來檢查是否安裝成功
C++檢查
pkg-config --modversion opencv
>> 3.3.0
//若安裝正確會回傳OpenCV的版本
新版本似乎無法直接連結 需要額外的一些指令

Python2檢查
python
import cv2
cv2.__version__
>> 3.3.0

Python3檢查
python3
import cv2
cv2.__version__
>> 3.3.0

一切正常的話那就大功告成拉
一次編譯 多語言都可以用
省時又省力!


[Update]

陸陸續續滿多人反映根據文章編譯會出錯
剛好最近Pi 4新推出 我也入手了一台
這幾天會更新一下 OpenCV 4.1.1 w/ Raspberry Pi 4 編譯心得與一些修正建議
-2019/9/19

[註1]

如果你使用make -j4發生記憶體不足的錯誤 試試下面的解法 
(1) 不要加-j4 直接make看看
(2) 參考下列指令增加虛擬記憶體
sudo nano /etc/dphys-swapfile

//找到這行將SWAPSIZE更改為1024
# CONF_SWAPSIZE=100
CONF_SWAPSIZE=1024

//ctrl+x, y, enter離開

//重啟SWAP
sudo /etc/init.d/dphys-swapfile stop
sudo /etc/init.d/dphys-swapfile start

//完成後可以用htop看看是否有改成功 上方swp應該要等於1G


[註2]

網路上搜尋到cv-tricks的一篇文章
雖然是裝在ubuntu上但補那些指令之後c++就可以正常編譯了 以下指令接續make完成無誤之後
//安裝lib
sudo make install
sudo sh -c 'echo "/usr/local/lib" >> /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig

//修改opencv4.pc 在includedir_old這行後面補上一個2
sudo nano ~/opencv/build/build/unix-install/opencv4.pc
//includedir_old=${prefix}/include/opencv4/opencv
includedir_old=${prefix}/include/opencv4/opencv2
//ctrl+x, y, enter離開

//重新連結
cd /usr/local/lib/
mkdir pkgconfig
sudo cp ~/opencv/build/unix-install/opencv4.pc /usr/local/lib/pkgconfig/

//更新環境變數PKG_CONFIG_PATH
sudo nano ~/.bashrc
//在此檔案的最下方加入這兩行
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
//ctrl+x, y, enter離開

//重新讀取一次
source ~/.bashrc
這樣子應該就沒有問題了 順便附上c++編譯的指令
g++ -std=c++11 HelloWorld.cpp `pkg-config --libs --cflags opencv4` -o result
//自行修改檔名

留言

  1. 請問版主能拍成影片嗎?
    我不知道哪裡出錯了
    他找不到我的安裝包
    感謝您~~

    回覆刪除
    回覆
    1. 哪個部分出錯呢?
      環境是甚麼?
      能幫的我盡量幫幫看

      刪除
  2. 請問在 visual studio 2015上使用c++搭配opencv dnn模塊寫好的影像處理程式要怎麼較輕鬆的移植到樹莓派上運行呢,例如樹莓派裝哪種作業系統與IDE,目前都是自己摸索查資料還麻煩大大指教謝謝!!

    回覆刪除
    回覆
    1. 我不是大大啦 這兩個字我還承擔不起XD

      要在pi上執行的話,原則上應該是要在pi上邊譯才可以
      把.hpp, .cpp檔丟上去編譯如果過了就是可以跑

      我目前的方法都是直接在pi上coding,用g++編譯
      OS的話我都是用Raspbian
      IDE基本上不用,我都是把code打好之後再pi上直接編譯執行(atom編輯器+ftp同步)
      如果不習慣下指令可以用pi接螢幕coding
      他就是一台速度比較慢的linux電腦
      linux上也是有不輸visual studio的IDE的

      刪除
    2. 您好 我在 make -j4 這個步驟跑到96%發生錯誤
      c++: internal compiler error: 程式記憶體區段錯誤 (program cc1plus)
      我使用的是opencv3.4.3 , 後續的make install步驟也是停在96%出現相同錯誤
      重新開機也無法解決~~ 還麻煩您指教謝謝!!

      刪除
    3. 出現這個的原因是Pi預設的swap不足導致
      先將-j4移除,單單使用make執行試試看過不過的了
      另外建議編譯的時盡量減少其他程式執行,並在CLI模式下編譯

      如果不行那就要去修改swap的大小了,這網路上已有許多教學

      make install要在make完成後執行才有意義
      make沒過當然install會失敗XD

      刪除
    4. 謝謝版大協助 =D
      參考這篇https://blog.gtwang.org/iot/raspberry-pi/raspberry-pi-swap-configuration-using-usb-stick/
      修改swap大小後 單使用make成功了!!

      另外發現 如果是用文章中的 git clone https://github.com/opencv/opencv.git方式下載opencv 在configured 和 generated 步驟 version control 、version control (extra) 顯示版本是3.4.3版 ,但最後 make 與install完成後,輸入指令 pkg-config --modversion opencv
      出現的版本卻是4.0.0-pre。
      後來移除4.0.0-pre 版 到opencv 官方git (左側Branch選單內tag選要下載的版本)
      https://github.com/opencv/opencv/tree/3.4.3
      https://github.com/opencv/opencv_contrib/tree/3.4.3
      抓zip檔下來解壓縮,重新make 與 install 就是3.4.3版了
      ( 會成功但不知道為什麼configured 和 generated 步驟 version control 、version control (extra) 顯示版本是unknow )

      編譯.cpp檔指令:
      $ g++ `pkg-config --libs opencv` test.cpp
      執行:
      $ ./a.out

      目前利用opencv dnn 模塊來做影像辨識,因為在windows上使用c++開發,為了要移植到樹莓派上面苦惱很久,問了幾位老師說沒辦法c++移植過來必須用QT在改寫,還好有搜尋到版大的文章,按照您文章的步驟再將自己的.cpp檔編譯後,一行程式都沒改就執行成功了 !!
      謝謝版大的文章與幫忙=D

      刪除
    5. 恭喜你完成了opencv的第一步XD

      其實版本問題我後來也有發現
      只是最近比較忙一點沒時間補指令+圖片上去

      如果有出現版本問題可以用以下指令來切換版本
      ~ cd opencv/
      ~ git fetch //取得目前版本的資訊
      ~ git checkout 3.4.3 //切換至指定版本
      如果有contrib也要記得切版本

      感謝提供相關指令 !

      其實,認真講的話,Raspberry Pi真的不太適合做神經網路計算就是了。
      不過真的要用的話我現在也都改用python了,tensorflow+keras基本上已經通吃了,模型基本上也都可以互吃。
      學學python不會吃虧的XD !

      刪除
    6. 請問如果是學keras 有什麼推薦的入門資源可以學習
      keras訓練出來的神經網絡opencv可以使用嗎
      目前比較想試看看識別台灣路上的紅綠燈,請問版大有什麼推薦的方案嗎,我是超級菜鳥XDD

      刪除
    7. keras不難,其實搜尋一下網路上就很多資源了,而且官方文件還有中文版。
      我記得是可以互吃的,但詳細的做法還要再去查一下。
      不過我是覺得多此一舉就是了拉哈。畢竟pi現在也能跑python+tf+keras。

      我不太確定你所想要辨識的環境是甚麼,如果是用神經網路,像車子在行進中辨識可不可行走,那我認為pi不太適合。ex: https://www.youtube.com/watch?v=nf6rk56wYuI
      這種環境YOLO的執行效果會很棒,但在pi上執行 .... 光是效能就會讓你崩潰了。
      但如果只是一張紅綠燈的圖要辨識是甚麼燈,那用opencv就可以了,不過你想要的應該是前者吧~

      通常這種載具是車子之類的,硬體選擇應該就不是用pi,而是tx2了。
      不過我最近發現一個pi的小玩意,如果效果不錯找時間在寫點東西上來。

      刪除
    8. 目前用 PI 3 + OpenCV + MobileNetSSD 每一個frame 需要1.4s ,改用YOLOv2 需要 2.5s
      如果改用PI3 搭配python+tf+keras 請問R大速度會有提升嗎

      目前想的情境大概是會搭配語音功能(盲人使用),所以應該是搭配快門按紐拍照用圖片的方式進行識別,紅綠燈因為是行人的,這方面台灣的燈號應該要自己訓練,請問整個流程以及圖片數據量大概需要具備怎樣的條件

      期待R大的新文章可以再跟您學習學習XDD

      刪除
    9. 如果已經有現成的c++的code那就不要轉了吧,應該是不會提升多少效能。
      要加快應該只能改模型吧。
      MobileNet有v2,Yolo有v3、tiny-Yolo v3,這些可能都要測試看看,我也不敢保證。

      我只有用過yolo,其實yolo訓練不太需要怎樣條件的圖片,只要有一定的量,標籤出你要辨識的物體,基本上就可以訓練了。 (我們幾乎都拿手機隨便拍一拍)
      詳細過程就要你自己去學習了,yolo的github看完一遍大概就懂了。

      別這麼說,我只稍微早接觸一點點而已,實際年齡我們應該差不多,互相學習即可!

      刪除
    10. 好的了解=D 謝謝R大!

      刪除
  3. 作者已經移除這則留言。

    回覆刪除
  4. /usr/bin/ld: CMakeFiles/opencv_shape.dir/src/aff_trans.cpp.o: file not recognized: file truncated
    collect2: error: ld returned 1 exit status
    make[2]: *** [modules/shape/CMakeFiles/opencv_shape.dir/build.make:163: lib/libopencv_shape.so.3.4.0] Error 1
    make[1]: *** [CMakeFiles/Makefile2:2647: modules/shape/CMakeFiles/opencv_shape.dir/all] Error 2
    make[1]: *** Waiting for unfinished jobs....
    /usr/bin/ld: CMakeFiles/opencv_imgcodecs.dir/src/loadsave.cpp.o: file not recognized: file truncated
    collect2: error: ld returned 1 exit status
    /usr/bin/ld: CMakeFiles/opencv_photo.dir/src/denoising.cuda.cpp.o: file not recognized: file truncated
    collect2: error: ld returned 1 exit status
    make[2]: *** [modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/build.make:370: lib/libopencv_imgcodecs.so.3.4.0] Error 1
    make[1]: *** [CMakeFiles/Makefile2:2548: modules/imgcodecs/CMakeFiles/opencv_imgcodecs.dir/all] Error 2
    make[2]: *** [modules/photo/CMakeFiles/opencv_photo.dir/build.make:287: lib/libopencv_photo.so.3.4.0] Error 1
    make[1]: *** [CMakeFiles/Makefile2:2123: modules/photo/CMakeFiles/opencv_photo.dir/all] Error 2
    /usr/bin/ld: CMakeFiles/opencv_dnn.dir/misc/tensorflow/op_def.pb.cc.o: file not recognized: file truncated
    collect2: error: ld returned 1 exit status
    make[2]: *** [modules/dnn/CMakeFiles/opencv_dnn.dir/build.make:1044: lib/libopencv_dnn.so.3.4.0] Error 1
    make[1]: *** [CMakeFiles/Makefile2:2384: modules/dnn/CMakeFiles/opencv_dnn.dir/all] Error 2
    make: *** [Makefile:163: all] Error 2


    你好 請問我MAKE 到一半 跑出這個 是甚麼問題呢? 麻煩了

    回覆刪除
    回覆
    1. 只有這裡顯示錯誤嗎? 大約是在幾%?
      這個資訊我看不太出來真正是哪裡出了問題呢 ..
      方便的話可以將多一點資訊傳到我的信箱 我可以看看

      刪除
    2. 大概在38%的時候

      刪除
    3. 只是我灌的是4.1.1的

      刪除
    4. 我個人是沒有遇過類似的情況呢 ... 加上我也很久沒有在pi上重新編譯opencv了
      我只能給你幾個建議
      1. 重新執行一次make (記得要把build資料夾刪掉, 或者也可以下指令 ~make clean)
      2. 重新確認一下版本 (opencv本身和contrib)

      給你參考看看

      刪除
    5. 好的 我再試試 謝謝

      刪除
    6. HI, 我用pi4並成功編譯了opencv 4.1.1
      將一些改進跟修正的部分打在文章裡面了

      刪除
  5. 你好我在下載
    git clone https://github.com/opencv/opencv.git

    git clone https://github.com/opencv/opencv_contrib.git
    這兩個的時候現錯誤
    (pi@Pi:~ $ git clone https://github.com/opencv/opencv.git
    Cloning into 'opencv'...
    fatal: unable to access 'https://github.com/opencv/opencv.git/': Failed to connect to github.com port 443: 找不到通往該主機的路由路徑
    pi@Pi:~ $ git clone https://github.com/opencv/opencv_contrib.git
    Cloning into 'opencv_contrib'...
    fatal: unable to access 'https://github.com/opencv/opencv_contrib.git/': Failed to connect to github.com port 443: 找不到通往該主機的路由路徑)
    請問要如何解決

    回覆刪除
    回覆
    1. Hi, 先祝你新年快樂!

      指令是沒問題的,你可能需要檢查一下Pi的網路是否正常。
      如果有proxy或之類的東西可能需要關掉。
      當然不排除你執行的時候github有狀況,不過這可能性應該很小很小。

      如果嫌用git clone麻煩你也可以用其他電腦抓好在上傳上Pi就是了。

      刪除
  6. 網誌管理員已經移除這則留言。

    回覆刪除
  7. 網誌管理員已經移除這則留言。

    回覆刪除
  8. 網誌管理員已經移除這則留言。

    回覆刪除

張貼留言

這個網誌中的熱門文章

[Windows 10] WSL 安裝流程,美化與心得(包含個人優缺點等..)

[MAC] Macbook pro 2011 Late 更換SSD