马赛克算法原理
在平常的生活中,我们会经常看到各种马赛克,比如某些宅男硬盘里的视频马赛克,有些直播犯罪嫌疑人的头像遮罩马赛克等。可以说在生活中,马赛克无处不在。
因此,我们在学习OpenCV的同时,也要熟练掌握马赛克的应用。下面,我们来了解马赛克算法的几种实现原理:
1.将需要马赛克的图像部位,全部赋值为该区域左上角的第一个像素值
2.将需要马赛克的图像部位像素随机打乱
3.随机用某一点代替需要马赛克区域内的所有像素值。
本篇将详细介绍马赛克的处理操作。
实现图片中的马赛克
这里,我们使用3实现原理,通过随机用某一点代替需要马赛克区域内的所有像素值。具体代码如下所示:
#马赛克操作 def mosaic_effect(img): new_img = img.copy() h, w, n = img.shape size = 10#马赛克大小 for i in range(size, h - 1 - size, size): for j in range(size, w - 1 - size, size): i_rand = random.randint(i - size, i) j_rand = random.randint(j - size, j) new_img[i - size:i + size, j - size:j + size] = img[i_rand, j_rand, :] return new_img if __name__ == "__main__": img = cv2.imread("49.jpg") cv2.imshow("0", img) cv2.imshow("1", mosaic_effect(img)) cv2.waitKey() cv2.destroyAllWindows()
可以看到,我们代码中设置的马赛克大小为10,在这个区域内,随机取一个像素点,将所有的像素都设置成该随机选取的像素值,这样就达到了马赛克的目的。而且对于原图来说,轮廓看起来还是没有变化的。效果如下:
跟踪视频人脸,将人脸用马赛克遮挡
直接实现图片中的马赛克好像有点简单,我们不妨结合前文的捕捉摄像头的知识以及人脸检测知识,将马赛克用于视频之中。话不多说,我们直接上代码:
# 将视频中的人脸替换成马赛克 def mosaic_video_effect(img): height, width, n = img.shape new_img = img.copy() size = 20 faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale(gray, scaleFactor=1.15, minNeighbors=2, minSize=(5, 5)) for (x, y, w, h) in faces: for i in range(x + size, (x + w) - 1 - size, size): for j in range(y + size, (y + h) - 1 - size, size): if i - size > 0 and j + size < width and i + size < height and j - size > 0: i_rand = random.randint(i - size, i) j_rand = random.randint(j - size, j) new_img[i - size:i + size, j - size:j + size] = img[i_rand, j_rand, :] else: new_img[x:x + w, y:y + h] = [255, 255, 255] return new_img if __name__ == "__main__": cap = cv2.VideoCapture(0) while (cap.isOpened()): ret, frame = cap.read() frame = mosaic_video_effect(frame) cv2.imshow('video', frame) c = cv2.waitKey(1) if c == 27: break cap.release() cv2.destroyAllWindows()
这里需要注意的是,因为我们只部分遮挡人脸,所以并不是全屏马赛克,而当人脸移动到摄像头边缘时,这个时候i - size,j-size可能小于0,j + size,i + size可能大于宽度高度,将导致数组越界报错。所以,为了避免人脸在边缘时,越界赋值,我们判断在边缘时直接遮挡白色马赛克即可。