Linux中國

使用 OpenCV 識別圖片中的貓咪

你知道 OpenCV 可以識別在圖片中小貓的臉嗎?而且是拿來就能用,不需要其它的庫之類的。

之前我也不知道。

但是在 Kendrick Tan 曝出這個功能後,我需要親自體驗一下……去看看到 OpenCV 是如何在我沒有察覺到的情況下,將這一個功能添加進了他的軟體庫(就像一隻悄悄溜進空盒子的貓咪一樣,等待別人發覺)。

下面,我將會展示如何使用 OpenCV 的貓咪檢測器在圖片中識別小貓的臉。同樣的,該技術也可以用在視頻流中。

使用 OpenCV 在圖片中檢測貓咪

如果你查找過 OpenCV 的代碼倉庫,尤其是在 haarcascades 目錄里(OpenCV 在這裡保存處理它預先訓練好的 Haar 分類器,以檢測各種物體、身體部位等), 你會看到這兩個文件:

  • haarcascade_frontalcatface.xml
  • haarcascade_frontalcatface_extended.xml

這兩個 Haar Cascade 文件都將被用來在圖片中檢測小貓的臉。實際上,我使用了相同的 cascades 分類器來生成這篇博文頂端的圖片。

在做了一些調查工作之後,我發現這些 cascades 分類器是由鼎鼎大名的 Joseph Howse 訓練和貢獻給 OpenCV 倉庫的,他寫了很多很棒的教程和書籍,在計算機視覺領域有著很高的聲望。

下面,我將會展示給你如何使用 Howse 的 Haar cascades 分類器來檢測圖片中的小貓。

貓咪檢測代碼

讓我們開始使用 OpenCV 來檢測圖片中的貓咪。新建一個叫 cat_detector.py 的文件,並且輸入如下的代碼:

# import the necessary packages
import argparse
import cv2

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
    help="path to the input image")
ap.add_argument("-c", "--cascade",
    default="haarcascade_frontalcatface.xml",
    help="path to cat detector haar cascade")
args = vars(ap.parse_args())

第 2 和第 3 行主要是導入了必要的 python 包。6-12 行用於解析我們的命令行參數。我們僅要求一個必需的參數 --image ,它是我們要使用 OpenCV 檢測貓咪的圖片。

我們也可以(可選的)通過 --cascade 參數指定我們的 Haar cascade 分類器的路徑。默認使用 haarcascades_frontalcatface.xml,假定這個文件和你的 cat_detector.py 在同一目錄下。

注意:我已經打包了貓咪的檢測代碼,還有在這個教程里的樣本圖片。你可以在博文原文的 「下載」 部分下載到。如果你是剛剛接觸 Python+OpenCV(或者 Haar cascade),我建議你下載這個 zip 壓縮包,這個會方便你跟著教程學習。

接下來,就是檢測貓的時刻了:

# load the input image and convert it to grayscale
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# load the cat detector Haar cascade, then detect cat faces
# in the input image
detector = cv2.CascadeClassifier(args["cascade"])
rects = detector.detectMultiScale(gray, scaleFactor=1.3,
    minNeighbors=10, minSize=(75, 75))

在 15、16 行,我們從硬碟上讀取了圖片,並且進行灰度化(這是一個在將圖片傳給 Haar cascade 分類器之前的常用的圖片預處理步驟,儘管不是必須的)

20 行,從硬碟載入 Haar casacade 分類器,即貓咪檢測器,並且實例化 cv2.CascadeClassifier 對象。

在 21、22 行通過調用 detectordetectMultiScale 方法使用 OpenCV 完成貓臉檢測。我們給 detectMultiScale 方法傳遞了四個參數。包括:

  1. 圖片 gray,我們要在該圖片中檢測貓臉。
  2. 檢測貓臉時的圖片金字塔 的檢測粒度 scaleFactor 。更大的粒度將會加快檢測的速度,但是會對檢測 準確性 true-positive 產生影響。相反的,一個更小的粒度將會影響檢測的時間,但是會增加 準確性 true-positive 。但是,細粒度也會增加 誤報率 false-positive 。你可以看這篇博文的「 Haar cascades 注意事項」部分來獲得更多的信息。
  3. minNeighbors 參數控制了檢定框的最少數量,即在給定區域內被判斷為貓臉的最少數量。這個參數可以很好的排除 誤報 false-positive 結果。
  4. 最後,minSize 參數不言自明。這個值描述每個檢定框的最小寬高尺寸(單位是像素),這個例子中就是 75*75

detectMultiScale 函數會返回 rects,這是一個 4 元組列表。這些元組包含了每個檢測到的貓臉的 (x,y) 坐標值,還有寬度、高度。

最後,讓我們在圖片上畫下這些矩形來標識貓臉:

# loop over the cat faces and draw a rectangle surrounding each
for (i, (x, y, w, h)) in enumerate(rects):
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
    cv2.putText(image, "Cat #{}".format(i + 1), (x, y - 10),
        cv2.FONT_HERSHEY_SIMPLEX, 0.55, (0, 0, 255), 2)

# show the detected cat faces
cv2.imshow("Cat Faces", image)
cv2.waitKey(0)

給我們這些框(比如,rects)的數據,我們在 25 行依次遍歷它。

在 26 行,我們在每張貓臉的周圍畫上一個矩形。27、28 行展示了一個整數,即圖片中貓咪的數量。

