利用python進行識別相似圖片
前言
和網上各種首先你要有一個女朋友
的系列一樣,想進行人臉判斷,首先要有臉
,
只要能靠確定人臉的位置,那麼進行兩張人臉是否相似的操作便迎刃而解了。
所以本篇文章著重講述如何利用openCV定位人臉。
上一篇文章的地址:
安裝openCV
在進行下一步操作時,我們需要安裝openCV,本來安裝openCV的步驟跟平常安裝其他模組一樣,而然由於python的歷史原因(用過都懂……),弄得一點都不友好。
先說一下,python2.7的使用者,可以直接在openCV的官網上直接下載,然後在openCV的build\python
的目錄下,根據自己的情況,選擇x86
,x64
下的cv2.pyd
放到你python的安裝目錄的\Lib\site-packages\
至於python3.4的使用者,即有點特別。你可以在StackOverFlow找到這樣
和這樣的答案,但我們不要這麼麻煩。
進入這個網站,下載openCV相關whl
檔案,例如opencv_python-3.1.0-cp35-none-win_amd64.whl
然後再對應目錄下使用pip install opencv_python-3.1.0-cp35-none-win_amd64.whl
命令即可
安裝完成後,可以在python的命令列下測試。
import cv2
如果沒有報錯的話,恭喜你安裝成功。
不過無論是哪個版本的使用者,在python上使用openCV都需要先安裝numpy這個模組。
人臉識別的原理
opencv的人臉識別是基於了haar特徵
,關於什麼叫haar特徵
,足以開另外一篇文章說明了,礙於篇幅,這裡不做介紹。
opencv提供已經訓練好的資料寫成了xml檔案,放在了opencv\sources\data\haarcascades
的目錄下。
如果只是安裝了opencv_python-3.1.0-cp35-none-win_amd64.whl
的,可以在我的github上,下載cvdata
裡面的內容
,地址會在文章底部給出。
除了人臉識別的資料外,還有人眼,上半身,下半身……等人體特徵的資料,觀察xml檔案的命名,不難見名知義。
接下來會介紹如何利用這個已經訓練好的資料,如果仍對haar
如何使用訓練好的資料
先講關於openCV基本的一些操作。全部具體程式碼,請檢視我的github。
讀入一張圖片
cv2.imread(path)
如果你用type()
把其返回值的型別是numpy.ndarray
。
而同樣,numpy.asarray(Image)
返回的亦是numpy.ndarray
物件,為什麼強調這兩點?
-
cv2.imread(path)
不能讀取中文路徑,若路徑中含有中文字元,其會返回None
-
在後面的操作中,包括是切割圖片(人臉部分),再進行區域性雜湊,比較相似度,
等等都是用Image
物件進行操作,如果再用Image.open()
讀入圖片未免顯得麻煩。
所以乾脆統一用Image.open()
開啟圖片,再用numpy.asarray(Image)
轉化即可。
需要注意有一個不同的地方是雖然其返回的也是三維陣列,但在第三維,即某個座標下的RGB值,兩個矩陣的順序是反的,但只要另外編寫一個小函式將其反轉即可。
載入xml資料
face_cascade = cv2.CascadeClassifier(xml_path)
將圖片灰度化
if img.ndim == 3:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
else:
gray = img
# 如果img維度為3,說明不是灰度圖,先轉化為灰度圖gray,如果不為3,也就是2,原圖就是灰度圖
img是之前讀入的三維陣列,雖然灰度圖可以用Image
物件的convert('L')
完成,但由於不確定
opencv的處理方法是否和該方法一樣,所以還是用opencv自己的方法進行處理比較好。
獲取人臉座標
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=3,
minSize=(10,10),flags=cv2.CASCADE_SCALE_IMAGE)
-
scale_factor:被檢測物件的尺度變化。尺度越大,越容易漏掉檢測的物件,但檢測速度加快;尺度越小,檢測越細緻準確,但檢測速度變慢。
-
min_neighbors:數值越大,檢測到物件的條件越苛刻;反之檢測到物件的條件越寬鬆;
-
minSize:檢測物件的大小
該方法返回的是一個列表,每個列表元素是長度為四的元組,分別臉部的左上角的x,y值,臉部區域的寬度和高度。
下一步操作
通過上述的方法,我們就已經獲取到人臉的位置,下一步你可以通過ImageDraw
`物件進行繪圖,框出人臉的位置。
同樣,你也可以使用Image
的crop
方法把人臉部分提取出來,然後進行區域性雜湊,
通過上一篇文章提及的演算法,比較兩者的相似度。
兩種操作分別在我的github中實現了,請參考我的github中face1.py
,和face2.py
兩個python檔案。
寫一隻具有識別能力的圖片爬蟲
在上一篇文章中,我說了會應用這些演算法做成以只具有識別能力的圖片爬蟲,然現在我也確實是在做但考慮到作為核心的圖片識別和人臉識別的部分我已經寫成文章分享出來,其餘部分就是想寫其他爬蟲一樣而已,所以我決定看看這兩篇文章的反響後再決定是否繼續該系列,把圖片爬蟲的製作過程和大家分享一下。
總結
鑑於個人實力有限,本文未能詳細說明人臉識別的原理,但總結了如何利用已經訓練好的資料進行人臉識別,希望能幫到有需要的朋友。
如有不足之處,歡迎提出。
本文涉及內容的詳細程式碼在下面的github地址。