TShopping

 找回密碼
 註冊
搜索
查看: 2318|回復: 0
打印 上一主題 下一主題

[教學] OpenCV行人檢測

[複製鏈接]
跳轉到指定樓層
1#
發表於 2020-11-23 20:25:56 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
 
Push to Facebook
你知道OpenCV裡面已經內置的行人檢測方法嗎?在OpenCV裡面,有一個預先訓練好了的HOG+線性SVM模型,能夠對圖像和視頻中的行人進行檢測。如果你還不熟悉方向梯度直方圖HOG和線性SVM方法,我建議你閱讀方向梯度直方圖和物體檢測這篇文章,在這篇文章中,我對該框架分了6步進行討論。
如果你已經熟悉了這個過程,或者你僅僅只是想看看OpenCV行人檢測的代碼,那麼現在就打開一個新文件,並將它命名為detect.py,開始我們的編程之旅吧:

  1. # import the necessary packages
  2. from __future__ import print_function
  3. from imutils.object_detection import non_max_suppression
  4. from imutils import paths
  5. import numpy as np
  6. import argparse
  7. import imutils
  8. import cv2

  9. # construct the argument parse and parse the arguments
  10. ap = argparse.ArgumentParser()
  11. ap.add_argument("-i", "--images", required=True, help="path to images directory")
  12. args = vars(ap.parse_args())

  13. # initialize the HOG descriptor/person detector
  14. hog = cv2.HOGDescriptor()
  15. hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
複製代碼


第2-8行導入一些我們必要的包,我們導入print_function確保我們的代碼同時在Python2.7和Python3上兼容,這樣可以使得我們的代碼能夠在OpenCV2.4.X和OPenCV3上都能夠工作,然後,從我的imutils包中我們導入non_max_suppression函數。

如果你還沒有安裝imutils,可以通過pip來安裝:


  1. pip install imutils
複製代碼

如果你已經安裝了imutils,你需要把它更新到最新版(v0.3.1),在這個版本里面,包含了non_max_suppression函數的實現,以及其它一些微小的更新:

  1. pip install --upgrade imutils
複製代碼

我已經在我的PyImageSearch博客上在兩次講到過非極大抑制(non-maxima suppression)方法,一次是在Python非極大抑制用於物體檢測,一篇是在用Python實現更快的非極大抑制,無論是哪一種情形,非極大抑制的宗旨都是獲取多個重疊的邊框(bounding box),並且將他們減少至僅有一個邊框。

圖1:左圖有很多檢測錯誤的邊框;右圖採用非極大抑制後,使得我們可以抑制那些重疊的區域,將正確的邊框留下來
非極大抑制方法可以減少在進行行人檢測過程中的假陽率。

第11-13行處理我們命令行傳入的參數,這裡,我們只需要一個切換--images,用它來傳入待檢測行人的圖像目錄。

最後,第16行和17行初始化我們的行人檢測器。首先,我們調用hog = cv2.HOGDescriptor()來初始化方向梯度直方圖描述子,然後,我們調用setSVMDetector來設置支持向量機(Support Vector Machine)使得它成為一個預先訓練好了的行人檢測器。

