實(shí)時“人臉”模糊!實(shí)戰(zhàn)教程
大家好,今天跟大家分享一個實(shí)戰(zhàn)的教程。
老規(guī)矩,先看效果(明確一下目標(biāo)):
隨著人臉識別技術(shù)的發(fā)展,給我們的日常生活帶來了許多的便利,但是同樣的也存在隱私的問題。以及可能被不法分子用于做一些違法事情。
所以很多視頻博主,都會給路人打碼。但是手動打碼是一件非常繁瑣的事情,對于單幀圖片還算簡單,但是假設(shè)視頻的幀率是 25FPS,即一秒中有25幀圖片,那么一個幾分鐘的視頻,其工作量也非常的可怕。
因此我們嘗試使用程序自動去執(zhí)行這樣子的操作!
我們可以使用Opencv、Mediapipe和Python,實(shí)現(xiàn)實(shí)時模糊人臉。
我們可以分兩步完成:
- 在打碼之前,首先確定人臉位置
- 取出臉,模糊它,然后將處理后的人臉放回到視頻幀中(視頻處理類似)
(留個作業(yè):如何實(shí)現(xiàn)對除了本人以外的其他人打碼?)
1、在打碼之前,首先確定人臉位置
老規(guī)矩,首先配置一下環(huán)境,安裝必要的庫(OpenCV 和 MediaPipe)
pip install opencv-python
pip install mediapipe
在 MediaPipe 庫中提供了人臉關(guān)鍵點(diǎn)檢測的模塊。
詳細(xì)的內(nèi)容可以參考:https://google.github.io/mediapipe/solutions/face_mesh.html
當(dāng)然在該項目的代碼中,也提供人臉關(guān)鍵點(diǎn)檢測的代碼。
“facial_landmarks.py”的文件:
人臉關(guān)鍵點(diǎn)檢測效果圖
下面我們就一起來寫一下這部分的代碼:
- 首先導(dǎo)入必要的庫以及用于人臉關(guān)鍵點(diǎn)檢測的模塊:
import cv2
import mediapipe as mp
import numpy as np
from facial_landmarks import FaceLandmarks
# Load face landmarks
fl = FaceLandmarks()
- 然后使用檢測出來的人臉關(guān)鍵點(diǎn)最外圍的一圈關(guān)鍵點(diǎn)繪制一個多邊形(臉部輪廓)。這里使用opencv 中的convxhull() 函數(shù)可以實(shí)現(xiàn):
# 1. Face landmarks detection
landmarks = fl.get_facial_landmarks(frame)
convexhull = cv2.convexHull(landmarks)
繪制完成后的結(jié)果如下所示:
之后使用上面所提取到的人臉關(guān)鍵點(diǎn)坐標(biāo)創(chuàng)建mask,用提取我們在視頻幀中感興趣的區(qū)域:
# 2. Face blurrying
mask = np.zeros((height, width), np.uint8)
# cv2.polylines(mask, [convexhull], True, 255, 3)
cv2.fillConvexPoly(mask, convexhull, 255)
結(jié)果如下所示:
得到這個mask,我們就可以進(jìn)一步對人臉進(jìn)行模糊(打碼)處理。
打碼的操作,這里使用的是OpenCV 中的cv2.blur() 函數(shù):
# Extract the face
frame_copy = cv2.blur(frame_copy, (27, 27))
face_extracted = cv2.bitwise_and(frame_copy, frame_copy, mask=mask)
結(jié)果:
目前,我們已經(jīng)實(shí)現(xiàn)對人臉進(jìn)行打碼操作,剩下的就是對人臉以外的區(qū)域進(jìn)行提取,并合并成最終的結(jié)果即可!
對人臉以外的區(qū)域進(jìn)行提?。ū尘埃瑢?shí)際上對上面的mask 進(jìn)行取反即可。
背景提?。?/p>
# Extract background
background_mask = cv2.bitwise_not(mask)
background = cv2.bitwise_and(frame, frame, mask=background_mask)
從圖像的細(xì)節(jié)可以看出,背景是完全可見的,但面部區(qū)域已經(jīng)變成黑色了。這是我們將在下一步中應(yīng)用模糊人臉的空白區(qū)域。
最后一步,將上面兩步獲取的人臉mask 和背景進(jìn)行相加即可,這里使用cv2.add() 即可實(shí)現(xiàn)我們的目標(biāo):
# Final result
result = cv2.add(background, face_extracted)
結(jié)果:
這是對一幀圖片進(jìn)行處理。
2、取出臉,模糊它,然后將處理后的人臉放回到視頻幀中
上面的操作都是在單幀圖片上進(jìn)行處理的,如果我們需要出來的是視頻的話,其實(shí)原理是完全一樣的,只不過是將一個視頻拆成一系列的圖片即可。
稍微做一些修改:
(1)輸入文件 (圖片 ---> 視頻)
cap = cv2.VideoCapture("person_walking.mp4")
(2)對輸入的視頻幀,做一個循環(huán)遍歷:
while True:
ret, frame = cap.read()
frame = cv2.resize(frame, None, fx=0.5, fy=0.5)
frame_copy = frame.copy()
height, width, _ = frame.shape
...