深度学习和目标检测系列教程 15-300:在 Python 中使用 OpenCV 执行 YOLOv3 对象检测
@Author:Runsen
上次講了yolov3,這是使用yolov3的模型通過(guò)opencv的攝像頭來(lái)執(zhí)行YOLOv3 對(duì)象檢測(cè)。
導(dǎo)入所需模塊:
import cv2 import numpy as np import time讓我們定義一些我們需要的變量和參數(shù):
CONFIDENCE = 0.5 SCORE_THRESHOLD = 0.5 IOU_THRESHOLD = 0.5# network configuration config_path = "cfg/yolov3.cfg" # YOLO net weights weights_path = "weights/yolov3.weights" # coco class labels (objects) labels = open("data/coco.names").read().strip().split("\n") # 每一個(gè)對(duì)象的檢測(cè)框的顏色 colors = np.random.randint(0, 255, size=(len(LABELS), 3), dtype="uint8")config_path和weights_path 分別代表yolov3模型配置 和對(duì)應(yīng)的預(yù)訓(xùn)練模型權(quán)重。
- yolov3.cfg下載:https://github.com/pjreddie/darknet/blob/master/cfg/yolov3.cfg
- coco.names下載:https://github.com/pjreddie/darknet/blob/master/data/coco.names
- yolov3.weights下載:https://pjreddie.com/media/files/yolov3.weights
labels是檢測(cè)的不同對(duì)象的所有類標(biāo)簽的列表,生成隨機(jī)顏色
 是因?yàn)橛泻芏囝惖拇嬖凇?/p> 
下面的代碼加載模型:
net = cv2.dnn.readNetFromDarknet(config_path, weights_path)先加載一個(gè)示例圖像:
path_name = "test.jpg" image = cv2.imread(path_name) file_name = os.path.basename(path_name) filename, ext = file_name.split(".") h, w = image.shape[:2]接下來(lái),需要對(duì)這個(gè)圖像進(jìn)行歸一化、縮放和整形,使其適合作為神經(jīng)網(wǎng)絡(luò)的輸入:
# create 4D blob blob = cv2.dnn.blobFromImage(image, 1/255.0, (416, 416), swapRB=True, crop=False)這會(huì)將像素值標(biāo)準(zhǔn)化為從0到1 的范圍,將圖像大小調(diào)整為(416, 416)并對(duì)其進(jìn)行縮放
print("image.shape:", image.shape) print("blob.shape:", blob.shape)image.shape: (1200, 1800, 3) blob.shape: (1, 3, 416, 416)現(xiàn)在讓我們將此圖像輸入神經(jīng)網(wǎng)絡(luò)以獲得輸出預(yù)測(cè):
# 將blob設(shè)置為網(wǎng)絡(luò)的輸入 net.setInput(blob) # 獲取所有圖層名稱 ln = net.getLayerNames() ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()] #得到網(wǎng)絡(luò)輸出 #測(cè)量一下時(shí)間花費(fèi) start = time.perf_counter() layer_outputs = net.forward(ln) time_took = time.perf_counter() - start print(f"Time took: {time_took:.2f}s")boxes, confidences, class_ids = [], [], []# 在每個(gè)層輸出上循環(huán) for output in layer_outputs:# 在每一個(gè)物體上循環(huán)''' detection.shape等于85,前4 個(gè)值代表物體的位置,(x, y)坐標(biāo)為中心點(diǎn)和邊界框的寬度和高度,其余數(shù)字對(duì)應(yīng)物體標(biāo)簽,因?yàn)檫@是COCO 數(shù)據(jù)集,它有80類標(biāo)簽。例如,如果檢測(cè)到的對(duì)象是人,則80長(zhǎng)度向量中的第一個(gè)值應(yīng)為1,其余所有值應(yīng)為0,自行車的第二個(gè)數(shù)字,汽車的第三個(gè)數(shù)字,一直到第 80 個(gè)對(duì)象。然后使用np.argmax() 函數(shù)來(lái)獲取類 id 的原因,因?yàn)樗祷?0長(zhǎng)度向量中最大值的索引。 ''' for detection in output:# 提取類id(標(biāo)簽)和置信度(作為概率)# 當(dāng)前目標(biāo)檢測(cè)scores = detection[5:]class_id = np.argmax(scores)confidence = scores[class_id]if confidence > CONFIDENCE:# 將邊界框坐標(biāo)相對(duì)于# 圖像的大小,記住YOLO實(shí)際上# 返回邊界的中心(x,y)坐標(biāo)# 框,然后是框的寬度和高度box = detection[:4] * np.array([w, h, w, h])(centerX, centerY, width, height) = box.astype("int")# 使用中心(x,y)坐標(biāo)導(dǎo)出x和y# 和邊界框的左角x = int(centerX - (width / 2))y = int(centerY - (height / 2))# 更新邊界框坐標(biāo),信任度,和類IDboxes.append([x, y, int(width), int(height)])confidences.append(float(confidence))class_ids.append(class_id) #根據(jù)前面定義的分?jǐn)?shù)執(zhí)行非最大值抑制 idxs = cv2.dnn.NMSBoxes(boxes, confidences, SCORE_THRESHOLD, IOU_THRESHOLD) font_scale = 1 thickness = 1 # 確保至少存在一個(gè)檢測(cè) if len(idxs) > 0:# 循環(huán)查看我們保存的索引for i in idxs.flatten():# 提取邊界框坐標(biāo)x, y = boxes[i][0], boxes[i][1]w, h = boxes[i][2], boxes[i][3]# 在圖像上繪制邊框矩形和標(biāo)簽color = [int(c) for c in colors[class_ids[i]]]cv2.rectangle(image, (x, y), (x + w, y + h), color=color, thickness=thickness)text = f"{labels[class_ids[i]]}: {confidences[i]:.2f}"# 計(jì)算文本寬度和高度以繪制透明框作為文本背景(text_width, text_height) = cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX, fontScale=font_scale, thickness=thickness)[0]text_offset_x = xtext_offset_y = y - 5box_coords = ((text_offset_x, text_offset_y), (text_offset_x + text_width + 2, text_offset_y - text_height))overlay = image.copy()cv2.rectangle(overlay, box_coords[0], box_coords[1], color=color, thickness=cv2.FILLED)#添加(長(zhǎng)方體的透明度)image = cv2.addWeighted(overlay, 0.6, image, 0.4, 0)cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX,fontScale=font_scale, color=(0, 0, 0), thickness=thickness)cv2.imwrite(filename + "_yolo3." + ext, image)
 一張圖片的時(shí)間需要1.3秒。
