基于深度學(xué)習(xí)和OpenCV實(shí)現(xiàn)目標(biāo)檢測
使用深度學(xué)習(xí)和 OpenCV 進(jìn)行目標(biāo)檢測
基于深度學(xué)習(xí)的對(duì)象檢測時(shí),您可能會(huì)遇到三種主要的對(duì)象檢測方法:
Faster R-CNNs (Ren et al., 2015)
You Only Look Once (YOLO) (Redmon et al., 2015)
Single Shot Detectors (SSD)(Liu 等人,2015 年)
Faster R-CNNs 可能是使用深度學(xué)習(xí)進(jìn)行對(duì)象檢測最“聽說”的方法;然而,該技術(shù)可能難以理解(特別是對(duì)于深度學(xué)習(xí)的初學(xué)者)、難以實(shí)施且難以訓(xùn)練。
此外,即使使用“更快”的 R-CNN 實(shí)現(xiàn)(其中“R”代表“區(qū)域提議”),算法也可能非常慢,大約為 7 FPS。
如果追求純粹的速度,那么我們傾向于使用 YOLO,因?yàn)檫@種算法要快得多,能夠在 Titan X GPU 上處理 40-90 FPS。 YOLO 的超快變體甚至可以達(dá)到 155 FPS。
YOLO 的問題在于它的準(zhǔn)確性不高。
最初由 Google 開發(fā)的 SSD 是兩者之間的平衡。該算法比 Faster R-CNN 更直接。
MobileNets:高效(深度)神經(jīng)網(wǎng)絡(luò)

