<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
opencv呼叫yolov3模型進行深度學習目標檢測,以範例進行程式碼詳解
對於yolo v3已經訓練好的模型,opencv提供了載入相關檔案,進行圖片檢測的類dnn。 下面對怎麼通過opencv呼叫yolov3模型進行目標檢測方法進行詳解,付原始碼
在訓練結果backup資料夾下,找到模型權重檔案,拷到win的工程資料夾下 在cfg資料夾下,找到模型組態檔,yolov3-voc.cfg拷到win的工程資料夾下 在data資料夾下,找到voc.names,類別標籤檔案,拷到win的工程資料夾下
weightsPath='E:deep_learnyolov3_modeFileyolov3-voc_25000.weights'# 模型權重檔案 configPath="E:deep_learnyolov3_modeFileyolov3-voc.cfg"# 模型組態檔 labelsPath = "E:\deep_learn\yolov3_modeFile\voc.names"# 模型類別標籤檔案
引入模型的相關檔案,這裡需要使用yolo v3訓練模型的三個檔案
(1)模型權重檔案 name.weights
(2)訓練模型時的組態檔 yolov3-voc.cfg(一定和訓練時一致,後面會提原因)
(3)模型類別的標籤檔案 voc.names
LABELS = open(labelsPath).read().strip().split("n")
從voc.names中得到標籤的陣列LABELS 我的模型識別的是車和人 voc,names檔案內容
LABELS陣列內容
COLORS = np.random.randint(0, 255, size=(len(LABELS), 3),dtype="uint8")#顏色 隨機生成顏色框
根據類別個數隨機生成幾個顏色 ,用來後期畫矩形框 [[ 33 124 191] [211 63 59]]
boxes = [] confidences = [] classIDs = []
宣告三個陣列 (1)boxes 存放矩形框資訊 (2)confidences 存放框的置信度 (3)classIDs 存放框的類別標籤 三個陣列元素一一對應,即boxes[0]、confidences[0]、classIDs[0]對應一個識別目標的資訊,後期根據該資訊在圖片中畫出識別目標的矩形框
net = cv2.dnn.readNetFromDarknet(configPath,weightsPath)
載入 網路設定與訓練的權重檔案 構建網路 注意此處opencv2.7不行 ,沒有dnn這個類,最好opencv版本在4.0以上,對應python用3.0以上版本
image = cv2.imread('E:deep_learnyolov3_detection_imageR1_WH_ZW_40_80_288.jpg') (H,W) = image.shape[0:2]
讀入待檢測的圖片,得到影象的高和寬
ln = net.getLayerNames()
得到 YOLO各層的名稱,之後從各層名稱中找到輸出層
可以看到yolo的各層非常多,紅框圈的'yolo_94'、'yolo_106'即為輸出層,下面就需要通過程式碼找到這三個輸出層,為什麼是三個?跟yolo的框架結構有關,yolo有三個輸出。對應的我們在訓練模型時修改 yolov3-voc.cfg檔案,修改的filters、classes也是三處,詳細參考darknet YOLOv3資料集訓練預測8. 修改./darknet/cfg/yolov3-voc.cfg檔案
下面就是在yolo的所有層名稱ln中找出三個輸出層,程式碼如下
out = net.getUnconnectedOutLayers()#得到未連線層得序號 x = [] for i in out: # i=[200] x.append(ln[i[0]-1]) # i[0]-1 取out中的數位 [200][0]=200 ln(199)= 'yolo_82' ln=x
yolo的輸出層是未連線層的前一個元素,通過net.getUnconnectedOutLayers()找到未連線層的序號out= [[200] /n [267] /n [400] ],迴圈找到所有的輸出層,賦值給ln 最終ln = ['yolo_82', 'yolo_94', 'yolo_106'] 接下來就是將影象轉化為輸入的標準格式
blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416),swapRB=True, crop=False)
用需要檢測的原始影象image構造一個blob影象,對原影象進行畫素歸一化1 / 255.0,縮放尺寸 (416, 416),,對應訓練模型時cfg的檔案 交換了R與G通道
交換R與G通道通道是opencv在開啟圖片時交換了一次,此處交換即又換回來了 此時blob.shape=(1, 3, 416, 416),四維。 可以用numpy裡的squeeze()函數把秩為1的維度去掉,然後顯示圖片出來看看
image_blob = np.squeeze(blob) cv2.namedWindow('image_blob', cv2.WINDOW_NORMAL) cv2.imshow('image_blob',np.transpose(image_blob,[1,2,0])) cv2.waitKey(0)
net.setInput(blob) #將blob設為輸入 layerOutputs = net.forward(ln) #ln此時為輸出層名稱 ,向前傳播 得到檢測結果
將blob設為輸入 ln此時為輸出層名稱 ,向前傳播 得到檢測結果。 此時layerOutputs即三個輸出的檢測結果,
layerOutputs是一個含有三個矩陣的列表變數,三個矩陣對應三個層的檢測結果,其中一層的檢測結果矩陣如下圖
是個507*7的矩陣,這個矩陣代表著檢測結果,其中507就是這層檢測到了507個結果(即507個矩形框),其中7就是矩形框的資訊,為什麼是7呢,這裡解釋下,7=5+2,5是矩形框(x,y,w,h,c)2是2個類別分別的置信度(class0、class1). 所以每一行代表一個檢測結果。
接下來就是對檢測結果進行處理與顯示 在檢測結果中會有很多每個類的置信度為0的矩形框,要把這些與置信度較低的框去掉
#接下來就是對檢測結果進行處理 for output in layerOutputs: #對三個輸出層 迴圈 for detection in output: #對每個輸出層中的每個檢測框迴圈 scores=detection[5:] #detection=[x,y,h,w,c,class1,class2] classID = np.argmax(scores)#np.argmax反饋最大值的索引 confidence = scores[classID] if confidence >0.5:#過濾掉那些置信度較小的檢測結果 box = detection[0: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)) classIDs.append(classID)
現在就將網路的檢測結果提取了出來,框、置信度、類別。 可以先畫一下看下效果
a=0 for box in boxes:#將每個框畫出來 a=a+1 (x,y)=(box[0],box[1])#框左上角 (w,h)=(box[2],box[3])#框寬高 if classIDs[a-1]==0: #根據類別設定框的顏色 color = [0,0,255] else: color = [0, 255, 0] cv2.rectangle(image, (x, y), (x + w, y + h), color, 2) #畫框 text = "{}: {:.4f}".format(LABELS[classIDs[a-1]], confidences[a-1]) cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.3, color, 1)#寫字 cv2.namedWindow('Image', cv2.WINDOW_NORMAL) cv2.imshow("Image", image) cv2.waitKey(0)
結果:
可以看到對於同一目標有幾個矩形框,這需要對框進行非極大值抑制處理。 進行非極大值抑制的操作,opencv的dnn有個直接的函數 NMSBoxes(bboxes, scores, score_threshold, nms_threshold, eta=None, top_k=None) bboxes需要操作的各矩形框對應咱程式的boxes scores矩形框對應的置信度對應咱程式的confidences score_threshold置信度的閾值,低於這個閾值的框直接刪除 nms_threshold nms的閾值 非極大值的原理沒有理解的話,裡面的引數不好設定。 下面簡單說下非極大值抑制的原理
1)先對輸入檢測框按置信度由高到低排序
2)挑選第一個檢測框(即最高置信度,記為A)和其它檢測框(記為B)進行iou計算
3)如果iou大於nmsThreshold, 那就將B清除掉
4)跳轉到2)從剩餘得框集裡面找置信度最大得框和其它框分別計算iou
5)直到所有框都過濾完 NMSBoxes()函數返回值為最終剩下的按置信度由高到低的矩形框的序列號 進行非極大值抑制後,顯示部分程式碼改一部分即可。
直接給出程式碼
idxs=cv2.dnn.NMSBoxes(boxes, confidences, 0.2,0.3) box_seq = idxs.flatten()#[ 2 9 7 10 6 5 4] if len(idxs)>0: for seq in box_seq: (x, y) = (boxes[seq][0], boxes[seq][1]) # 框左上角 (w, h) = (boxes[seq][2], boxes[seq][3]) # 框寬高 if classIDs[seq]==0: #根據類別設定框的顏色 color = [0,0,255] else: color = [0,255,0] cv2.rectangle(image, (x, y), (x + w, y + h), color, 2) # 畫框 text = "{}: {:.4f}".format(LABELS[classIDs[seq]], confidences[seq]) cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.3, color, 1) # 寫字 cv2.namedWindow('Image', cv2.WINDOW_NORMAL) cv2.imshow("Image", image) cv2.waitKey(0)
最終的檢測結果
至此及用opencv載入yolo v3的模型,進行了一次圖片的檢測。
#coding:utf-8 import numpy as np import cv2 import os weightsPath='E:deep_learnyolov3_modeFileyolov3-voc_25000.weights'# 模型權重檔案 configPath="E:deep_learnyolov3_modeFileyolov3-voc.cfg"# 模型組態檔 labelsPath = "E:\deep_learn\yolov3_modeFile\voc.names"# 模型類別標籤檔案 #初始化一些引數 LABELS = open(labelsPath).read().strip().split("n") boxes = [] confidences = [] classIDs = [] #載入 網路設定與訓練的權重檔案 構建網路 net = cv2.dnn.readNetFromDarknet(configPath,weightsPath) #讀入待檢測的影象 image = cv2.imread('E:deep_learnyolov3_detection_imageR1_WH_ZW_40_80_288.jpg') #得到影象的高和寬 (H,W) = image.shape[0:2] # 得到 YOLO需要的輸出層 ln = net.getLayerNames() out = net.getUnconnectedOutLayers()#得到未連線層得序號 [[200] /n [267] /n [400] ] x = [] for i in out: # 1=[200] x.append(ln[i[0]-1]) # i[0]-1 取out中的數位 [200][0]=200 ln(199)= 'yolo_82' ln=x # ln = ['yolo_82', 'yolo_94', 'yolo_106'] 得到 YOLO需要的輸出層 #從輸入影象構造一個blob,然後通過載入的模型,給我們提供邊界框和相關概率 #blobFromImage(image, scalefactor=None, size=None, mean=None, swapRB=None, crop=None, ddepth=None) blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416),swapRB=True, crop=False)#構造了一個blob影象,對原影象進行了影象的歸一化,縮放了尺寸 ,對應訓練模型 net.setInput(blob) #將blob設為輸入??? 具體作用還不是很清楚 layerOutputs = net.forward(ln) #ln此時為輸出層名稱 ,向前傳播 得到檢測結果 for output in layerOutputs: #對三個輸出層 迴圈 for detection in output: #對每個輸出層中的每個檢測框迴圈 scores=detection[5:] #detection=[x,y,h,w,c,class1,class2] scores取第6位至最後 classID = np.argmax(scores)#np.argmax反饋最大值的索引 confidence = scores[classID] if confidence >0.5:#過濾掉那些置信度較小的檢測結果 box = detection[0:4] * np.array([W, H, W, H]) #print(box) (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)) classIDs.append(classID) idxs=cv2.dnn.NMSBoxes(boxes, confidences, 0.2,0.3) box_seq = idxs.flatten()#[ 2 9 7 10 6 5 4] if len(idxs)>0: for seq in box_seq: (x, y) = (boxes[seq][0], boxes[seq][1]) # 框左上角 (w, h) = (boxes[seq][2], boxes[seq][3]) # 框寬高 if classIDs[seq]==0: #根據類別設定框的顏色 color = [0,0,255] else: color = [0,255,0] cv2.rectangle(image, (x, y), (x + w, y + h), color, 2) # 畫框 text = "{}: {:.4f}".format(LABELS[classIDs[seq]], confidences[seq]) cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.3, color, 1) # 寫字 cv2.namedWindow('Image', cv2.WINDOW_NORMAL) cv2.imshow("Image", image) cv2.waitKey(0)
以上就是opencv呼叫yolov3模型深度學習目標檢測範例詳解的詳細內容,更多關於opencv呼叫yolov3目標檢測的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45