今天來說一說和寫一寫 YOLOv1例驹,YOLOv1 在目標(biāo)檢測中應(yīng)該算獨(dú)樹一幟,有點類似今天 web 前端 vue 地位留夜。
首先 YOLOv1 將目標(biāo)檢測問題成功轉(zhuǎn)換為回歸(regression)的問題么介。其實 YOLOv1 屬于 one-stage 目標(biāo)檢測鹃答,這也就是為什么 YOLOv1。
通常我們知道神經(jīng)網(wǎng)絡(luò)都是設(shè)計函數(shù)李滴,輸入數(shù)據(jù)函數(shù)就給我們想要了解輸出螃宙。在 YOLOv1 是輸入一張圖片,輸出是一個結(jié)構(gòu)化數(shù)據(jù)悬嗓,其中包含圖片中出現(xiàn)那些目標(biāo)以及目標(biāo)的位置信息污呼。
import cv2
import numpy as np
net = cv2.dnn.readNet('yolov3.weights','yolov3.cfg')
可以在 dartnet 下載提供訓(xùn)練好的模型 yolov3.weights 和 yolov3.cfg
classes = []
with open("coco.names","r") as f:
classes =[line.strip() for line in f.readlines()]
print(classes)
coco.names 是分類文件名稱文件,我們可以通過打印輸出 cooc.names 名稱來了解通過模型我們能夠識別出的物體種類包竹。
['person', 'bicycle', 'car', 'motorbike', 'aeroplane', 'bus', 'train', 'truck', 'boat',
layers_names = net.getLayerNames()
output_layers = [layers_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
blob = cv2.dnn.blobFromImage(img,0.00392,(416,416),(0,0,0),True,crop=False)
for b in blob:
for n, img_blob in enumerate(b):
cv2.imshow(str(n),img_blob)
將通過 blobFromImage 讀取圖片作為神經(jīng)網(wǎng)絡(luò)的輸入燕酷,
def blobFromImage(image, scalefactor, size, mean, swapRB, crop, ddepth)
- 讀取的圖片
- 對圖片值會乘以該指定數(shù)據(jù) 0.00392
- 輸出圖片的大小,也就是寬高
- 從通道中減去平均值的平均標(biāo)量周瞎。
- swapRB 表示是否交互第一個或最后一個通道
- ddepth 表示輸出帶有景深通道苗缩,讀取圖片需要選擇 CV_32F 或者 CV_8U
- crop: true 表示對比圖片進(jìn)行裁剪,false 表示是否裁剪和保持原有寬高比
- 返回值為一個 4 維矩陣(NCHW)
returns 4-dimensional Mat with NCHW dimensions order.
net.setInput(blob)
outs = net.forward(output_layers)
將 blob 作為神經(jīng)網(wǎng)絡(luò)的輸入声诸,然后 outs 接收向前傳播作為輸出
# print(outs)
# showing informations on the screen
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5:
# objecte detected
center_x = int(detection[0] * width)
center_y = int(detection[1] * height)
w = int(detection[2] * width)
h = int(detection[3] * height)
net.setInput(blob)
outs = net.forward(output_layers)
print(outs)
從輸出結(jié)果來看酱讶,輸出 outs 是一個 list 前 4 位值分別為識別出物體中心坐標(biāo) x 和y 以及識別物體的大小也就是 w 和 h,不過這些都是比例值需要換算彼乌。
然后從第 5 開始就是檢測物體對應(yīng)每一個分類概率泻肯,我們可以通過 np.argmax 取最大也就是檢測物體最??可能類的概率值渊迁。從而得到該物體是什么物體。
cv2.circle(img,(center_x,center_y),10,(0,255,0),2)
接下來做的事就是把這些物體在圖片中表示出來灶挟。
boxes.append([x,y,w,h])
confidences.append(float(confidence))
class_ids.append(class_id)
print(len(boxes))
7
number_objects_detected = len(boxes)
for i in range(len(boxes)):
x, y, w, h = boxes[i]
label = classes[class_ids[i]]
print(label)
chair
oven
chair
chair
orange
orange
orange
font = cv2.FONT_HERSHEY_SIMPLEX
number_objects_detected = len(boxes)
for i in range(len(boxes)):
x, y, w, h = boxes[i]
label = str(classes[class_ids[i]])
cv2.rectangle(img,(x,y),(x + w, y + h),(0,255,0),2)
cv2.putText(img,label,(x,y + 30), font, 1, (255,255,252),2)
print(label)