如何给一张图片打上马赛克呢?
马赛克原理
图像的马赛克效果是通过设置指定大小的像素块,并让这个像素块中的所有像素点设置为统一值来实现的。
方法一 手动制作马赛克
原理:这个过程有点像卷积的过程,如让这个像素块是10*10, 那么相当于卷积的步长strides=(10, 10),每次选取这个像素块左上角(当然可以是其他的任意点),让这个区域中的100个点和这个点的像素点都相同,便能实现马赛克的功能。
import cv2
def mosaic1(image, region=10):
h, w, _ = image.shape
for m in range(h - region):
for n in range(w - region):
# pixel ->10*10
if m % region == 0 and n % region == 0:
for i in range(0, region):
for j in range(0, region):
b, g, r = image[m, n]
image[i + m, j + n] = b, g, r
cv2.imshow('mosaic', image)
cv2.waitKey(0)
if __name__ == '__main__':
img = cv2.imread('lenna.png', 1)
mosaic1(img)
效果
原图
马赛克图
可以调整region的大小来设置马赛克的粒度,当然如果region=1的时候其实就是没有马赛克效果。
方法二 先缩小再放大产生马赛克
原理:先将图片缩小,然后放大,便形成了将一个像素块设置成相同像素值一样的效果,但是此处最好采用最近邻插值法放大图片,如果用双线性插值变会形成平滑的效果,相当于仅仅是模糊的效果,并没有形成成块状的马赛克效果。
import cv2
def mosaic2(image, step=10, interpolation=0):
h, w, _ = image.shape
image2 = cv2.resize(image, (w // step, h // step))
image3 = cv2.resize(image2, (w, h), interpolation=interpolation)
cv2.imshow('mosaic', image3)
cv2.waitKey(0)
if __name__ == '__main__':
img = cv2.imread('lenna.png', 1)
mosaic2(img)
马赛克图
可以看到和第一种效果基本一致。