首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

利用Python生成马赛克艺术画作

马赛克画是一张由小图拼成的大图,我们的效果图,放大看细节,每一块都是一张独立的图片,拼在一起组成一张大图,感觉像是用马赛克拼出来的画,所以叫马赛克画。看到网上的一些马赛克画觉得很酷,于是自己用Python实现了一下将一张原图转换成马赛克画。

我们的效果图是这样的

原图是这样的

Python学习资料或者需要代码、视频加这个群吧,516加上107还有834 都在这里了

总之就是516107834

实现的具体思路是这样

第一步:首先收集一组图片,这些图片会作为大图中的小方格图片。图片越多,最后生成的图片颜色越接近。

第二步:将要转换的图片分割成一个一个小方格图片,像下面这样

第三步:对于每一个小方格图片,取图片集里面最接近的图片替换。所有小方格都替换后,就生成了我们最终的马赛克画。

听上去是不是很简单?

我们来看一下具体的实现步骤,下面是一些核心代码。

我们的图片集存在images目录下,下面的代码加载目录下所有的图片,并缩放成统一的尺寸

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数组,这里我们将三维数组转换成一维数组后,比较两者的欧式距离。之后要找出最相似的图片,只需遍历图片集中所有的图片,找到距离最短的那张图片,去替换原图中的小方格就可以了。

我们再来看一下最终实现的效果

放大图中局部的细节如下

如果对图片的画质不满意,想要更精细的画质,可以考虑在分割的时候把图片分割成更小的方格,不过这样也会增加程序运行的时间。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181025A132EM00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券