随着抖音帶貨的火熱,很多人開始加入了自媒體時代的潮流。由于很多人都不是專業演員出身,當拍視頻的時候,或多或少有點不适應,好不容拍好的視頻,由于不願意露臉,又不會添加馬賽克,幸苦拍好的視頻也不願意發出去。畢竟很多人也不會進行視頻制作,更别說視頻添加馬賽克了。
本文利用人工智能技術,給圖片或者視頻添加馬賽克,避免自己出鏡的尴尬,再也不用擔心朋友圈屏蔽老爸老媽了。
添加馬賽克步驟
1、給定要添加的視頻或者圖片
2、利用人工智能技術識别圖片或者視頻中的人臉
3、創建屏蔽層
4、給圖片或者視頻添加上屏蔽層
5、顯示最終的圖片或者實時同步到視頻 中
給圖片或者視頻人臉添加馬賽克,最主要步驟是創建屏蔽層,我們利用2種方式進行人臉的打碼
import numpy as np
import cv2
def face_blur(image, factor=3.0):
(h, w) = image.shape[:2]
kW = int(w / factor)
kH = int(h / factor) #高斯内核
if kW % 2 == 0:
kW -= 1
if kH % 2 == 0:
kH -= 1
return cv2.GaussianBlur(image, (kW, kH), 0)
以上便是很簡單的創建屏蔽層的代碼
首先我們獲取了圖片的尺寸(h, w) = image.shape[:2]
利用要使用高斯運算,我們要計算高斯内核的尺寸
kW = int(w / factor)
kH = int(h / factor)
以上計算了高斯内核的基本尺寸,由于高斯内核的尺寸隻要求是奇數,當我們檢測到基數時,需要轉成為奇數。最後使用cv2.GaussianBlur(image, (kW, kH), 0)來創建屏蔽層
高斯函數高斯濾波是一種線性平滑濾波,對于除去高斯噪聲有很好的效果。
在圖像處理中高斯濾波一般有兩種實現方式:一種是用離散化窗口滑窗卷積,另一種是通過傅裡葉變換。最常見的就是第一種滑窗實現,隻有當離散化的窗口非常大,用滑窗計算量非常大的情況下會考慮基于傅裡葉變換的方法。
opencv提供了GaussianBlur()函數對圖形進行高斯濾波,其原型如下:
C : void GaussianBlur(InputArray src, outputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT )
參數解釋:
. InputArray src: 輸入圖像,可以是Mat類型,圖像深度為CV_8U、CV_16U、CV_16S、CV_32F、CV_64F。
. OutputArray dst: 輸出圖像,與輸入圖像有相同的類型和尺寸。
. Size ksize: 高斯内核大小,這個尺寸與前面兩個濾波kernel尺寸不同,ksize.width和ksize.height可以不相同但是這兩個值必須為正奇數,如果這兩個值為0,他們的值将由sigma計算。
. double sigmaX: 高斯核函數在X方向上的标準偏差
. double sigmaY: 高斯核函數在Y方向上的标準偏差,如果sigmaY是0,則函數會自動将sigmaY的值設置為與sigmaX相同的值,如果sigmaX和sigmaY都是0,這兩個值将由ksize.width和ksize.height計算而來。具體可以參考getGaussianKernel()函數查看具體細節。建議将size、sigmaX和sigmaY都指定出來。
. int borderType=BORDER_DEFAULT: 推斷圖像外部像素的某種便捷模式,有默認值BORDER_DEFAULT,如果沒有特殊需要不用更改,具體可以參考borderInterpolate()函數。
高斯屏蔽
自建馬斯克圖像高斯函數的馬賽克十分平滑,但是這跟我們平時見到的馬斯克有所區别,我們新建一個函數來創建自己的馬斯克
def face_blur(image, blocks=5):
(h, w) = image.shape[:2]
xSteps = np.linspace(0, w, blocks 1, dtype="int")
ySteps = np.linspace(0, h, blocks 1, dtype="int")
for i in range(1, len(ySteps)):
for j in range(1, len(xSteps)):
startX = xSteps[j - 1]
startY = ySteps[i - 1]
endX = xSteps[j]
endY = ySteps[i]
ROI = image[startY:endY, startX:endX]
(B, G, R) = [int(x) for x in cv2.mean(roi)[:3]]
cv2.rectangle(image, (startX, startY), (endX, endY),(B, G, R), -1)
return image
首先獲取了圖片的尺寸,把圖片分成block*block的小方塊
計算每個小方塊的初始位置與最終位置
把每個小方塊圖片提取roi = image[startY:endY, startX:endX]
opencv中封裝了一個專門用于求解cv::Mat均值的函數,即cv::mean(&cv::Mat),該函數會得到Mat中各個通道的均值,若要獲取指定通道的均值,做進一步解析即可。
最後把獲取的平均值畫到原始圖片中,來實現加馬賽克的效果
馬賽克
函數中的blocks定義了圖片需要進行馬賽克的小方塊的數量,以上圖片的馬賽克跟我們見到的很是類似
加載模型,檢測圖片有了以上的添加屏蔽層的代碼,便可以加載模型來進行圖片的處理了
prototxtFacePath = "model/deploy.prototxt"
weightsFacePath = "model/res10_300x300_ssd_iter_140000.caffemodel"
faceNet = cv2.dnn.readNet(prototxtFacePath, weightsFacePath)
image = cv2.imread("image/img1.jpg")
orig = image.copy()
(h, w) = image.shape[:2]
blob = cv2.dnn.blobFromImage(image, 1.0, (300, 300),(104.0, 177.0, 123.0))
faceNet.setInput(blob)
detections = faceNet.forward()
首先加載人臉檢測模型
對人臉模型進行初始化faceNet = cv2.dnn.readNet(prototxtFacePath, weightsFacePath)
獲取圖片的尺寸大小,然後進行圖片blob值的計算blob = cv2.dnn.blobFromImage(image, 1.0, (300, 300),(104.0, 177.0, 123.0))
最後進行人臉神經網絡的預測f
aceNet.setInput(blob)
detections = faceNet.forward()
for i in range(0, detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > 0.5:
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
face = image[startY:endY, startX:endX]
face = face_blur(face, factor=3.0)
# face1 = face_blur(face,blocks=5)
image[startY:endY, startX:endX] = face
output = np.hstack([orig,image])
cv2.imshow("Output", output)
cv2.waitKey(0)
當檢測到人臉後,提取所有人臉的置信度,我們判斷大于0.5的人臉置信度為可靠人臉.
計算人臉在圖片中的位置(startX, startY, endX, endY) = box.astype("int")
獲取人臉圖片ROI:face = image[startY:endY, startX:endX]
根據人臉的ROI圖片來進行高斯模糊,以便達到添加馬賽克的效果
最後把馬賽克圖片合并到原始圖片中
mask
你還以為很多視頻中的馬賽克是後期處理添加上的嗎??下期帶你看如何為視頻實時添加mask,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!