解決yolov3中darknet.py預測位置不準和使用python3執行報錯的問題
阿新 • • 發佈:2018-12-16
本文總結了使用yolo過程中出現的一些問題,在網路上找到了相關的解決方案。
1 使用darknet.py預測位置不準
1.1 使用python呼叫darknet
一般來說,模型訓練好了,也可以使用shell命令進行預測了,下一步該在業務裡面使用別的語言來呼叫了,我們這裡使用python來呼叫yolo模型。
為了提高識別效率,當然不能直接在python裡面來呼叫shell,這樣的話每次呼叫都會重新載入一次模型,你想想有多慢?
darknet官方專案提供了python呼叫yolo模型的示例,也就是使用python與C互動,載入模型後就可以進行預測了,最後返回預測的座標(其實返回的是中心點座標和box的高寬)。
我們直接看到最後的程式碼部分:
if __name__ == "__main__": #net = load_net("cfg/densenet201.cfg", "/home/pjreddie/trained/densenet201.weights", 0) #im = load_image("data/wolf.jpg", 0, 0) #meta = load_meta("cfg/imagenet1k.data") #r = classify(net, meta, im) #print r[:10] net = load_net("cfg/tiny-yolo.cfg", "tiny-yolo.weights", 0) meta = load_meta("cfg/coco.data") r = detect(net, meta, "data/dog.jpg") print r
我們只需要在load_net,load_meta裡面填上相關引數,最後呼叫detect方法就可以進行識別了。
當然,我們可以在一個web專案中,提前把load_net,load_meta載入好,最後每次呼叫api的時候,執行detect方法就可以了。
1.2 darknet.py的結果不準
上面也提到了,python呼叫模型後返回的結果是並不是預測的box四個點的座標,而是中心點座標和box的高寬。
從detect函式裡面的這一段程式碼可以看出來(b.x, b.y, b.w, b.h)
:
res = [] for j in range(num): for i in range(meta.classes): if dets[j].prob[i] > 0: b = dets[j].bbox res.append((meta.names[i], dets[j].prob[i], (b.x, b.y, b.w, b.h)))
得到中心點座標和box高寬後,經過簡單的計算,就可以得到四個角點的座標了
# 結果r是四個元素的陣列 (中心點x,中心點y,寬,高)
x, y, w, h = r
a = x - (h/2)
c = x + (h/2)
b = y - (w/2)
d = y + (w/2)
2 使用python3執行darknet.py
你可能發現了,darknet.py用python3執行會報錯ctypes.ArgumentError
。
Traceback (most recent call last):
File "python/darknet.py", line 151, in <module>
net = load_net("cfg/tiny-yolo.cfg", "tiny-yolo.weights", 0)
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type
解決方案如下:把配置相關的引數使用bytes型別傳入,而不是string
net = load_net("cfg/tiny-yolo.cfg".encode('utf-8'), "tiny-yolo.weights".encode('utf-8'), 0)
meta = load_meta("cfg/coco.data".encode('utf-8'))
r = detect(net, meta, "data/dog.jpg".encode('utf-8'))
現在就可以使用python3執行了~
更多
實現載入模型、座標預測工作後,接下來是標記圖片、切割圖片、預測分類和介面開發等工作。後續有空會把demo貼上來。