最後,31,32 行在屏幕上展示了輸出的圖片。

貓咪檢測結果

為了測試我們的 OpenCV 貓咪檢測器,可以在原文的最後,下載教程的源碼。

然後,在你解壓縮之後,你將會得到如下的三個文件/目錄:

  1. cat_detector.py:我們的主程序
  2. haarcascade_frontalcatface.xml: 貓咪檢測器 Haar cascade
  3. images:我們將會使用的檢測圖片目錄。

到這一步,執行以下的命令:

$ python cat_detector.py --image images/cat_01.jpg

圖 1. 在圖片中檢測貓臉,甚至是貓咪部分被遮擋了。

注意,我們已經可以檢測貓臉了,即使它的其餘部分是被遮擋的。

試下另外的一張圖片:

python cat_detector.py --image images/cat_02.jpg

圖 2. 使用 OpenCV 檢測貓臉的第二個例子,這次貓臉稍有不同。

這次的貓臉和第一次的明顯不同,因為它正在發出「喵嗚」叫聲的當中。這種情況下,我們依舊能檢測到正確的貓臉。

在下面這張圖片的結果也是正確的:

$ python cat_detector.py --image images/cat_03.jpg

圖 3. 使用 OpenCV 和 python 檢測貓臉

我們最後的一個樣例就是在一張圖中檢測多張貓臉:

$ python cat_detector.py --image images/cat_04.jpg

圖 4. 在同一張圖片中使用 OpenCV 檢測多隻貓

注意,Haar cascade 返回的檢定框不一定是以你預期的順序。這種情況下,中間的那隻貓會被標記成第三隻。你可以通過判斷他們的 (x, y) 坐標來自己排序這些檢定框。

關於精度的說明

在這個 xml 文件中的注釋非常重要,Joseph Hower 提到了這個貓臉檢測器有可能會將人臉識別成貓臉。

這種情況下,他推薦使用兩種檢測器(人臉 & 貓臉),然後將出現在人臉識別結果中的結果剔除掉。

Haar cascades 注意事項

這個方法首先出現在 Paul Viola 和 Michael Jones 2001 年出版的 Rapid Object Detection using a Boosted Cascade of Simple Features 論文中。現在它已經成為了計算機識別領域引用最多的論文之一。

這個演算法能夠識別圖片中的對象,無論它們的位置和比例。而且最令人感興趣的或許是它能在現有的硬體條件下實現實時檢測。

在他們的論文中,Viola 和 Jones 關注在訓練人臉檢測器;但是,這個框架也能用來檢測各類事物,如汽車、香蕉、路標等等。

問題是?

Haar cascades 最大的問題就是如何確定 detectMultiScale 方法的參數正確。特別是 scaleFactorminNeighbors 參數。你很容易陷入一張一張圖片調參數的坑,這個就是該對象檢測器很難被實用化的原因。

這個 scaleFactor 變數控制了用來檢測對象的圖片的各種比例的圖像金字塔。如果 scaleFactor 參數過大,你就只需要檢測圖像金字塔中較少的層,這可能會導致你丟失一些在圖像金字塔層之間縮放時少了的對象。

換句話說,如果 scaleFactor 參數過低,你會檢測過多的金字塔圖層。這雖然可以能幫助你檢測到更多的對象。但是他會造成計算速度的降低,還會明顯提高誤報率。Haar cascades 分類器就是這樣。

為了避免這個,我們通常使用 Histogram of Oriented Gradients + 線性 SVM 檢測 替代。

上述的 HOG + 線性 SVM 框架的參數更容易調優。而且更好的誤報率也更低,但是唯一不好的地方是無法實時運算。

對對象識別感興趣?並且希望了解更多?

圖 5. 在 PyImageSearch Gurus 課程中學習如何構建自定義的對象識別器。

如果你對學習如何訓練自己的自定義對象識別器感興趣,請務必要去了解下 PyImageSearch Gurus 課程。

在這個課程中,我提供了 15 節課,覆蓋了超過 168 頁的教程,來教你如何從 0 開始構建自定義的對象識別器。你會掌握如何應用 HOG + 線性 SVM 框架來構建自己的對象識別器來識別路標、面孔、汽車(以及附近的其它東西)。

要學習 PyImageSearch Gurus 課程(有 10 節示例免費課程),點此: https://www.pyimagesearch.com/pyimagesearch-gurus/?src=post-cat-detection

總結

在這篇博文里,我們學習了如何使用 OpenCV 默認就有的 Haar cascades 分類器來識別圖片中的貓臉。這些 Haar casacades 是由 Joseph Howse 訓練兵貢獻給 OpenCV 項目的。我是在 Kendrick Tan 的這篇文章中開始注意到這個。

儘管 Haar cascades 相當有用,但是我們也經常用 HOG + 線性 SVM 替代。因為後者相對而言更容易使用,並且可以有效地降低誤報率。

我也會在 PyImageSearch Gurus 課程中詳細的講述如何構建定製的 HOG + 線性 SVM 對象識別器,來識別包括汽車、路標在內的各種事物。

不管怎樣,我希望你喜歡這篇博文。

via: http://www.pyimagesearch.com/2016/06/20/detecting-cats-in-images-with-opencv/

作者:Adrian Rosebrock 譯者:MikeCoder 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國