這篇教學會介紹延伸「人臉偵測」文章的範例,搭配 OpenCV 馬賽克的效果,自動偵測影像中的人臉,並將人臉加上馬賽克。
原文參考:OpenCV 偵測人臉,自動加馬賽克
因為程式中的 OpenCV 會需要使用鏡頭或 GPU,所以請使用本機環境 ( 參考:使用 Python 虛擬環境 ) 或使用 Anaconda Jupyter 進行實作 ( 參考:使用 Anaconda ) ,並安裝 OpenCV 函式庫 ( 參考:OpenCV 函式庫 )。
OpenCV 的官方 Github 提供了許多訓練好的特徵模型,只需要下載後就能使用,請從下方網址進行下載,下載後將 xml 檔案和 Python 的程式檔放在同一層目錄下。
- OpenCV 官方 Github:https://github.com/opencv/opencv/tree/4.x/data
- 人臉特徵模型:haarcascade_frontalface_default.xml
將「人臉偵測」和「馬賽克效果」兩篇文章的範例結合,當影像中偵測到人臉時,透過 x、y 坐標和 w、h 長寬,就能定義馬賽克的位置和大小,下面的程式執行後,會自動將蒙娜麗莎的臉加上馬賽克。
import cv2
img = cv2.imread('mona.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 影像轉換成灰階
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") # 載入人臉偵測模型
faces = face_cascade.detectMultiScale(gray,1.2,3) # 開始辨識影像中的人臉
for (x, y, w, h) in faces:
mosaic = img[y:y+h, x:x+w] # 馬賽克區域
level = 15 # 馬賽克程度
mh = int(h/level) # 根據馬賽克程度縮小的高度
mw = int(w/level) # 根據馬賽克程度縮小的寬度
mosaic = cv2.resize(mosaic, (mw,mh), interpolation=cv2.INTER_LINEAR) # 先縮小
mosaic = cv2.resize(mosaic, (w,h), interpolation=cv2.INTER_NEAREST) # 然後放大
img[y:y+h, x:x+w] = mosaic # 將指定區域換成馬賽克區域
cv2.imshow('oxxostudio', img)
cv2.waitKey(0) # 按下任意鍵停止
cv2.destroyAllWindows()
如果有多張人臉,也可以順利偵測,並將偵測到的人臉加上馬賽克 ( 圖片為 Fusilamientos de Torrijos y sus compañeros en las playas de Málaga
)。
延伸「讀取並播放影片」文章的範例,搭配人臉偵測的方法,就可以即時偵測攝影鏡頭裡的人臉。
import cv2
cap = cv2.VideoCapture(0)
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
ret, frame = cap.read()
if not ret:
print("Cannot receive frame")
break
frame = cv2.resize(frame,(480,300)) # 縮小尺寸,避免尺寸過大導致效能不好
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 影像轉轉灰階
faces = face_cascade.detectMultiScale(gray) # 偵測人臉
for (x, y, w, h) in faces:
mosaic = frame[y:y+h, x:x+w]
level = 15
mh = int(h/level)
mw = int(w/level)
mosaic = cv2.resize(mosaic, (mw,mh), interpolation=cv2.INTER_LINEAR)
mosaic = cv2.resize(mosaic, (w,h), interpolation=cv2.INTER_NEAREST)
frame[y:y+h, x:x+w] = mosaic
cv2.imshow('oxxostudio', frame)
if cv2.waitKey(1) == ord('q'):
break # 按下 q 鍵停止
cap.release()
cv2.destroyAllWindows()
大家好,我是 OXXO,是個即將邁入中年的斜槓青年,我已經寫了超過 400 篇 Python 的教學,有興趣可以參考下方連結呦~ ^_^