目錄
1.opencv的安裝
之前感覺太麻煩放棄了,檢測圖片直接保存,沒用到。現在想檢測視頻,是避不開了,弄了我一天才安裝好,之前一直make失敗,後來發現opencv4.1.1不可用,又換3.4.2心累,結果配置好了,環境變量不生效,重啓了傻逼電腦進不去系統,一直紫屏,嗚嗚,最後大神都放棄,幫我拯救了,重啓了一下好了,不過進入系統會閃屏,而且垃圾箱不可用,不過能進就好,嗚嗚。
建議使用cmake-gui編譯,容易發現問題。
1)去官網下載opencv
在本教程中選用的時opencv3.4.2,其他版本的配置方法其實差不多。
下載鏈接http://opencv.org/releases.html,選擇sources版本
2)解壓下載下來的zip包
unzip opencv-3.4.2.zip
3)安裝必須庫和cmake-gui
sudo apt-get install cmake-gui
sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg.dev libtiff4.dev libswscale-dev libjasper-dev
庫不全的話,後期cmake有問題再補
4)cmake-gui編譯
進入到解壓後的文件包中,在解壓的文件夾裏新建一個文件夾build用來編譯OpenCV
中間cmake編譯過程,參考博客https://blog.csdn.net/jindunwan7388/article/details/80397700和
https://blog.csdn.net/u011897411/article/details/89743448
中間解決ippicv下載問題,離線下載
# 打開終端,輸入
gedit ~/DownLoad/opencv_source/opencv/3rdparty/ippicv/ippicv.cmake
# 將47行的
"https://raw.githubusercontent.com/opencv/opencv_3rdparty/${IPPICV_COMMIT}ippicv/"
# 改爲手動下載的文件的本地路徑(也就是將網絡下載的模式改爲本地文件下載的模式):
"file:///path" #(根據文件路徑填寫,注意是///)
5)make和make install
我就是make卡住了
make -j8
出現的錯誤:
/usr/bin/ld: warning: libiconv.so.2, needed by //home/smiles/anaconda2/lib/libgobject-2.0.so.0, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libpcre.so.1, needed by //home/smiles/anaconda2/lib/libgobject-2.0.so.0, not found (try using -rpath or -rpath-link)
//home/smiles/anaconda2/lib/libglib-2.0.so.0:對‘libiconv_open’未定義的引用
//home/smiles/anaconda2/lib/libglib-2.0.so.0:對‘libiconv_close’未定義的引用
//home/smiles/anaconda2/lib/libglib-2.0.so.0:對‘libiconv’未定義的引用
解決:參照博客https://blog.csdn.net/tsq292978891/article/details/78854188
把cmake編譯中的python3改爲anaconda下面,並把python的包的路徑,都改成了anaconda3下面的路徑。
make install
6)路徑設置
參考對應版本(3或4)博客https://blog.csdn.net/jindunwan7388/article/details/80397700和
https://blog.csdn.net/u011897411/article/details/89743448
7)測試一下:
# 命令行輸入以下命令
pkg-config --modversion opencv
2.yolov3源碼更改與排錯
Error1:cv_window_normal未定義
終於知道這些錯誤原因了,是根據博客https://blog.csdn.net/babyzbb636/article/details/100534359更改,版本不同,把對應部分改成源碼對應或者對應下面排錯。
差點因爲這個原因就放棄了,各種百度找不到,找到的也不適用,還懷疑opencv環境各種。
最後想起來看源碼,看哪裏錯誤,發現,它好像不識別的是這幾個定義; 查了一下這個函數的用法,想到了可能是版本差異:改成如下就好了,記住一共兩處修改
Error2:showimage參數不足
showimage源碼參數是兩個,這個也是opencv版本不同,改成三個,第三參數爲0, 把cvSetwindowproperty註釋了,有需要的網友可以根據版本更改
Make -j8 success天呀
3.測試視頻與保存
1)官方命令:
./darknet detector demo cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_10000.weights test_video/video/video001.avi
其中只能顯示最後的結果無法保存,或者使用
./darknet detector demo cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_10000.weights test_video/video/video001.avi -prefix test_video/result/video001.mp4
最後是逐幀保存,也不太好,所以這裏修改下源碼:
1.在src/image.c裏面修改show_image函數
int show_image(image p, const char *name, int ms)
{
#ifdef OPENCV
// int c = show_image_cv(p, name, ms);
// 增加保存結果視頻
int c = save_video(p, name, ms);
return c;
#else
fprintf(stderr, "Not compiled with OpenCV, saving to %s.png instead\n", name);
save_image(p, name);
return -1;
#endif
}
2.在src/image_opencv.cpp裏面增加一個save_video函數
int save_video(image im, const char*name, int ms)
{
// 靜態數據成員,第一次調用初始化,之後調用不會在初始化
static VideoWriter* video;
Mat m = image_to_mat(im);
// imshow(name, m);
{
// 空視頻對象則初始化一個對象
if(video == NULL){
const char* output_name = "test_video/result/video001.mp4"; //修改輸出路徑
// 新建視頻保存對象
video = new VideoWriter(output_name, VideoWriter::fourcc('M','J','P','G'), 50, Size(im.w,im.h));
printf("\n DST output_video = %s \n", output_name);
}
// 寫入每一幀的處理結果
video->write(m);
printf("\n cvWriteFrame \n");
}
int c = waitKey(ms);
if (c != -1) c = c%256;
return c;
}
2)python爲接口
參考文獻:
https://blog.csdn.net/orDream/article/details/84311697
https://blog.csdn.net/dragongiri/article/details/90647089
https://blog.csdn.net/OliverkingLi/article/details/93487281
其中我把image.c和image.h的條件編譯去掉了,否則老報libdarknet.so: undefined symbol: ndarray_to_image,可能我插入代碼位置不對。終於實現了視頻檢測。
之前保存視頻老打不開,在darknet.py的main中,貼出我修改後的代碼(前面參照我貼出來的博客修改):
if __name__ == "__main__":
net = load_net("/home/zbb/darknet/cfg/yolov3-voc.cfg".encode('utf-8'), "/home/zbb/darknet/backup/yolov3-voc_10000.weights".encode('utf-8'), 0)
meta = load_meta("/home/zbb/darknet/cfg/voc.data".encode('utf-8'))
in_path='/home/zbb/darknet/test_video/plane.MP4'
#out_path='/home/zbb/darknet/test_video/result/test.avi'
vid = cv2.VideoCapture(in_path)
total_frames = vid.get(cv2.CAP_PROP_FRAME_COUNT)
fps = vid.get(cv2.CAP_PROP_FPS)
frame_size = (int(vid.get(cv2.CAP_PROP_FRAME_WIDTH)), int(vid.get(cv2.CAP_PROP_FRAME_HEIGHT)))
fourcc = cv2.VideoWriter_fourcc(*"mp4v") #avi格式:*'XVID' mp4格式: *"mp4v"
out_path = in_path.split(".")[0] + "-result.mp4"
videoWriter = cv2.VideoWriter(out_path, fourcc, fps, frame_size)
#videoWriter = cv2.VideoWriter('/home/zbb/darknet/test_video/result/test.avi', fourcc, 25, (720,404)) #改成自己的framesize或者用上面的寫入
while True:
return_value,arr=vid.read()
if not return_value:
break
im=nparray_to_image(arr)
boxes= detect(net, meta, im)
for i in range(len(boxes)):
score=boxes[i][1]
label=boxes[i][0]
xmin=boxes[i][2][0]-boxes[i][2][2]/2
ymin=boxes[i][2][1]-boxes[i][2][3]/2
xmax=boxes[i][2][0]+boxes[i][2][2]/2
ymax=boxes[i][2][1]+boxes[i][2][3]/2
print(label)
cv2.rectangle(arr,(int(xmin),int(ymin)),(int(xmax),int(ymax)),(0,255,0),2)
cv2.putText(arr,str(label),(int(xmin),int(ymin)),fontFace=cv2.FONT_HERSHEY_SIMPLEX,fontScale=0.8,color=(0,255,255),thickness=2)
cv2.imshow("Canvas", arr)
videoWriter.write(arr)
cv2.waitKey(1)
cv2.destroyAllWindows()
現在存在問題是標籤不對,有b’,看了detect也沒有問題,簡單去掉'