天天看點

20年AI經驗大佬深度解析基于深度學習和OpenCV實作目标檢測

作者:AI人工智能知識庫

這篇文章主要介紹了通過使用OpenCV進行基于深度學習的對象檢測以及使用OpenCV檢測視訊,文中的示例代碼講解詳細,需要的可以參考一下

目錄

  • 使用深度學習和 OpenCV 進行目标檢測
  • MobileNets:高效(深度)神經網絡
  • 使用 OpenCV 進行基于深度學習的對象檢測
  • 使用 OpenCV 檢測視訊

使用深度學習和 OpenCV 進行目标檢測

基于深度學習的對象檢測時,您可能會遇到三種主要的對象檢測方法:

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 可能是使用深度學習進行對象檢測最“聽說”的方法;然而,該技術可能難以了解(特别是對于深度學習的初學者)、難以實施且難以訓練。

此外,即使使用“更快”的 R-CNN 實作(其中“R”代表“區域提議”),算法也可能非常慢,大約為 7 FPS。

如果追求純粹的速度,那麼我們傾向于使用 YOLO,因為這種算法要快得多,能夠在 Titan X GPU 上處理 40-90 FPS。 YOLO 的超快變體甚至可以達到 155 FPS。

YOLO 的問題在于它的準确性不高。

最初由 Google 開發的 SSD 是兩者之間的平衡。該算法比 Faster R-CNN 更直接。

MobileNets:高效(深度)神經網絡

20年AI經驗大佬深度解析基于深度學習和OpenCV實作目标檢測

在建構對象檢測網絡時,我們通常使用現有的網絡架構,例如 VGG 或 ResNet,這些網絡架構可能非常大,大約 200-500MB。 由于其龐大的規模和由此産生的計算數量,諸如此類的網絡架構不适合資源受限的裝置。 相反,我們可以使用 Google 研究人員的另一篇論文 MobileNets(Howard 等人,2017 年)。我們稱這些網絡為“MobileNets”,因為它們專為資源受限的裝置而設計,例如您的智能手機。 MobileNet 與傳統 CNN 的不同之處在于使用了深度可分離卷積。 深度可分離卷積背後的一般思想是将卷積分成兩個階段:

  • 3×3 深度卷積。
  • 随後是 1×1 逐點卷積。

這使我們能夠實際減少網絡中的參數數量。 問題是犧牲了準确性——MobileNets 通常不如它們的大哥們準确…… ……但它們的資源效率要高得多。

使用 OpenCV 進行基于深度學習的對象檢測

MobileNet SSD 首先在 COCO 資料集(上下文中的常見對象)上進行訓練,然後在 PASCAL VOC 上進行微調,達到 72.7% mAP(平均精度)。

是以,我們可以檢測圖像中的 20 個對象(背景類為 +1),包括飛機、自行車、鳥、船、瓶子、公共汽車、汽車、貓、椅子、牛、餐桌、狗、馬、機車、人、盆栽 植物、羊、沙發、火車和電視顯示器。

在本節中,我們将使用 OpenCV 中的 MobileNet SSD + 深度神經網絡 (dnn) 子產品來建構我們的目标檢測器。

打開一個新檔案,将其命名為 object_detection.py ,并插入以下代碼:

  1. | import numpy as np
  2. | import cv2
  3. | if __name__=="__main__":
  4. | image_name = '11.jpg'
  5. | prototxt = 'MobileNetSSD_deploy.prototxt.txt'
  6. | model_path = 'MobileNetSSD_deploy.caffemodel'
  7. | confidence_ta = 0.2
  8. | # 初始化MobileNet SSD訓練的類标簽清單
  9. | # 檢測,然後為每個類生成一組邊界框顔色
  10. | CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat",
  11. | "bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
  12. | "dog", "horse", "motorbike", "person", "pottedplant", "sheep",
  13. | "sofa", "train", "tvmonitor"]
  14. | COLORS = np.random.uniform(0, 255, size=(len(CLASSES), 3))

導入需要的包。

定義全局參數:

  • image_name:輸入圖像的路徑。
  • prototxt :Caffe prototxt 檔案的路徑。
  • model_path :預訓練模型的路徑。
  • confidence_ta :過濾弱檢測的最小機率門檻值。 預設值為 20%。