到了這裡,我們的OpenCV行人檢測器已經完全載入了,我們只需要把它應用到一些圖像上:


  1. # import the necessary packages
  2. from __future__ import print_function
  3. from imutils.object_detection import non_max_suppression
  4. from imutils import paths
  5. import numpy as np
  6. import argparse
  7. import imutils
  8. import cv2

  9. # construct the argument parse and parse the arguments
  10. ap = argparse.ArgumentParser()
  11. ap.add_argument("-i", "--images", required=True, help="path to images directory")
  12. args = vars(ap.parse_args())

  13. # initialize the HOG descriptor/person detector
  14. hog = cv2.HOGDescriptor()
  15. hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

  16. # loop over the image paths
  17. for imagePath in paths.list_images(args["images"]):
  18.         # load the image and resize it to (1) reduce detection time
  19.         # and (2) improve detection accuracy
  20.         image = cv2.imread(imagePath)
  21.         image = imutils.resize(image, width=min(400, image.shape[1]))
  22.         orig = image.copy()

  23.         # detect people in the image
  24.         (rects, weights) = hog.detectMultiScale(image, winStride=(4, 4),
  25.                 padding=(8, 8), scale=1.05)

  26.         # draw the original bounding boxes
  27.         for (x, y, w, h) in rects:
  28.                 cv2.rectangle(orig, (x, y), (x + w, y + h), (0, 0, 255), 2)

  29.         # apply non-maxima suppression to the bounding boxes using a
  30.         # fairly large overlap threshold to try to maintain overlapping
  31.         # boxes that are still people
  32.         rects = np.array([[x, y, x + w, y + h] for (x, y, w, h) in rects])
  33.         pick = non_max_suppression(rects, probs=None, overlapThresh=0.65)

  34.         # draw the final bounding boxes
  35.         for (xA, yA, xB, yB) in pick:
  36.                 cv2.rectangle(image, (xA, yA), (xB, yB), (0, 255, 0), 2)

  37.         # show some information on the number of bounding boxes
  38.         filename = imagePath[imagePath.rfind("/") + 1:]
  39.         print("[INFO] {}: {} original boxes, {} after suppression".format(
  40.                 filename, len(rects), len(pick)))

  41.         # show the output images
  42.         cv2.imshow("Before NMS", orig)
  43.         cv2.imshow("After NMS", image)
  44.         cv2.waitKey(0)
複製代碼

在第20行我們對我們的--images目錄下的圖像進行循環,這篇博文中使用的例子樣本是從INRIA Person Dataset這個很流行的人物庫上抽取的,更具體的說,是從GRAZ-01子集中抽取出來的,這些圖片存放在源碼目錄下面了。

第23-25行載入磁盤中的圖像,並且將圖像裁剪到最大寬度為400個像素,之所以降低我們的圖像維度(其實就是之所以對我們的圖像尺寸進行裁剪)主要有兩個原因:

減小圖像的尺寸可以減少在圖像金字塔中滑窗的數目,如此可以降低檢測的時間,從而提高整體檢測的吞吐量。
調整圖像的尺寸能夠整體提高行人檢測的精度,也就是假陽率。
真正對圖像中的行人進行檢測的代碼是在第28行和29行,通過調用detectMultiScale的hog描述子方法。這個detectMultiScale方法構造了一個尺度scale=1.05的圖像金字塔,以及一個分別在x方向和y方向步長為(4,4)像素大小的滑窗。

窗口的大小固定在32*128像素大小,這個設置是按照seminal Dalal和Triggs論文來設置的。detectMultiScale函數會返回一個2-元組的rects,或者是圖像中每一個行人的邊框坐標(x,y),以及由SVM在每一次檢測中返回的weights置信值(我們一般也成為分數,譯者註)。

scale的尺度設置得越大,在圖像金字塔中層的數目就越少,相應的檢測速度就越快,但是尺度太大會導致行人出現漏檢;同樣的,如果scale設置得太小,將會急劇的增加圖像金字塔的層數,這樣不僅耗費計算資源,而且還會急劇地增加檢測過程中出現的假陽數目(也就是不是行人的被檢測成行人)。這表明,scale是在行人檢測過程中它是一個重要的參數,需要對scale進行調參。我會在後面的文章中對detectMultiScale中的每個參數做些調研。

第32行和33行獲取我們的初始邊框,並將它們在圖像上框出來。

不過,你將會看到在一些圖像上有的行人框出來的框,有很多重疊的邊框,如上面1圖所示。

針對這種情況,我們有兩種選擇。一種選擇是檢測一個邊框是否完全包含了另一個邊框(你可以看看OpenV中的一些實現例子)。另外一種選擇是應用非極大抑制方法,通過設置一個閾值來抑制那些重疊的邊框,這就是第38行和39行所干的事。

注意:如果你想了解更多HOG框架和非極大抑制,我推薦你閱讀方向梯度直方圖和物體檢測。在那篇博文中,你可以查看Python非極大抑制用於物體檢測,以及後面更新的Malisiewicz方法