在構(gòu)建對(duì)象檢測網(wǎng)絡(luò)時(shí),我們通常使用現(xiàn)有的網(wǎng)絡(luò)架構(gòu),例如 VGG 或 ResNet,這些網(wǎng)絡(luò)架構(gòu)可能非常大,大約 200-500MB。 由于其龐大的規(guī)模和由此產(chǎn)生的計(jì)算數(shù)量,諸如此類的網(wǎng)絡(luò)架構(gòu)不適合資源受限的設(shè)備。 相反,我們可以使用 Google 研究人員的另一篇論文 MobileNets(Howard 等人,2017 年)。我們稱這些網(wǎng)絡(luò)為“MobileNets”,因?yàn)樗鼈儗橘Y源受限的設(shè)備而設(shè)計(jì),例如您的智能手機(jī)。 MobileNet 與傳統(tǒng) CNN 的不同之處在于使用了深度可分離卷積。 深度可分離卷積背后的一般思想是將卷積分成兩個(gè)階段:
- 3×3 深度卷積。
- 隨后是 1×1 逐點(diǎn)卷積。
這使我們能夠?qū)嶋H減少網(wǎng)絡(luò)中的參數(shù)數(shù)量。 問題是犧牲了準(zhǔn)確性——MobileNets 通常不如它們的大哥們準(zhǔn)確…… ……但它們的資源效率要高得多。
使用 OpenCV 進(jìn)行基于深度學(xué)習(xí)的對(duì)象檢測
MobileNet SSD 首先在 COCO 數(shù)據(jù)集(上下文中的常見對(duì)象)上進(jìn)行訓(xùn)練,然后在 PASCAL VOC 上進(jìn)行微調(diào),達(dá)到 72.7% mAP(平均精度)。
因此,我們可以檢測圖像中的 20 個(gè)對(duì)象(背景類為 +1),包括飛機(jī)、自行車、鳥、船、瓶子、公共汽車、汽車、貓、椅子、牛、餐桌、狗、馬、摩托車、人、盆栽 植物、羊、沙發(fā)、火車和電視顯示器。
在本節(jié)中,我們將使用 OpenCV 中的 MobileNet SSD + 深度神經(jīng)網(wǎng)絡(luò) (dnn) 模塊來構(gòu)建我們的目標(biāo)檢測器。
打開一個(gè)新文件,將其命名為 object_detection.py ,并插入以下代碼:
import numpy as np
import cv2
if __name__=="__main__":
image_name = '11.jpg'
prototxt = 'MobileNetSSD_deploy.prototxt.txt'
model_path = 'MobileNetSSD_deploy.caffemodel'
confidence_ta = 0.2
# 初始化MobileNet SSD訓(xùn)練的類標(biāo)簽列表
# 檢測,然后為每個(gè)類生成一組邊界框顏色
CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat",
"bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
"dog", "horse", "motorbike", "person", "pottedplant", "sheep",
"sofa", "train", "tvmonitor"]
COLORS = np.random.uniform(0, 255, size=(len(CLASSES), 3))
導(dǎo)入需要的包。
定義全局參數(shù):
- image_name:輸入圖像的路徑。
- prototxt :Caffe prototxt 文件的路徑。
- model_path :預(yù)訓(xùn)練模型的路徑。
- confidence_ta :過濾弱檢測的最小概率閾值。 默認(rèn)值為 20%。
接下來,讓我們初始化類標(biāo)簽和邊界框顏色。
# load our serialized model from disk
print("[INFO] loading model...")
net = cv2.dnn.readNetFromCaffe(prototxt, model_path)
# 加載輸入圖像并為圖像構(gòu)造一個(gè)輸入blob
# 將大小調(diào)整為固定的300x300像素。
# (注意:SSD模型的輸入是300x300像素)
image = cv2.imread(image_name)
(h, w) = image.shape[:2]
blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 0.007843,
(300, 300), 127.5)
# 通過網(wǎng)絡(luò)傳遞blob并獲得檢測結(jié)果和
# 預(yù)測
print("[INFO] computing object detections...")
net.setInput(blob)
detections = net.forward()
從磁盤加載模型。
讀取圖片。
提取高度和寬度(第 35 行),并從圖像中計(jì)算一個(gè) 300 x 300 像素的 blob。
將blob放入神經(jīng)網(wǎng)絡(luò)。
計(jì)算輸入的前向傳遞,將結(jié)果存儲(chǔ)為 detections。
# 循環(huán)檢測結(jié)果
for i in np.arange(0, detections.shape[2]):
# 提取與數(shù)據(jù)相關(guān)的置信度(即概率)
# 預(yù)測
confidence = detections[0, 0, i, 2]
# 通過確?!爸眯哦取眮磉^濾掉弱檢測
# 大于最小置信度
if confidence > confidence_ta:
# 從`detections`中提取類標(biāo)簽的索引,
# 然后計(jì)算物體邊界框的 (x, y) 坐標(biāo)
idx = int(detections[0, 0, i, 1])
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
# 顯示預(yù)測
label = "{}: {:.2f}%".format(CLASSES[idx], confidence * 100)
print("[INFO] {}".format(label))
cv2.rectangle(image, (startX, startY), (endX, endY),
COLORS[idx], 2)
y = startY - 15 if startY - 15 > 15 else startY + 15
cv2.putText(image, label, (startX, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 2)
# show the output image
cv2.imshow("Output", image)
cv2.imwrite("output.jpg", image)
cv2.waitKey(0)
循環(huán)檢測,首先我們提取置信度值。
如果置信度高于我們的最小閾值,我們提取類標(biāo)簽索引并計(jì)算檢測到的對(duì)象周圍的邊界框。
然后,提取框的 (x, y) 坐標(biāo),我們將很快使用它來繪制矩形和顯示文本。
接下來,構(gòu)建一個(gè)包含 CLASS 名稱和置信度的文本標(biāo)簽。
使用標(biāo)簽,將其打印到終端,然后使用之前提取的 (x, y) 坐標(biāo)在對(duì)象周圍繪制一個(gè)彩色矩形。
通常,希望標(biāo)簽顯示在矩形上方,但如果沒有空間,我們會(huì)將其顯示在矩形頂部下方。
最后,使用剛剛計(jì)算的 y 值將彩色文本覆蓋到圖像上。
運(yùn)行結(jié)果:

使用 OpenCV 檢測視頻
打開一個(gè)新文件,將其命名為 video_object_detection.py ,并插入以下代碼:
video_name = '12.mkv'
prototxt = 'MobileNetSSD_deploy.prototxt.txt'
model_path = 'MobileNetSSD_deploy.caffemodel'
confidence_ta = 0.2
# initialize the list of class labels MobileNet SSD was trained to
# detect, then generate a set of bounding box colors for each class
CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat",
"bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
"dog", "horse", "motorbike", "person", "pottedplant", "sheep",
"sofa", "train", "tvmonitor"]
COLORS = np.random.uniform(0, 255, size=(len(CLASSES), 3))
# load our serialized model from disk
print("[INFO] loading model...")
net = cv2.dnn.readNetFromCaffe(prototxt, model_path)
# initialze the video stream, allow the camera to sensor to warmup,
# and initlaize the FPS counter
print('[INFO] starting video stream...')
vs = cv2.VideoCapture(video_name)
fps = 30 #保存視頻的FPS,可以適當(dāng)調(diào)整
size=(600,325)
fourcc=cv2.VideoWriter_fourcc(*'XVID')
videowrite=cv2.VideoWriter('output.avi',fourcc,fps,size)
time.sleep(2.0)
定義全局參數(shù):
- video_name:輸入視頻的路徑。
- prototxt :Caffe prototxt 文件的路徑。
- model_path :預(yù)訓(xùn)練模型的路徑。
- confidence_ta :過濾弱檢測的最小概率閾值。 默認(rèn)值為 20%。
接下來,讓我們初始化類標(biāo)簽和邊界框顏色。
加載模型。
初始化VideoCapture對(duì)象。
設(shè)置VideoWriter對(duì)象以及參數(shù)。size的大小由下面的代碼決定,需要保持一致,否則不能保存視頻。

