使用Python编程制作马赛克真是太酷了~
马赛克就是由小图片组成的大图片。本文的封面是我们的渲染图。放大查看细节。每幅作品都是一个独立的图像。它们组合在一起,形成了一幅大图,感觉像马赛克画,所以被称为马赛克画。我在网上看到一些马赛克,觉得很酷,所以我用Python将原始图像转换为马赛克。
原来的封面图是这样的。 。图像越多,最终创建的图像的颜色就越接近。
第2步:将要转换的图像划分为小正方形图像,如下所示
第3步:对于每个小正方形图像,将其替换为一系列图像中最接近的图像。当所有小方块都被替换后,最终的马赛克就创建好了。
听起来是不是很简单?
我们来看看具体的实现步骤。下面是基本代码。完整代码可以后台回复“马赛克”公众号【Python与数据分析】获取。
我们的图像集合存储在图像目录中。下面的代码加载目录下的所有图片,并缩放为统一大小
import re
import os
import cv2
import numpy as np
from tqdm import tqdm
IMG_DIR = "images"
def load_all_images(tile_row, tile_col):
img_dir = IMG_DIR
filenames = os.listdir(img_dir)
result = []
print(len(filenames))
for filename in tqdm(filenames):
if not re.search(".jpg", filename, re.I):
continue
try:
filepath = os.path.join(img_dir, filename)
im = cv2.imread(filepath)
row = im.shape[0]
col = im.shape[1]
im = resize(im, tile_row, tile_col)
result.append(np.array(im))
except Exception as e:
msg = "error with {} - {}".format(filepath, str(e))
print(msg)
return np.array(result, dtype=np.uint8)
这里的Load_all_images函数的参数都是统一大小。 tile_row和tile_col对应于高度和宽度。 。
下面的代码对要转换的图像进行分割
img = cv2.imread(infile)
tile_row, tile_col = get_tile_row_col(img.shape)
for row in range(0, img_shape[0], tile_row):
for col in range(0, img_shape[1], tile_col):
roi = img[row:row+tile_row,col:col+tile_col,:]
我们将要转换的图像分割成小方块。 tile_row 和tile_col 是小方块的高度和宽度。 roi 在小方块中使用图片。信息。
下面是计算两幅图像相似度的函数
from scipy.spatial.distance import euclidean
def img_distance(im1, im2):
if im1.shape != im2.shape:
msg = "shapes are different {} {}".format(im1.shape, im2.shape)
raise Exception(msg)
array1 = im1.flatten()
array2 = im2.flatten()
dist = euclidean(array1, array2)
return dist
im1和im2是两幅图像的数据。图像数据是一个三维numpy数组。这里我们将三维数组转换为一维数组并比较两者。欧几里得距离。要找到最相似的图像,只需遍历图像集合中的所有图像,找到距离最短的图像,并替换原始图像的小方块即可。
来看看最终效果
放大图像中的局部细节如下
如果您对图像质量不满意,想要更精确的图像质量,可以考虑将图像分割成更小的方块分割时,但这也会增加程序的运行时间。
创建图片需要时间。出于性能考虑,原程序采用多进程并行处理。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。