在應用非極大抑制後,我們在第42行和43行畫出最終的邊框,在第46-48行中我們展示圖像的一些基本信息,以及檢測到的邊框數目,在第51-53行,在屏幕最終顯示我們輸入的圖像。

行人檢測結果
為了看看我們寫的行人檢測腳本的實際效果,我們只需要執行下面命令:

  1. python detect.py --images images
複製代碼

下圖是一張行人檢測的結果圖:



圖2:檢測效果
上圖我們檢測到了站在警車旁的單個行人。



圖3:在前景和背景中分別檢測到了1個人
上面我們可以看到在前景中的男人被檢測到了,同時背景中推著嬰兒車的女人也檢測到了。



圖4:一個展示為什麼用非極大抑制很重要的例子
圖4的例子展示了為什麼用非極大抑制很重要。detectMultiScale函數除了將正確的邊框檢測出來外,還把兩個邊框邊框檢測出來了,這兩個錯誤的邊框將圖像中的行人覆蓋了。通過使用非極大抑制,我們可以抑制錯誤的邊框,只留下正確檢測的邊框。



圖5:另一個展示非極大抑制效果的例子
我們再一次可以看到,有很多錯誤的邊框被檢測出來了,通過使用非極大抑制,我們可以抑制錯誤的邊框,只留下正確檢測的邊框。



圖6:在一個購物中心檢測行人
圖6在一個購物中心進行行人檢測,圖中,有兩個人正向攝像頭走進,另外一個人正遠離攝像頭,不管是哪種情形,我們的HOG檢測方法都能夠準確的檢測出行人。在non_maxima_suppression 函數中較大的overlapThresh能夠確保那些部分重疊了的邊框不會被抑制。



圖7:在模糊圖片中檢測行人
老實說,我對上面圖片的檢測結果有點兒驚訝,因為一般而言HOG描述子在運動模糊的圖片上檢測效果不是很好,不過在這幅圖像上,我們卻將行人檢測出來了。



圖8:在室外街道上檢測行人
這裡有另外一個多個重疊邊框的例子,不過因為我們的overlapThresh設置得比較大,所以這些邊框沒有被抑制,從而能夠將正確的檢測結果留下來。



圖9:檢測一張具有4個成員的家庭的圖片
圖9的例子展示了HOG+SVM行人檢測器的多功能性,我們不僅能夠檢測到成年的男人,也能夠檢測到那三個小孩(注意:該檢測器不能檢測到躲藏在他老爸後面的小孩)。



圖10:對路標標識進行行人檢測
我將圖10放在最後是因為我發覺這非常的有趣,我們可以很清楚的看到這只是一個路標標識,標識表示人行橫道,然而,HOG+SVM檢測器將它們在圖中框出來了,實際上它們卻並不是行人。

總結
在這篇博文中,我們已經學到了怎樣使用OpenCV的庫以及Python來進行行人檢測。

實際上OpenCV庫已經內置了一個預先訓練好了的HOG+線性SVM檢測器的模型,它是基於Dalal和Triggs論文裡的方法來自動的實現圖像中行人的檢測。

雖然HOG的方法比Haar counter-part的精度要高,不過它仍需要對detectMultiScale進行合理的設置。在後面的博文中,我會對detectMultiScale中的每一個參數做一個調研,已經怎樣調參的細節,並陳述在精度和性能之間的折中。

不管怎麼說,我都希望你喜歡這篇博文!我正打算在後面給出更多的關於物體檢測的教程,如果你希望這些教程出來後能夠獲得及時的通知,你可以考慮訂閱我的博客。

我已經在PyImageSearch Gurus course裡麵包含了HOG+線性SVM的物體檢測方法,你可以看看。



文章出處

網頁設計,網站架設 ,網路行銷,網頁優化,SEO - NetYea 網頁設計

 

臉書網友討論
*滑块验证:
您需要登錄後才可以回帖 登錄 | 註冊 |

本版積分規則



Archiver|手機版|小黑屋|免責聲明|TShopping

GMT+8, 2024-4-27 10:00 , Processed in 0.070754 second(s), 25 queries .

本論壇言論純屬發表者個人意見,與 TShopping綜合論壇 立場無關 如有意見侵犯了您的權益 請寫信聯絡我們。

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表