接下就是循環(huán)視頻的幀,然后輸入到檢測器進(jìn)行檢測,這一部分的邏輯和圖像檢測一致。代碼如下:
# loop over the frames from the video stream
while True:
ret_val, frame = vs.read()
if ret_val is False:
break
frame = imutils.resize(frame, width=1080)
print(frame.shape)
# grab the frame dimentions and convert it to a blob
(h, w) = frame.shape[:2]
blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 0.007843, (300, 300), 127.5)
# pass the blob through the network and obtain the detections and predictions
net.setInput(blob)
detections = net.forward()
# loop over the detections
for i in np.arange(0, detections.shape[2]):
# extract the confidence (i.e., probability) associated with
# the prediction
confidence = detections[0, 0, i, 2]
# filter out weak detections by ensuring the `confidence` is
# greater than the minimum confidence
if confidence > confidence_ta:
# extract the index of the class label from the
# `detections`, then compute the (x, y)-coordinates of
# the bounding box for the object
idx = int(detections[0, 0, i, 1])
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
# draw the prediction on the frame
label = "{}: {:.2f}%".format(CLASSES[idx],
confidence * 100)
cv2.rectangle(frame, (startX, startY), (endX, endY),
COLORS[idx], 2)
y = startY - 15 if startY - 15 > 15 else startY + 15
cv2.putText(frame, label, (startX, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 2)
# show the output frame
cv2.imshow("Frame", frame)
videowrite.write(frame)
key = cv2.waitKey(1) & 0xFF
# if the `q` key was pressed, break from the loop
if key == ord("q"):
break
videowrite.release()
# do a bit of cleanup
cv2.destroyAllWindows()
vs.release()
運(yùn)行結(jié)果:
https://www.bilibili.com/video/BV19i4y197kh?spm_id_from=333.999.0.0?
以上就是基于深度學(xué)習(xí)和OpenCV實(shí)現(xiàn)目標(biāo)檢測的詳細(xì)內(nèi)容,更多關(guān)于深度學(xué)習(xí) OpenCV目標(biāo)檢測的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- python opencv檢測目標(biāo)顏色的實(shí)例講解
- Python+OpenCV目標(biāo)跟蹤實(shí)現(xiàn)基本的運(yùn)動(dòng)檢測
- Python Opencv任意形狀目標(biāo)檢測并繪制框圖
- OpenCV實(shí)現(xiàn)幀差法檢測運(yùn)動(dòng)目標(biāo)
- OpenCV+python實(shí)現(xiàn)實(shí)時(shí)目標(biāo)檢測功能
- OpenCV實(shí)現(xiàn)車輛識(shí)別和運(yùn)動(dòng)目標(biāo)檢測
- 如何使用Python和OpenCV進(jìn)行實(shí)時(shí)目標(biāo)檢測實(shí)例詳解
相關(guān)文章
pytorch中permute()函數(shù)用法實(shí)例詳解
permute中參數(shù)為張量的維度,將不同維度以不同的維度排列,得到一個(gè)新的張量,在深度學(xué)習(xí)中的主要作用是將特征值聚類,下面這篇文章主要給大家介紹了關(guān)于pytorch中permute()函數(shù)用法的相關(guān)資料,需要的朋友可以參考下2022-04-04
Python實(shí)現(xiàn)快速多線程ping的方法
這篇文章主要介紹了Python實(shí)現(xiàn)快速多線程ping的方法,實(shí)例分析了Python多線程及ICMP數(shù)據(jù)包的發(fā)送技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07
python的?PyPDF2實(shí)現(xiàn)pdf文件切割和合并
大家好,本篇文章主要講的是python的?PyPDF2實(shí)現(xiàn)pdf文件切割和合并,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下2022-02-02
numpy使用fromstring創(chuàng)建矩陣的實(shí)例
今天小編就為大家分享一篇numpy使用fromstring創(chuàng)建矩陣的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-06-06
python利用pd.cut()和pd.qcut()對(duì)數(shù)據(jù)進(jìn)行分箱操作
本文主要介紹了python利用pd.cut()和pd.qcut()對(duì)數(shù)據(jù)進(jìn)行分箱操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
向量化操作改進(jìn)數(shù)據(jù)分析工作流的Pandas?Numpy示例分析
這篇文章主要介紹了向量化操作改進(jìn)數(shù)據(jù)分析工作流的Pandas?Numpy示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
python中幾個(gè)常用函數(shù)的正確用法-lambda/filter/map/reduce
這篇文章主要介紹了python中幾個(gè)常用函數(shù)的正確用法,這幾個(gè)常用函數(shù)包括lambda、filter、map、reduce,本文將圍繞這幾個(gè)常用函數(shù)展開內(nèi)容,需要的朋友可以參考一下2021-11-11
pytorch下的unsqueeze和squeeze的用法說明
這篇文章主要介紹了pytorch下的unsqueeze和squeeze的用法說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-02-02
python時(shí)間與Unix時(shí)間戳相互轉(zhuǎn)換方法詳解
這篇文章主要介紹了python時(shí)間與Unix時(shí)間戳相互轉(zhuǎn)換方法詳解,需要的朋友可以參考下2020-02-02

