使用OpenCV預處理神經網絡中的面部圖像(圖片/影像)
使用OpenCV預處理神經網絡中的面部圖像(圖片/影像)
資料來源: https://mp.weixin.qq.com/s?__biz=MzA4MDExMDEyMw==&mid=2247489151&idx=2&sn=face6c60085b508319dfc8d9bbc7d861&chksm=9fa8613ba8dfe82d25b9a0790d3b70331d2e0059687d484c9d3a18324d13175a161486015c40&scene=126&sessionid=1595899093&key=bf49e72a192178bf16c44cd135ae34f4bacd9e6aec96f68e3764134a6318570f02a50387fc796169384df611e5c804b4880ba2e80f508e63ae97d139afb7a569f5dbb082ba3a1a05ddc0a49fda053ae7&ascene=1&uin=MjIwODk2NDgxNw%3D%3D&devicetype=Windows+10+x64&version=62090529&lang=zh_TW&exportkey=AprBPbfUxcdO9xqdr8nrKqs%3D&pass_ticket=JJEmjBpPvJCtmH9Wn54FpB%2BhYrxSxNTlT3OneYBMt3NEAMfnleETJFjmG943cHJ5
01.圖片載入
我們使用該imread() 函數加載圖像,並指定文件路徑和圖像模式。第二個參數對於運行基本通道和深度轉換很重要。
img = cv2.imread('path/image.jpg', cv2.IMREAD_COLOR)
要查看圖像可以使用imshow() 功能:
cv2.imshow(img)
02.彩色圖像有3個通道:藍色,綠色和紅色(在OpenCV中按此順序)。
我們可以很輕鬆查看單個通道:
# Example for green channel img[:, :, 0]; img[:, :, 2]; cv2.imshow(img)
03.灰度圖像
為了避免在人臉圖像分類過程中存在的干擾,通常選擇黑白圖像(當然也可以使用彩圖!請小伙伴們自行嘗試兩者並比較結果)。要獲得灰度圖像,我們只需要在圖像加載函數中通過將適當的值作為第二個參數傳遞來指定它:
img = cv2.imread('path/image.jpg', cv2.IMREAD_GRAYSCALE)
04.面部和眼睛檢測
在處理人臉分類問題時,我們可能需要先對圖形進行裁剪和拉直,再進行人臉檢測以驗證是否有人臉的存在。為此,我們將使用OpenCV中自帶的的基於Haar 特徵的級聯分類器進行對象檢測。
首先,我們選擇用於面部和眼睛檢測的預訓練分類器。以下時可用的XML 文件列表:
1)對於面部檢測,OpenCV提供了這些(從最鬆的先驗到最嚴格的先驗):
• haarcascade_frontalface_default.xml
• haarcascade_frontalface_alt.xml
• haarcascade_frontalface_alt2.xml
• haarcascade_frontalface_alt_tree.xml
2)對於眼睛檢測,我們可以選擇以下兩種:
• haarcascade_eye.xml
• haarcascade_eye_tree_eyeglasses.xml(正在嘗試處理眼鏡!)
我們以這種方式加載預訓練的分類器:
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')eyes_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye.xml')
我們可以測試幾種組合,但我們要記住一點,沒有一種分類器在所有情況下都是最好的(如果第一個分類失敗,您可以嘗試第二個分類,甚至嘗試所有分類)。
對於人臉檢測,我們可使用以下代碼:
faces_detected = face_cascade.detectMultiScale(img, scaleFactor=1.1, minNeighbors=5)
結果是一個數組,其中包含所有檢測到的臉部特徵的矩形位置。我們可以很容易地繪製它:
(x, y, w, h) = faces_detected[0] cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 1); cv2.imshow (img)
對於眼睛,我們以類似的方式進行,但將搜索範圍縮小到剛剛提取出來的面部矩形框內:
eyes = eyes_cascade.detectMultiScale(img[y:y+h, x:x+w])for (ex, ey, ew, eh) in eyes: cv2.rectangle(img, (x+ex, y+ey), (x+ex+ew, y+ey+eh), (255, 255, 255), 1)
05.臉部旋轉
通過計算兩隻眼睛之間的角度,我們就可以拉直面部圖像(這很容易)。計算之後,我們僅需兩個步驟即可旋轉圖像:
rows, cols = img.shape[:2] M = cv2.getRotationMatrix2D((cols/2, rows/2), <angle>, 1) img_rotated = cv2.warpAffine(face_orig, M, (cols,rows))
06.裁臉
為了幫助我們的神經網絡完成面部分類任務,最好去除外界無關信息,例如背景,衣服或配件。在這些情況下,面部裁切非常方便。
我們需要做的第一件事是再次從旋轉後的圖像中獲取面部矩形。然後我們需要做出決定:我們可以按原樣裁剪矩形區域,也可以添加額外的填充,以便在周圍獲得更多空間。這取決於要解決的具體問題(按年齡,性別,種族等分類);也許我們需要保留頭髮,也許不需要。
最後進行裁剪(p 用於填充):
cv2.imwrite('crop.jpg', img_rotated[y-p+1:y+h+p, x-p+1:x+w+p])
07.圖像調整大小
神經網絡需要的所有輸入圖像具有相同的形狀和大小,因為GPU應用相同的指令處理一批相同大小圖像,可以達到較快的速度。我們雖然可以隨時調整它們的大小,但這並不是一個好主意,因為需要在訓練期間將對每個文件執行幾次轉換。因此,如果我們的數據集包含大量圖像,我們應該考慮在訓練階段之前實施批量調整大小的過程。
在OpenCV中,我們可以與同時執行縮小和升頻resize() ,有幾個插值方法可用。指定最終大小的示例:
cv2.resize(img, (<width>, <height>), interpolation=cv2.INTER_LINEAR)
要縮小圖像,OpenCV建議使用INTER_AREA 插值法,而放大圖像時,可以使用INTER_CUBIC (慢速)或INTER_LINEAR (更快,但效果仍然不錯)。最後,這是質量和時間之間的權衡。