Yolo(3)(项目)Yolo v3 目标检测(85分类)
目錄
基礎理論
一、 讀取文件
二、神經網絡初始化
?1、搭建神經網絡
2、GPU加速
三、打開攝像頭、按幀讀取圖像
四、向神經網絡輸入
五、獲取神經網絡輸出
1、獲取各層名稱
2、獲取輸出層名稱
3、獲取輸出層圖像(內容)
六、框出物體
1、獲取所有預測框情況?
逐特征圖輸出
逐框輸出
單預測框結果
置信度過半時,把預測框認為可能的預測結果存入列表
2、保留一個預測框
3、畫出預測框
總代碼
基礎理論
圖像被劃分成3個圖像:
????????圖像在多次卷積壓縮后,小物體容易消失,所以我們分別用52*52、26*26、13*13的網格檢測小物體、中物體、大物體。
?(貓是大物體,所以用13*13的網格檢測)
輸出層output:
一、 讀取文件
?需要三個文件:
coco.names、yolov3.cfg、yolov3.weights。
?下載地址:?
https://download.csdn.net/download/great_yzl/34365174
(也可以去yolo官網下載,不過coco.names文件不知道有沒有)?
?yolov3.cfg、yolov3.weights都是官方給定的模型(已經設置訓練好的,直接拿來用即可)。
# 讀取文件
def ReadFile():global name_listname_list = []# 讀取文件with open('coco.names') as f:name_list = f.read().split('\n')print(name_list)
二、神經網絡初始化
?1、搭建神經網絡
根據yolov3官方的設置和權重
global networkmodel_configuration = 'yolov3.cfg' # 配置模型model_weights = 'yolov3.weights' # 權重# 1、創建神經網絡network = cv2.dnn.readNetFromDarknet(model_configuration, model_weights)# 配置模型 權重
2、GPU加速
# 2、GPU加速network.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV) # 設置opencv作為后端network.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)
三、打開攝像頭、按幀讀取圖像
def Capture_Init():global capture, w, hcapture = cv2.VideoCapture(0)w, h = 320, 320
while True:global imgsuccess, img = capture.read()# img = cv2.imread("Resource/test4.jpg")cv2.imshow('img', img)# 設置每幀間隔時間(q鍵退出)cv2.waitKey(1)# if cv2.waitKey(1) & 0XFF == ord("q"):# break
四、向神經網絡輸入
# 向神經網絡輸入Input_to_Network(img)
把img的數據變換一下,作為blob輸入到image中。?
# 向神經網絡輸入
def Input_to_Network(image):# 把image轉換成blob數據類型(歸一化等一系列數據類型轉換)(這種方式網絡可以理解)blob = cv2.dnn.blobFromImage(image, 1 / 255, (w, h), [0, 0, 0], 1, crop=False)# 圖像 歸一化 寬,高 裁剪結果# 設置神經網絡輸入network.setInput(blob)print(blob)
五、獲取神經網絡輸出
1、獲取各層名稱
# 神經網絡各層名稱layersNames = network.getLayerNames()print(layersNames)
2、獲取輸出層名稱
# 2、獲取神經網絡輸出層名稱outputNames = [(layersNames[i[0] - 1]) for i in network.getUnconnectedOutLayers()]print(outputNames)
3、獲取輸出層圖像(內容)
# 3、獲取輸出層圖像(內容)# outputs:3個特征圖:分別為小、中、大。(13*13、26*26、52*52)# 每個特征圖又輸出85個類別outputs = network.forward(outputNames)# print(outputs[0].shape)# print(outputs[1].shape)# print(outputs[2].shape)# print(outputs[0][0])return outputs
# 獲取神經網絡輸出
def Network_Output():# 神經網絡各層名稱layersNames = network.getLayerNames()# 神經網絡輸出層名稱outputNames = [(layersNames[i[0] - 1]) for i in network.getUnconnectedOutLayers()]# outputs:3個特征圖:分別為小、中、大。(13*13、26*26、52*52)# 每個特征圖又輸出85個類別outputs = network.forward(outputNames)# print(outputs[0].shape)# print(outputs[1].shape)# print(outputs[2].shape)# print(outputs[0][0])return outputs
得到圖中的一系列結果:
預測框坐標、長寬、置信度、各分類的預測分數。
[5.9418369e-02 7.4009120e-02 5.7651168e-01 1.6734526e-01 6.5560471e-07
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
?0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00]?
六、框出物體
# 框出物體
def GetObject(outputs, image):# 創建參數列表h_p, w_p, c_p = image.shape # 圖像的高、寬、通道數bboxes = [] # 預測框classIds = [] # 分類索引confidences = [] # 置信度
1、獲取所有預測框情況?
逐特征圖輸出
# 逐特征圖輸出for output in outputs:
逐框輸出
# 逐框輸出for one_class in output:
單預測框結果
# 算出每個框的預測情況# 先得到其85分類,每個分類的得分,再獲取最大得分的下標作為索引,最后得到其置信度scores = one_class[5:] # 獲取所有得分classId = np.argmax(scores) # 獲取分類索引confidence = scores[classId] # 獲取置信度
置信度過半時,把預測框認為可能的預測結果存入列表
# 加入預測到的物體(認為可能的物體)if confidence > 0.5:# 獲取預測框寬高、坐標w_b, h_b = int(one_class[2] * w_p), int(one_class[3] * h_p)x, y = int((one_class[0] * w_p) - w_b / 2), int((one_class[1] * h_p) - h_b / 2)# (中心點x、y坐標)bbox = [x, y, w_b, h_b]# 把參數加入列表(預測框參數、分類索引、置信度)bboxes.append(bbox) # 預測框參數classIds.append(classId) # 分類索引confidences.append(float(confidence)) # 置信度print(confidences)
2、保留一個預測框
????????根據置信度、NMS進行非極大值抑制。 (前面對置信度已經有過一次過濾,這次可以不再設置置信度閾值)。
# 保留一個預測框(從置信度閾值、NMS閾值進行設置)indices = cv2.dnn.NMSBoxes(bboxes, confidences, 0.5, 0.1)# 預測框 置信度 置信度閾值 NMS閾值(非極大值抑制)
3、畫出預測框
# 輸出預測框for i in indices:i = i[0]box = bboxes[i]x, y, w, h = box[0], box[1], box[2], box[3]# print(x,y,w,h)cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 255), 2)cv2.putText(image, f'{name_list[classIds[i]].upper()} {int(confidences[i] * 100)}%',(x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 0, 255), 2)cv2.imshow('image', image)
?
?
?預測最大的問題就是比較慢,用tiny的話足夠快,但是不準確,還有很大的提升空間。
總代碼
import cv2
import numpy as np# 讀取文件
def ReadFile():global name_listname_list = []# 讀取文件with open('yolo/coco.names') as f:name_list = f.read().split('\n')# print(name_list)# 搭建神經網絡
def Network_Init():global networkmodel_configuration = 'yolo/yolov3.cfg' # 配置模型model_weights = 'yolo/yolov3.weights' # 權重# 1、創建神經網絡network = cv2.dnn.readNetFromDarknet(model_configuration, model_weights)# 配置模型 權重# 2、GPU加速network.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV) # 設置opencv作為后端network.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)# print(network)# 打開攝像頭
def Capture_Init():global capture, w, hcapture = cv2.VideoCapture(0)w, h = 320, 320# 向神經網絡輸入
def Input_to_Network(image):# 把image轉換成blob數據類型(歸一化等一系列數據類型轉換)(這種方式網絡可以理解)blob = cv2.dnn.blobFromImage(image, 1 / 255, (w, h), [0, 0, 0], 1, crop=False)# 圖像 歸一化 寬,高 裁剪結果# 設置神經網絡輸入network.setInput(blob)# print(blob)# 獲取神經網絡輸出
def Network_Output():# 1、獲取神經網絡各層名稱layersNames = network.getLayerNames()# 2、獲取神經網絡輸出層名稱outputNames = [(layersNames[i[0] - 1]) for i in network.getUnconnectedOutLayers()]# print(outputNames)# 3、獲取輸出層圖像(內容)# outputs:3個特征圖:分別為小、中、大。(13*13、26*26、52*52)# 每個特征圖又輸出85個類別outputs = network.forward(outputNames)# print(outputs[0].shape)# print(outputs[1].shape)# print(outputs[2].shape)# print(outputs[0][0])return outputs# 框出物體
def GetObject(outputs, image):# 創建參數列表h_p, w_p, c_p = image.shape # 圖像的高、寬、通道數bboxes = [] # 預測框classIds = [] # 分類索引confidences = [] # 置信度# 1、獲取所有預測框的情況# outputs:小、中、大三個特征圖# output:小、中、大單個特征圖# oneclass:小、中、大每個分類# 逐特征圖輸出for output in outputs:# 逐框輸出for one_class in output:# 算出每個框的預測結果# 先得到其85分類,每個分類的得分,再獲取最大得分的下標作為索引,最后得到其置信度scores = one_class[5:] # 獲取所有得分classId = np.argmax(scores) # 獲取分類索引confidence = scores[classId] # 獲取置信度# 加入預測到的物體(認為可能的物體)if confidence > 0.5:# 獲取預測框寬高、坐標w_b, h_b = int(one_class[2] * w_p), int(one_class[3] * h_p)x, y = int((one_class[0] * w_p) - w_b / 2), int((one_class[1] * h_p) - h_b / 2)# (中心點x、y坐標)bbox = [x, y, w_b, h_b]# 把參數加入列表(預測框參數、分類索引、置信度)bboxes.append(bbox) # 預測框參數classIds.append(classId) # 分類索引confidences.append(float(confidence)) # 置信度print(confidences)# 保留一個預測框(從置信度閾值、NMS閾值進行設置)indices = cv2.dnn.NMSBoxes(bboxes, confidences, 0.5, 0.1)# 預測框 置信度 置信度閾值 NMS閾值(非極大值抑制)# 輸出預測框for i in indices:i = i[0]box = bboxes[i]x, y, w, h = box[0], box[1], box[2], box[3]# print(x,y,w,h)cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 255), 2)cv2.putText(image, f'{name_list[classIds[i]].upper()} {int(confidences[i] * 100)}%',(x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 0, 255), 2)cv2.imshow('image', image)if __name__ == '__main__':ReadFile() #讀取文件Network_Init() #神經網絡初始化Capture_Init() #攝像頭初始化while True:global img# success, img = capture.read()img = cv2.imread("Resource/test4.jpg")# 向神經網絡輸入Input_to_Network(img)# 獲取神經網絡輸出outputs = Network_Output()# 框出物體GetObject(outputs, img)# 設置每幀間隔時間(q鍵退出)cv2.waitKey(1)# if cv2.waitKey(1) & 0XFF == ord("q"):# breakcv2.waitKey(0)
總結
以上是生活随笔為你收集整理的Yolo(3)(项目)Yolo v3 目标检测(85分类)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV 错误:无法打开摄像头(打开
- 下一篇: 深度学习 -- TensorFlow(9