下面結(jié)合opencv讀取攝像頭的功能,實(shí)現(xiàn)攝像頭的拍攝畫面的識(shí)別
import cv2 import numpy as np import time CONFIDENCE = 0.5 SCORE_THRESHOLD = 0.5 IOU_THRESHOLD = 0.5 config_path = "cfg/yolov3.cfg" weights_path = "weights/yolov3.weights" font_scale = 1 thickness = 1 LABELS = open("data/coco.names").read().strip().split("\n") COLORS = np.random.randint(0, 255, size=(len(LABELS), 3), dtype="uint8") net = cv2.dnn.readNetFromDarknet(config_path, weights_path) ln = net.getLayerNames() ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()] cap = cv2.VideoCapture(0) while True:_, image = cap.read()h, w = image.shape[:2]blob = cv2.dnn.blobFromImage(image, 1/255.0, (416, 416), swapRB=True, crop=False)net.setInput(blob)start = time.perf_counter()layer_outputs = net.forward(ln)time_took = time.perf_counter() - startprint("Time took:", time_took)boxes, confidences, class_ids = [], [], []for output in layer_outputs:for detection in output:scores = detection[5:]class_id = np.argmax(scores)confidence = scores[class_id]if confidence > CONFIDENCE:box = detection[:4] * np.array([w, h, w, h])(centerX, centerY, width, height) = box.astype("int")x = int(centerX - (width / 2))y = int(centerY - (height / 2))boxes.append([x, y, int(width), int(height)])confidences.append(float(confidence))class_ids.append(class_id)idxs = cv2.dnn.NMSBoxes(boxes, confidences, SCORE_THRESHOLD, IOU_THRESHOLD)font_scale = 1thickness = 1if len(idxs) > 0:for i in idxs.flatten():x, y = boxes[i][0], boxes[i][1]w, h = boxes[i][2], boxes[i][3]color = [int(c) for c in COLORS[class_ids[i]]]cv2.rectangle(image, (x, y), (x + w, y + h), color=color, thickness=thickness)text = f"{LABELS[class_ids[i]]}: {confidences[i]:.2f}"(text_width, text_height) = cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX, fontScale=font_scale, thickness=thickness)[0]text_offset_x = xtext_offset_y = y - 5box_coords = ((text_offset_x, text_offset_y), (text_offset_x + text_width + 2, text_offset_y - text_height))overlay = image.copy()cv2.rectangle(overlay, box_coords[0], box_coords[1], color=color, thickness=cv2.FILLED)image = cv2.addWeighted(overlay, 0.6, image, 0.4, 0)cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX,fontScale=font_scale, color=(0, 0, 0), thickness=thickness)cv2.imshow("image", image)if ord("q") == cv2.waitKey(1):breakcap.release() cv2.destroyAllWindows() 與50位技術(shù)專家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的深度学习和目标检测系列教程 15-300:在 Python 中使用 OpenCV 执行 YOLOv3 对象检测的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: win10笔记本电脑蓝屏怎么解决办法 w
- 下一篇: u盘插上电脑怎么没有反应了 电脑无法识别
