經過一段時間的瞎搞,總算把一個檢測人體2D關鍵點的模型能夠在HI3516DV300上生成結果,獲取開發板上輸出的blob hex數據通過python+opencv解析在PC上看,效果還是有差距的:
不過沒有關係,事情總得一步步來。以前我就是太着急,總期望在短時間內獲得一定的結果,最後獲得的多半是不好的結果和自我懷疑。質量互變,否定之否定,螺旋上升,實踐總結再實踐直到達到目的,這是規律。
關於人體關鍵點的檢測若是能在海思平臺實現以及優化再做一系列博客。
需要使用openCV是到了一個比較麻煩的時刻:從NNIE輸出的數據是HI_S32轉成浮點型的一張張46*46置信圖數據,爲了找到人體關鍵點的座標位置,需要對置信圖進行高斯濾波,邊沿查找等運算獲取結果。對應python代碼是:
當然海思平臺運行的是C/C++程序,python也不是那麼適合嵌入式平臺。
爲了實現從海思NNIE輸出中結算出人體關鍵點在圖象內座標位置,按照我目前的理解,應該是有兩種路徑:移植openCV或者通過海思的IVE(Intelligent Video Engine)計算。
(或許對於單個人體的檢測直接使用NMS非極大值抑制也行,而海思SVP的sample裏面有整個函數,不過僅適用單個目標)
先移植openCV試試。
我使用的是ubuntu16.04虛擬機環境。
openCV獲取:
安裝wget:apt-get install wget
wget -O opencv-3.4.3.zip https://github.com/Itseez/opencv/archive/3.4.3.zip
wget -O opencv_contrib-3.4.3.zip https://github.com/Itseez/opencv_contrib/archive/3.4.3.zip
解壓openCV以及openCV_contrib到同級目錄:
unzip opencv-3.4.1.zip
unzip opencv_contrib-3.4.1.zip
HISI交叉編譯器安裝:
參考《Hi3516CV500╱Hi3516DV300╱Hi3516AV300 開發環境用戶指南.pdf》即可
cmake安裝:
apt-get install cmake cmake-gui
openCV交叉編譯:相關資料網上一大堆,可以參考這幾個博客:
https://www.cnblogs.com/huty/p/8518227.html
https://blog.csdn.net/avideointerfaces/article/details/89477828
這裏會在opencv-3.4.3的目錄下新建兩個目錄:build output
注意最好把opencv-3.4.3整個路徑的權限都 chmod 777,另外最好在cmake把build_OPENCV_WORLD也選上
make
那麼問題來了,編譯期間會出一些錯誤,雖然不一定每個人都會遇到,這裏記錄下我遇到的:
<0> 錯誤信息:先參照以上的兩篇博客
<1> 錯誤信息:找不到zlib.h
解決方法:在opencv-3.4.3路徑下找到CMakeLists.txt內的ocv_include_directories(),改爲./3rdparty/zlib/
<2> 錯誤信息:
Scanning dependencies of target opencv_core
[ 37%] Building CXX object modules/core/CMakeFiles/opencv_core.dir/src/lapack.cpp.obj
In file included from /home/samba2/opencv-3.4.3/modules/core/src/lapack.cpp:43:0:
/home/samba2/opencv-3.4.3/modules/core/src/precomp.hpp:46:38: fatal error: opencv2/opencv_modules.hpp: No such file or directory “#include "opencv2/opencv_modules.hpp"
解決方法:
具體原因也沒有探究,我編譯期間出現各種少了頭/源文件的錯誤。解決辦法就是找到這些文件然後拷貝到缺少文件的路徑。這些缺少的文件基本都在build目錄下,報錯就找到並且拷進去吧。
例如上面這個錯誤,就通過:cd build ;cp -rf ./opencv2/ /home/samba2/opencv-3.4.3/modules/core/src/; 解決
需要注意的是,如果缺少的是#include<opencv2/xxx.h>這樣的文件,一般是把build下的opencv2整個目錄拷貝到缺少該文件路徑的上一級的include文件下;如果這個include文件下已經存在opencv2目錄,那就只拷貝opencv2下的文件即可,以免直接覆蓋了
如果缺少的是#include "xxxxx.h"這樣的文件,那直接拷貝到缺少該文件的源碼路徑就行了,這都很好理解的
一般情況下按照以上方法就能過編譯,當然每個人環境不一樣可能遇到不一樣的問題,應該需要各自解決。
通過編譯後,make install,output目錄下就會有include lib文件夾,全部拷貝到海思開發板備用。
接下來需要驗證一下移植的庫是否可用:
<1>
將opencv-3.4.3/output下的include lib文件拷貝到交叉編譯器的路徑下,我的路徑是:
/opt/hisi-linux/x86-arm/arm-himix200-linux/arm-linux-gnueabi/
將/opecv-3.4-3/output下include目錄下的opencv & opencv2文件夾拷貝到arm-linux-gnueabi/include下
將/opecv-3.4-3/output下lib目錄內所有文件拷貝到arm-linux-gnueabi/lib下
<2>
隨便找一段opencv的代碼demo.cpp:
#include <opencv2/opencv.hpp>
using namespace cv;
extern "C" {
int main(int argc, char *argv[]){
Mat img = imread("./demo.jpg");
Mat gray;
if(img.empty()){
printf("read img err...\n");
return -1;
}
cvtColor(img, gray, COLOR_BGR2GRAY);
imwrite("demo_gray.jpg", gray);
return 0;
}
}
通過命令編譯:
arm-himix200-linux-g++ demo.cpp -I/opt/hisi-linux/x86-arm/arm-himix200-linux/include/ -lopencv_highgui -lopencv_core -lopencv_imgproc -lpthread -lrt -lopencv_objdetect -o demo
如果編譯了opencv_world,則用以下命令編譯:
arm-himix200-linux-g++ demo.cpp -I/opt/hisi-linux/x86-arm/arm-himix200-linux/include/ -lopencv_world -lpthread -lrt -ldl -o demo
編譯出的demo可執行文件與demo.jpg拷貝到開發板執行,生成灰度圖對比原圖:
至此,可以認爲openCV初步移植成功。
openCV移植初步成功後,下一步就是如何將openCV的代碼與海思SVP的代碼融合並且成功編譯運行,由於摻雜了C/C++編程,因此需要花些時間來解決。
這裏要參考和感謝其它博客的大神:
海思AI芯片(Hi3519A/3559A)方案學習(十八)如何將sample sdk代碼重構並編譯成動態鏈接庫:
https://blog.csdn.net/avideointerfaces/article/details/96141090
海思AI芯片(Hi3519A/3559A)方案學習(十九)如何在推理動態鏈接庫中引入opencv庫:
https://blog.csdn.net/avideointerfaces/article/details/97012873
我將參照這些大神的思路來實現自己的人體關鍵點檢測功能