【Python 项目】照片马赛克 - 1

照片马赛克 - 1

照片马赛克是一张图像,它被分割成长方形的网格,每个长方形由另一张匹配"目标"的图像(最终希望出现在照片马赛克中的图像)替代。换言之,如果从远处看照片马赛克,会看到目标图像;但如果走近,会看到该图像实际上包含许多较小的图像。这个迷题有解是因为人眼的工作方式。下图中的低分辨率块状图像,靠近了很难识别,但如果从远处看,就知道它代表什么,因为看到的细节较少,就使得边缘越光滑。照片马赛克的原理是相似的。从远处看,图像看起来正常,但走近时,秘密揭开了:每"块"都是一个独特的图像!

开始

本项目中,我们将学习如何用 Python 创建照片马赛克。我们将目标图像划分成较小图像的网格,并用适当的图像替换网格中的每一小块,创建原始图像的照片马赛克。你可以指定网格的尺寸,并选择输入图像是否可以在马赛克中重复使用。

在这个项目中,你将学习如何做到以下几点:

  • 用 Python 图像库(PIL)创建图像;
  • 计算图像的平均 RGB 值;
  • 剪切图像;
  • 通过粘贴另一张图像来替代原图像的一部分;
  • 利用平均距离测量来比较 RGB 值。

工作原理

要创建照片马赛克,就从目标图像的块状低分辨率版本开始(因为在高分辨率的图像中,小块图像的数量会太大)。该图像的分辨率将决定马赛克的维度 M×N(M 是行数,N 是列数)。接着,根据这种方法替换原始图像中的每一小块:

  1. 读入一些小块图像,它们将取代原始图像中的小块;
  2. 读入目标图像,将它分割成 M×N 的小块网格;
  3. 对于每个小块,从输入的小块图像中找到最佳匹配;
  4. 将选择的输入图像安排在 M×N 的网格中,创建最终的照片马赛克。

分割目标图像

按照下图中的方案,开始将目标图像划分成 M×N 的网格。

图像展示了如何将原始图像分割成小块的网格。 x 轴表示网格的列,y 轴表示网格的行。

现在,看看如何计算网格中一个小块的坐标。下标为(i,j)的小块,左上角坐标为 (iw, ij),右下角坐标为((i+1)*w, (j+1)*h),其中 w 和 h 分别是小块的宽度和高度。PIL 可以用这些数据,从原图像创建小块。

平均颜色值

图像中的每个像素都有颜色,由它的红、绿、蓝值来表示。在这个例子中,使用 8 位的图像,因此每个部分有 8 位值,范围在0,255。如果一幅图像共有 N 个像素,平均 RGB 计算如下:
r , g , b { r 1 + r 2 + . . . + r n N , g 1 + g 2 + . . . + g n N , b 1 + b 2 + . . . + b n N } r,g,b \left\{\begin{aligned} \end{aligned} \right.\frac{r_1+r_2+...+r_n} {N}, \frac{g_1+g_2+...+g_n}{N}, \frac{b_1+b_2+...+b_n}{N}\left.\begin{aligned} \end{aligned}\right\} r,g,b{Nr1+r2+...+rn,Ng1+g2+...+gn,Nb1+b2+...+bn}

请注意,平均 RGB 也是一个三元组,不是标量或一个数字,因为平均值是针对每个颜色成分分别计算的。计算平均 RGB 是为了匹配图像小块和目标图像。

匹配图像

对于目标图像中的每个小块,需要在用户指定的输入文件夹的一些图像中,找到一幅匹配的图像。要确定两个图像是否匹配,就使用平均 RGB 值。最接近的匹配就是最接近平均 RGB 值的图像。

要做到这一点,最简单的方法是计算一个像素中 RGB 值之间的距离,以便从输入图像中找到最佳匹配。对于几何中的三维点,可以用以下的距离计算方法:
D 1 , 2 = ( r 1 − r 2 ) 2 + ( g 1 − g 2 ) 2 + ( b 1 − b 2 ) 2 D_1,_2 = \sqrt { (r_1 - r_2)^2 + (g_1 - g_2)^2 + (b_1 - b_2)^2 } D1,2=(r1−r2)2+(g1−g2)2+(b1−b2)2

这里计算了点 (r1, g1, b1) 和 (r2, g2, b2) 之间的距离。给定一个目标图像的平均RGB 值,以及来自输入图像的平均 RGB 值列表,你可以使用线性搜索和三维点的距离计算,来找到最匹配的图像。

所需模块

这个项目将使用 Pillow 读入图像,访问其底层数据,创建和修改图像。还会用numpy 来操作图像数据。

相关推荐
legendary_163几秒前
PD‑SINK芯片在无协议后端负载中的工程应用
c语言·开发语言·人工智能·智能手机·计算机外设
Nuanyt3 分钟前
JVM常见核心知识梳理02 类加载 字节码技术 双亲委派 Java内存模型 JMM 并发底层 volatile synchronized 常见排障与调优工具
java·开发语言·jvm
YOLO数据集集合17 分钟前
福寿螺目标检测数据集 | 福寿螺检测 入侵物种 农业植保 目标检测9062期
人工智能·yolo·目标检测·计算机视觉·福寿螺·福寿螺检测·入侵物种
深度学习lover19 分钟前
<数据集>电力劳保穿戴识别<目标检测>
人工智能·yolo·目标检测·计算机视觉·数据集·电力劳保穿戴识别
liliangcsdn20 分钟前
IC计算-前向/远期收益计算和代码示例
开发语言·python·pandas
2601_9623818632 分钟前
python安装好了如何设置环境变量
python·开发工具·环境变量·虚拟环境·ide配置
小溪学编程35 分钟前
Java ListIterator 接口详解:双向遍历与列表修改的利器
java·开发语言·windows
影视飓风TIM35 分钟前
C++11 新特性:Lambda表达式、std::function与std::bind
开发语言·c++
sbjdhjd40 分钟前
在 8 字符、字母数字过滤与 PHP 版本差异下复盘临时文件命令执行链 | (8字符绕过)
android·java·开发语言·安全·web安全·数据挖掘·php
小柯南敲键盘42 分钟前
跨马翻译:跨境电商图片翻译工具,批量处理视频字幕与抠图
python·音视频