炫酷!200 行 Python 代码实现马赛克拼图
在一图胜千言的时代 , 没有什么比一张图片更有冲击力的了 , 那如果一千张图片拼接起来是什么效果呢?
别问 , 问就是两字 —— 炫酷!
文章插图
文章插图
文章插图
你有没有想过上面的图片是怎么实现的 , 难道这是用 ps 一张张拼起来的?当然 , 靠人工把近千张图片按照色域一一排列 , 应该是不可能的 。
【炫酷!200 行 Python 代码实现马赛克拼图】今天我们就用 Python 做一个马赛克图片生成器~ 只需要 200 行 Python 代码 , 就可以将任意图片转化为马赛克拼图效果 , 一劳永逸!拿来记录校园生活、游戏生涯、送女朋友都最合适不过了!
文章插图
ONE
项目思路
项目大概分为 3 个步骤:
- 计算素材库中每张图片的平均色
- 把目标图片切分成平均的色块 , 与素材库图片进行替换
- 全部替换完成后 , 再与原始图像进行融合
文章插图
TWO
计算图像平均值
一张图像是通过许多的像素组成的 。 为了生成马赛克图片 , 我们的想法是 , 将原有图像的每一个小部分 , 使用颜色与这一小部分相似的图像进行替换 , 从而生成马赛克风格的图像 。
如何计算图片的颜色相似度?这里要引用 RGB 和 HSV 的概念 。
RGB 色彩空间是 , 由三个通道表示一幅图像 。 三个通道分别为红色 (R) , 绿色 (G) 和蓝色 (B) , 通过这三种颜色的不同组合 , 可以形成几乎所有的其他颜色 。
文章插图
但是 , 在自然环境下 , 图像容易受自然光照、遮挡等情况的影响 。 也就是人眼观察图片会对图片的亮度比较敏感 。 而 RGB 色彩空间的三个分量都与亮度密切相关 , 只要亮度改变 , RGB 颜色的三个分量都会改变.
同时 , 由于人眼对于这 RGB 这三种颜色的敏感程度是不一样的 。 在单色中 , 人眼对红色最不敏感 , 蓝色最敏感 , 所以 RGB 色彩空间是一种均匀性较差的色彩空间 。
由于 RGB 色彩空间不能方便的比较颜色之间的相似度 , 于是我们要使用 HSV 色彩空间 。 HSV 色彩空间也是由三个分量组成的 , 分别是:
- Hue(色调)
- Saturation (饱和度)
- Value (明度)
- H 用极坐标的极角表示;
- S 用极坐标的轴的长度表示;
- V 用圆柱的高度表示;
文章插图
计算图片 HSV 值的代码如下:
class mosaic(object):"""定义计算图片的平均hsv值"""def __init__(self, IN_DIR: str, OUT_DIR: str, SLICE_SIZE: int, REPATE: int,OUT_SIZE: int) -> None:self.IN_DIR = IN_DIR# 原始的图像素材所在文件夹self.OUT_DIR = OUT_DIR# 输出素材的文件夹, 这些都是计算过hsv和经过resize之后的图像self.SLICE_SIZE = SLICE_SIZE# 图像放缩后的大小self.REPATE = REPATE# 同一张图片可以重复使用的次数self.OUT_SIZE = OUT_SIZE# 最终图片输出的大小def resize_pic(self, in_name: str, size: int) -> Image:"""转换图像大小"""img = Image.open(in_name)img = ImageOps.fit(img, (size, size), Image.ANTIALIAS)return imgdef get_avg_color(self, img: Image) -> Tuple[float, float, float]:"""计算图像的平均hsv"""width, height = img.sizepixels = img.load()if type(pixels) is not int:data = http://kandian.youth.cn/index/[]# 存储图像像素的值for x in range(width):for y in range(height):cpixel = pixels[x, y]# 获得每一个像素的值data.append(cpixel)h = 0s = 0v = 0count = 0for x in range(len(data)):r = data[x][0]g = data[x][1]b = data[x][2]# 得到一个点的GRB三色count += 1hsv = rgb_to_hsv(r / 255.0, g / 255.0, b / 255.0)h += hsv[0]s += hsv[1]v += hsv[2]hAvg = round(h / count, 3)sAvg = round(s / count, 3)vAvg = round(v / count, 3)if count> 0:# 像素点的个数大于0return (hAvg, sAvg, vAvg)else:raise IOError("读取图片数据失败")else:raise IOError("PIL 读取图片数据失败")
以上内容出自实验楼免费课程 —— 《Python 制作马赛克拼合图像》 , 篇幅有限 , 欢迎大家来实验楼学习完整的课程代码 。
- 看不上|为什么还有用户看不上华为Mate40系列来看看内行人怎么说
- 智能手机市场|华为再拿第一!27%的份额领跑全行业,苹果8%排在第四名!
- 行业|现在行业内客服托管费用是怎么算的
- 痛点|首个OTA智能社区诞生 解决行业四大痛点
- 通气会|12月4~6日,2020中国信息通信大会将在成都举行
- 程序|2020全景生态流量秋季大报告:TOP100APP超半数布局小程序,全景流量重塑行业竞争新格局
- 同轴心配合|用SolidWorks画一个直角传动,画四个零件就行
- 无国界|嘴上说着支持华为,却为苹果贡献了2000亿!还真是科技无国界啊?
- 化妆产品|直播带货年入百万,这8个行业告诉你:是真的
- 王储|壹周游闻第20期:直播打赏实行实名制;沙特王储收购SNK