接下來,讓我們初始化類标簽和邊界框顔色。

  1. | # load our serialized model from disk
  2. | print("[INFO] loading model...")
  3. | net = cv2.dnn.readNetFromCaffe(prototxt, model_path)
  4. | # 加載輸入圖像并為圖像構造一個輸入blob
  5. | # 将大小調整為固定的300x300像素。
  6. | # (注意:SSD模型的輸入是300x300像素)
  7. | image = cv2.imread(image_name)
  8. | (h, w) = image.shape[:2]
  9. | blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 0.007843,
  10. | (300, 300), 127.5)
  11. | # 通過網絡傳遞blob并獲得檢測結果和
  12. | # 預測
  13. | print("[INFO] computing object detections...")
  14. | net.setInput(blob)
  15. | detections = net.forward()

從磁盤加載模型。

讀取圖檔。

提取高度和寬度(第 35 行),并從圖像中計算一個 300 x 300 像素的 blob。

将blob放入神經網絡。

計算輸入的前向傳遞,将結果存儲為 detections。

  1. | # 循環檢測結果
  2. | for i in np.arange(0, detections.shape[2]):
  3. | # 提取與資料相關的置信度(即機率)
  4. | # 預測
  5. | confidence = detections[0, 0, i, 2]
  6. | # 通過確定“置信度”來過濾掉弱檢測
  7. | # 大于最小置信度
  8. | if confidence > confidence_ta:
  9. | # 從`detections`中提取類标簽的索引,
  10. | # 然後計算物體邊界框的 (x, y) 坐标
  11. | idx = int(detections[0, 0, i, 1])
  12. | box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
  13. | (startX, startY, endX, endY) = box.astype("int")
  14. | # 顯示預測
  15. | label = "{}: {:.2f}%".format(CLASSES[idx], confidence * 100)
  16. | print("[INFO] {}".format(label))
  17. | cv2.rectangle(image, (startX, startY), (endX, endY),
  18. | COLORS[idx], 2)
  19. | y = startY - 15 if startY - 15 > 15 else startY + 15
  20. | cv2.putText(image, label, (startX, y),
  21. | cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 2)
  22. | # show the output image
  23. | cv2.imshow("Output", image)
  24. | cv2.imwrite("output.jpg", image)
  25. | cv2.waitKey(0)

循環檢測,首先我們提取置信度值。

如果置信度高于我們的最小門檻值,我們提取類标簽索引并計算檢測到的對象周圍的邊界框。

然後,提取框的 (x, y) 坐标,我們将很快使用它來繪制矩形和顯示文本。

接下來,建構一個包含 CLASS 名稱和置信度的文本标簽。

使用标簽,将其列印到終端,然後使用之前提取的 (x, y) 坐标在對象周圍繪制一個彩色矩形。

通常,希望标簽顯示在矩形上方,但如果沒有空間,我們會将其顯示在矩形頂部下方。

最後,使用剛剛計算的 y 值将彩色文本覆寫到圖像上。

運作結果:

20年AI經驗大佬深度解析基于深度學習和OpenCV實作目标檢測

使用 OpenCV 檢測視訊

打開一個新檔案,将其命名為 video_object_detection.py ,并插入以下代碼:

  1. | video_name = '12.mkv'
  2. | prototxt = 'MobileNetSSD_deploy.prototxt.txt'
  3. | model_path = 'MobileNetSSD_deploy.caffemodel'
  4. | confidence_ta = 0.2
  5. | # initialize the list of class labels MobileNet SSD was trained to
  6. | # detect, then generate a set of bounding box colors for each class
  7. | CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat",
  8. | "bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
  9. | "dog", "horse", "motorbike", "person", "pottedplant", "sheep",
  10. | "sofa", "train", "tvmonitor"]
  11. | COLORS = np.random.uniform(0, 255, size=(len(CLASSES), 3))
  12. | # load our serialized model from disk
  13. | print("[INFO] loading model...")
  14. | net = cv2.dnn.readNetFromCaffe(prototxt, model_path)
  15. | # initialze the video stream, allow the camera to sensor to warmup,
  16. | # and initlaize the FPS counter
  17. | print('[INFO] starting video stream...')
  18. | vs = cv2.VideoCapture(video_name)
  19. | fps = 30 #儲存視訊的FPS,可以适當調整
  20. | size=(600,325)
  21. | fourcc=cv2.VideoWriter_fourcc(*'XVID')
  22. | videowrite=cv2.VideoWriter('output.avi',fourcc,fps,size)
  23. | time.sleep(2.0)

