上一期,我们分享了如何给图片添加马赛克,但是很多时候,我们需要给视频添加马赛克。当然,你能想到的是后处理软件的方法。本文教你通过使用几行简单的代码,方便地给视频添加马赛克
上一期,我们分享了如何给图片添加马赛克,但是很多时候,我们需要给视频添加马赛克。当然,你能想到的是后处理软件的方法。本文教你通过使用几行简单的代码,方便地给视频添加马赛克。
添加镶嵌步骤1.给定要添加的视频或图片
2.利用人工智能技术识别图片或视频中的人脸。
3.创建一个屏蔽层。
4.为图片或视频添加屏蔽层。
5.显示最终图片或将其实时同步到视频。
创建屏蔽层要给图片或视频人脸添加马赛克,最重要的一步是创建屏蔽层。我们用两种方法对人脸进行编码。
将numpy作为np导入
导入cv2
def face_blur(图像,因子=3.0):
(h,w) = image.shape[:2]
kW = int(w /系数)
KH = int(h/factor) #高斯核
如果kW % 2 == 0:
千瓦-= 1
如果kH % 2 == 0:
kH -= 1
返回cv2。GaussianBlur(image,(kW,kH),0)
上面是一个非常简单的代码来创建一个屏蔽层。
首先,我们得到图片的大小(h,w) = image.shape[:2]
要使用高斯运算,我们需要计算高斯核的大小。
kW = int(w /系数)
kH = int(h /因子)
高斯核的基本大小如上计算。只要高斯核的大小是奇数,我们检测基数的时候就需要改成奇数。最后用cv2.gaussianblur (image,(kw,KH),0)创建屏蔽层。
高斯函数高斯滤波器是一种线性平滑滤波器,对于去除高斯噪声有很好的效果。
图像处理中高斯滤波的实现方式一般有两种:一种是与离散窗卷积,另一种是傅里叶变换。最常见的是第一个滑动窗口实现。只有当离散化窗口很大,滑动窗口的计算量很大时,才会考虑基于傅立叶变换的方法。
Opencv为高斯滤镜图形提供了GaussianBlur()函数,其原型如下:
c++:void Gaussian blur(input array 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:高斯核大小,与前面两个滤波器核大小不同。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()函数。
。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 = & # 8221int & # 8221)
ySteps = np.linspace(0,h,blocks + 1,dtype = & # 8221int & # 8221)
对于范围内的I(1,len(ySteps)):
对于范围(1,len(xSteps))中的j:
startX = x steps[j –1]
startY = y steps[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)
返回图像
首先获取图片的大小,将图片分成block*block的小方块。
计算每个小方块的初始位置和最终位置。
从每个小正方形图片中提取ROI =图像[starty: endy,startx: endx]
Opencv封装了一个专门求解cv::Mat均值的函数,即CV:: Mean (& Cv::Mat),这个函数会得到Mat中每个通道的均值。如果想得到指定通道的平均值,可以做进一步的分析。
最后把获取的平均值画到原始图片中,来实现加马赛克的效果
最后将得到的平均值绘制到原图中,实现拼接效果。
马赛克
函数中的块定义了图像中需要镶嵌的小块的数量。上图中的马赛克和我们看到的非常相似。
加载模型并打开摄像机。prototxtFacePath = & # 8220model/deploy . proto txt ”
weightsFacePath = & # 8220型号/res10 _ 300 x300 _ SSD _ ITER _ 140000 . caffemodel ”
faceNet = cv2 . dnn . readnet(prototxtFacePath,weightsFacePath)
捕获= cv2。视频捕获(0)
时间.睡眠(2.0)
首先,我们加载所需的人脸检测模型。
使用cv2 . dnn . readnet(prototype face path,weightfacepath)函数来初始化用于人脸检测的神经网络。
VideoCapture()中的参数为0,表示开启笔记本内置摄像头。如果参数是视频文件的路径,视频就会打开,比如cap = cv2.videocapture(“../HD.avi”)。
打开默认摄像头,然后遍历视频并实时添加马赛克。
实时读取视频帧并检测人脸。虽然正确:
ret,frame = capture.read()
frame = cv2.resize(frame,(600,400))
(h,w) = frame.shape[:2]
blob = cv2 . dnn . blobfromimage(frame,1.0,(300,300),(104.0,177.0,123.0))
faceNet.setInput(blob)
detections = faceNet.forward()
Cap.read()逐帧读取视频,ret和frame是cap.read()方法的两个返回值。其中ret是一个布尔值,如果读取的帧是正确的,则返回True,如果文件读取到末尾,则返回False。Frame是每一帧的图像,是一个三维矩阵。
获取图片的大小,然后从image (image,1.0,(300,300),(104.0,177.0,123.0))计算图片的blob值blob = cv2.dnn.blob
最后,对人脸神经网络进行预测。
faceNet.setInput(blob)
detections = faceNet.forward()
当检测到面部时,面部被分析和识别。
对于范围内的I(0,detections.shape[2]):
置信度=检测次数[0,0,I,2]
如果信心& gt0.5:
box =检测[0,0,I,3:7] * np.array([w,h,w,h])
(startX,startY,endX,endY)= box . as type(“int & # 8221)
face = frame[startY:endY,startX:endX]
face = face_blur(face,factor=4.0)
frame[startY:endY,startX:endX] = face
检测人脸时,提取所有人脸的置信度,我们判断置信度大于0.5的人脸为可靠人脸。
计算人脸在图片中的位置(startx,starty,endx,endy)= box . as type(“int & # 8221)
获取人脸图片ROI: face = frame [starty: endy,startx: endx]
根据人脸的ROI图片进行高斯模糊,从而达到添加马赛克的效果。
然后,将拼接的画面实时反馈到视频帧中。
显示视频cv2 . im show(“框架”框架)
key = cv2 . wait key(1)&0xFF
if key = = ord(“q & # 8221):
破裂
cv2.stop()
cv2.destroyAllWindows()
最后实时显示视频。