【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 来操作图像数据。

相关推荐
Metaphor69239 分钟前
Python 自动化办公:如何轻松在 PDF 中导入与导出表单数据
python·pdf·自动化
拜小白6 小时前
【论文解读】DMH-Net:用深度曼哈顿霍夫变换从全景立方图估计3D房间布局
深度学习·计算机视觉·全景图
H.莓飛7 小时前
【数据结构】排序_OJ题(一):计数、桶与排序后的处理
java·开发语言·数据结构
wangchunyu1148 小时前
JAVA AQS与Lock实现原理(含CAS)
java·开发语言·word
爱喝水的鱼丶9 小时前
SAP-ABAP:ECC→S/4HANA ABAP 迁移升级指南——程序改造、语法兼容与性能优化 导语
运维·开发语言·性能优化·sap·abap·经验交流·开发交流
ViperL19 小时前
[智能计算]AutoDiffusion-基于进化NAS的扩散模型
人工智能·深度学习·计算机视觉
小灰灰搞电子9 小时前
Rust+Slint 实现FTP客户端调试助手源码分享
开发语言·后端·rust
外收内放9 小时前
面向对象高级(实战案例)
开发语言·python·学习
专业程序开发源10 小时前
springboot欧缇蔓月子中心管理系统82697-计算机课程设计、毕业设计
java·spring boot·后端·python·spring·django·课程设计
FPGA小迷弟10 小时前
用 Claude Code 重构遗留系统:从评估到落地的完整实践指南
c++·python·ai·plotly·django·ai编程·claude