定義全局參數:

  • video_name:輸入視訊的路徑。
  • prototxt :Caffe prototxt 檔案的路徑。
  • model_path :預訓練模型的路徑。
  • confidence_ta :過濾弱檢測的最小機率門檻值。 預設值為 20%。

接下來,讓我們初始化類标簽和邊界框顔色。

加載模型。

初始化VideoCapture對象。

設定VideoWriter對象以及參數。size的大小由下面的代碼決定,需要保持一緻,否則不能儲存視訊。

20年AI經驗大佬深度解析基于深度學習和OpenCV實作目标檢測

接下就是循環視訊的幀,然後輸入到檢測器進行檢測,這一部分的邏輯和圖像檢測一緻。代碼如下:

  1. | # loop over the frames from the video stream
  2. | while True:
  3. | ret_val, frame = vs.read()
  4. | if ret_val is False:
  5. | break
  6. | frame = imutils.resize(frame, width=1080)
  7. | print(frame.shape)
  8. | # grab the frame dimentions and convert it to a blob
  9. | (h, w) = frame.shape[:2]
  10. | blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 0.007843, (300, 300), 1| 27.5)
  11. | # pass the blob through the network and obtain the detections and predictions
  12. | net.setInput(blob)
  13. | detections = net.forward()
  14. | # loop over the detections
  15. | for i in np.arange(0, detections.shape[2]):
  16. | # extract the confidence (i.e., probability) associated with
  17. | # the prediction
  18. | confidence = detections[0, 0, i, 2]
  19. | # filter out weak detections by ensuring the `confidence` is
  20. | # greater than the minimum confidence
  21. | if confidence > confidence_ta:
  22. | # extract the index of the class label from the
  23. | # `detections`, then compute the (x, y)-coordinates of
  24. | # the bounding box for the object
  25. | idx = int(detections[0, 0, i, 1])
  26. | box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
  27. | (startX, startY, endX, endY) = box.astype("int")
  28. | # draw the prediction on the frame
  29. | label = "{}: {:.2f}%".format(CLASSES[idx],
  30. | confidence * 100)
  31. | cv2.rectangle(frame, (startX, startY), (endX, endY),
  32. | COLORS[idx], 2)
  33. | y = startY - 15 if startY - 15 > 15 else startY + 15
  34. | cv2.putText(frame, label, (startX, y),
  35. | cv2.FONT_HERSHEY_SIMPLEX, 0.5, COLORS[idx], 2)
  36. | # show the output frame
  37. | cv2.imshow("Frame", frame)
  38. | videowrite.write(frame)
  39. | key = cv2.waitKey(1) & 0xFF
  40. | # if the `q` key was pressed, break from the loop
  41. | if key == ord("q"):
  42. | break
  43. | videowrite.release()
  44. | # do a bit of cleanup
  45. | cv2.destroyAllWindows()
  46. | vs.release()

運作結果:

(B站):https://www.bilibili.com/video/BV1h8411c7zk/?spm_id_from=333.337.search-card.all.click&vd_source=b2d0f4c8b7d5e055a1426385d0f0fd5b

以上就是基于深度學習和OpenCV實作目标檢測的詳細内容,更多關于深度學習 OpenCV目标檢測的資料請關注小編其它相關文章!

準備了100G人工智能學習禮包:

1:人工智能詳細學習路線圖、大綱

2:300本人工智能經典書籍

3:機器學習算法+深度學習神經網絡學習教程

4:計算機視覺論文合集

5:人工智能實戰項目合集(附源碼)

6、人工智能筆試、面試題

【還有更多學習筆記,評論區:666,先到先得!】

20年AI經驗大佬深度解析基于深度學習和OpenCV實作目标檢測

繼續閱讀