ImageMagick 示例 --
数字照片处理

索引
ImageMagick 示例前言和索引
数码相机元数据,EXIF 信息
数字照片方向
颜色改进
照片转换食谱
ImageMagick 的主要用途之一是处理和修改用新型现代数码相机拍摄的照片。这些相机通常拍摄相当大、高分辨率的照片,并且包含关于时间、比例、缩放、相机、方向等的元数据。甚至还有计划将相机连接到移动电话,以便它甚至可以猜测你拍摄照片时身在何处以及照片中可能有哪些人(从它前面有哪些移动电话)。在这里,我们看看处理数字照片的基础知识,甚至将它们转换为其他目的,例如艺术渲染。特别感谢数码相机用户 Walter Dnes 在数字照片增强方面提供的帮助。

数码相机元数据,EXIF 信息

当数码相机拍摄照片时,它还会在 JPEG 保存文件中包含大量额外的信息。这些元数据被称为 EXIF 信息,专门为摄影实验室和开发提供。ImageMagick 的 "magick identify" 以及 "-verbose" 设置将显示此 Exif 信息。以下是我拍摄的 中国南部昆明动物园的宝塔 的照片的 EXIF 数据。

  magick identify -format "%[EXIF:*]" pagoda_sm.jpg |\
      sed 's/\(.\{46\}\).*/\1/' | column -c 110
[IM Text]
EXIF 数据或任何标识输出应以不区分大小写的方式处理。例如,许多较旧版本的 IM 将输出 "EXIF:"(大写)而不是 "exif:"(小写)。
这是一个类似的示例,但使用 'globbing'(类似 shell)表达式将输出限制为涉及时间的 EXIF 字段...

  magick identify -format "%[exif:*time*]" pagoda_sm.jpg
[IM Text]
EXIF 信息中包含很多关于这张照片的信息。例如
  • 我的相机是松下 ('Make'),DMC-LZ1 ('Model')
  • 相机已旋转 ('Orientation')。但我一定是在没有调整 EXIF 数据的情况下校正了旋转。相机也略微向上倾斜,但该信息未记录。
  • 'FocalLength' 为 '37mm' 表明我没有使用相机的 '光学变焦' 功能。我的相机可以进行高达 6 倍的光学变焦,'FocalLength' 为 '366/10' 或 '222mm'。
  • 而 'DigitalZoomRatio' 表明我也没有进行数字变焦。
  • 相机还使用了 1/8 秒的快速 'ExposureTime',光圈 'MaxApertureValue' 为 3mm,或 'FNumber' 为 '5.6','ISOSpeedRating' 为 '64'。
  • 没有使用闪光灯 ('LightSource')。
  • 原始图像为 1728 x 2304 像素 ('ExifImageLength' 和 'ExifImageWidth')。虽然实际的图像(如果你想检查一下)更小,所以我一定裁剪过和/或调整过它的大小。
  • 可能最重要的是,它是在 2005 年 7 月 9 日下午 14:05 左右拍摄的,根据 'DateTime' 字符串。这假设我已正确设置了相机的时钟(确实如此)。
  • 更现代的相机甚至可能具有 GPS 位置和可能的视图指南针方向!
此外,还包括但未列出上述内容的是相机在其自身显示屏上使用的小型 '缩略图' 预览图像。此外还有功能可以标记你想要由照相打印机 '冲印' 或打印的照片,以及调整其他打印参数。然而,大多数人很少使用这些功能。许多这些设置对用户来说可能非常有用,但对人们来说最有用的是照片的日期和时间。当然,这假设在拍摄照片之前在相机上正确设置了日期和时间。此外,许多人对图像的方向感兴趣,以便在显示时可以正确旋转。也就是说,我们将要讨论的下一个内容。所有这些数据,尤其是预览图像,可能会占用图像中相当大的空间。而且我可能不希望全世界都知道我在 2005 年 7 月身处中国昆明。因此,你可能希望在将图像实际发布到万维网上之前从图像中删除 EXIF 数据。此外,来自数码相机的图像的大小通常非常大(并且越来越大),允许你以照片质量级别打印它,但对于 WWW 的使用来说太大,尤其是对于缩略图来说太大。因此,除非你希望用户能够实际打印照片质量的图像,否则我不建议直接发布原始图像。例如,上面的图像已被裁剪并调整大小以供 IM 示例使用,但我故意保留了 EXIF 数据以供示例使用。通常我会删除这些信息。

数字照片方向

我听说 Photoshop 会根据 EXIF 'Orientation' 设置自动旋转数字图像,IM 也会通过在读取图像后包含 "-auto-orient" 运算符来实现。但是,这一点很重要
JPEG 格式是有损的
这意味着,只要你解码并保存 JPEG 文件格式,图像就会略微劣化。作为通用图像处理器,IM 将始终完全解码和重新编码格式,因此,在重新保存图像时,它将始终使 JPEG 图像劣化。有关 JPEG 格式性质的更多信息,请参阅 JPEG 图像文件格式。关键是只有在执行其他图像修改操作时才使用 IM 来校正数字照片方向(使用 "-auto-orient"),例如 缩略图创建图像注释水印 甚至 曝光调整。IM 可以使用 图像属性转义 从照片中提取当前方向(作为数字)...

  magick identify -format '%[exif:orientation]' pagoda_sm.jpg
[IM Text]
IM 提供一个特殊的 "-orient" 运算符(使用 "-list orientation" 查看可能的取值)。

  magick pagoda_sm.jpg -orient bottom-right \
                 -format '%[exif:orientation]'   info:
[IM Text]
这些元数据设置方法允许你调整你修改过照片的方向,尤其是你旋转过的照片。请注意,正确定向的照片的方向为 'Top-Left' 或 1。当然,如果你计划稍后使用 "-auto-orient",则不应删除 EXIF 元数据(使用 "-strip" 或 "-thumbnail")。在剥离图像元数据之前使用它。如果你确实想校正照片的方向,而不会劣化或以其他方式修改图像,我建议你使用 JHead 程序。例如,在这里我校正照片的方向,并删除目录中所有数字照片的内置预览缩略图。

  jhead -autorot  *.jpg
JPEG 无损旋转仅适用于大小可被 8 或 16 整除的图像。这对于大多数(但并非全部)数码相机照片来说都是正确的。如果你尝试对大小为奇数的图像进行此操作,则右侧或底部边缘块(包含部分大小)将不会在最终图像中正确定位,因为这些块只能存在于右侧或底部边缘。

有关这方面的示例,请参阅此 特定讨论
JHead 程序还允许你调整照片的日期(如果你的相机时间设置错误,或者你去了不同的时区),提取/删除/替换预览缩略图,设置图像的注释字段,删除 Photoshop 配置文件,以及进行基本的图像裁剪(以删除暴露自己的陌生人 ;-) 等操作,而不会劣化 JPEG 图像数据。我推荐这个程序,或者类似的程序(请参阅 其他 JPEG 处理程序),以修复此信息。只需确保它不会实际解码/重新编码 JPEG 图像数据。关于方向的最后一个要点。如果你将相机几乎直指上方或下方,则 EXIF 方向设置可能无法正确解析。倾斜或倾斜拍摄也是如此。方向(和相机)对这些情况毫无感觉。对于此类照片,你的唯一选择是自己使用较低级的无损 "jpegtrans" 或 IM "-rotate" 进行旋转,然后重置 EXIF 方向设置(使用 JHead 或 IM "-orient" 运算符),或者只是剥离 EXIF 信息。
Other IM Lossy Modifications...
  If you are also resizing or otherwise modifying the image, such as reducing
  its quality and size for use on the web, then data loss is already a fact.
  As such during those operations IM can do similar things, allowing you to do
  all the required operations in a single 'load-save' cycle.

  Rotate ALL images to landscape   -rotate 90\<
                       portrait    -rotate -90\>


颜色改进

在继续之前,建议你先查看 颜色修改,了解将要使用的通用颜色修改技术的介绍。将高对比度线框图和图形 规范化(使用 "-normalize")可能很棒。但规范化的照片可能看起来不真实,并且如前所述,可能也不适合打印。 "-contrast-stretch" 运算符可以限制规范化的 "边界",但 "-levels" 和/或 "-sigmoidal-contrast" 运算符可以进行 "更平滑" 的调整(请参阅 直方图调整,了解这些运算符执行操作的更低层级的讨论)。上面的输入来自 IM 邮件列表的 "Tong"。

亮度不足的照片亮度由 Walter Dnes 贡献

有时,可用的光线不足以进行适当的曝光。在其他情况下,你可能不得不使用比最佳曝光时间更短的曝光时间,以消除运动模糊。欠曝光的数字照片可以通过使用 "-sigmoidal-contrast" 运算符以及 '0%' 阈值级别来优先亮度较暗的区域,而不会吹出高光。有关更多详细信息,请参阅 S 形非线性对比度。以下是一个轻微欠曝光的示例,它是在日落后的一次免费音乐会上拍摄的。它有很多亮度很高的区域,这些区域很清晰,但也有一些我想让它们更可见的黑暗区域。

  magick night_club_orig.jpg  -sigmoidal-contrast 4,0%  night_club_fixed.jpg
[IM Output] ==> [IM Output]
与往常一样,你应该使用 TIFF 或 PNG 这样的无损格式进行中间工作。JPEG 格式仅用于减少磁盘空间和 Web 发布的下载带宽。

选择图像以查看示例实际使用的放大版本,而不是显示的小缩略图。
以下是一个严重欠曝光的示例,它是从我的阳台上向南拍摄的,朝向多伦多市。

  magick night_scape_orig.jpg -sigmoidal-contrast 10,0%  night_scape_fixed.jpg
[IM Output] ==> [IM Output]
主要参数控制着亮度增强的程度。所需的亮度增强越多,使用的值就越高。输出图片也会显得越粗糙。这是因为较小的像素误差也被增强了。S形对比度亮度增强往往会弱化光谱的红色端。你最终可能不得不选择一个参数,使其产生最自然的肤色,而不是你真正想要的亮度级别。在严重曝光不足的情况下,亮度增强后,你最终会得到一张颗粒状的黑白图像。这是数字图像增强技术的物理局限性。如果不存在颜色数据,IM 不会为你生成颜色数据。现实生活中,我阳台右侧的砖块是红色的,下面的树是绿色的。

合并 - 降低数字噪声由 Walter Dnes 贡献

许多严肃的摄影师对数码相机制造商“百万像素竞赛”的副作用感到不满意。制造商通过缩小像素尺寸,将更多像素塞进数码相机的传感器中。在相同的 ISO 设置下,较小的像素会导致图像噪声更大,这迫使人们使用较低的 ISO 设置。使用较低的 ISO 评分来避免噪声需要更长的曝光时间。反过来,这意味着大多数消费级数码相机在室内使用时,除了使用三脚架拍摄静物照片外,在内置闪光灯的 10 英尺范围内之外,实际上毫无用处。许多数码相机用户很乐意用一些像素换取在更高 ISO 设置下更少的噪声图像,但控制着这些公司的营销人员拒绝考虑这种选择。幸运的是,这种权衡可以在数字照片后期进行。专业术语是“合并”。简化的理论如下…
  • 取一个 n×n 的像素网格,并将它们的成分平均起来得到一个“超级像素”。
  • 信号与合并像素区域成正比,这意味着信号量增加了 n^2 倍。
  • 噪声是随机的。这意味着它与合并像素区域的平方根成正比,即 n 倍。最终结果是信噪比 (SNR) 增加了 n 倍。有关更多详细信息,请参阅 照片词汇表,合并
当将 1600×1200 的数字照片合并到 800×600(即 2×2 网格)时,信噪比会加倍。同样,将 2560×1920 的图片合并到 853×640 像素的 3×3 网格中,信噪比会提高 3 倍。
为了使用合并,照片图像必须是最终所需尺寸的整数倍。
在 ImageMagick 中,特殊的“-filter”设置“box”将在你“-resize”图像时,将像素组平均到单个像素(有关详细信息,请参阅 重采样滤波器。这意味着要进行“合并”,你只需要正确调整图像大小。
正在建设中
Walter Dnes 还提供了原始脚本 binn 来执行计算,最小程度地裁剪图像并执行“合并”。 合并示例 3合并示例 4

照片转换食谱

轻微旋转校正-- 使照片更平整

典型情况。你已经拍摄了一张照片,但图像不平整,你想纠正它。 [IM 输出]例如,这是我在 2008 年用手持相机在北京拍摄的照片,照片拍摄于景山公园的半山腰,就在故宫后面。它不是故宫本身的照片,而是山另一边的一座寺庙的照片。点击缩略图,查看更大的图像。是的,图像很小,你应该将解决方案应用于原始图像,而不是小的缩略图,但技术对于任何图像都是相同的。在这种情况下,图像需要旋转 -1.8 度才能纠正它。
现在,如果你只是简单地旋转图像,你会得到一个稍微大一点的图像,包含角落的彩色区域,这使得校正看起来很明显而且很糟糕。

  magick beijing_tn.png -rotate -1.95  beijing_rotate.png
即使你将图像裁剪回原来的大小,例如在 简单图像旋转 中演示的那样,你仍然会得到一些彩色的角落。
[IM Output]
最简单的解决方案是现在裁剪该结果,以移除这些边框,但你的图像会变成一个非常奇怪的大小,这再次表明已经做了某些操作。虽然执行该剪切的公式并不简单,但在 失真旋转方法 中进行了演示。
更好的解决方案是不仅旋转图像,还要稍微缩放它,以便生成一个与原始图像大小相同的旋转图像。

  angle=-1.95
  magick beijing_tn.png -distort SRT \
     "%[fx:aa=$angle*pi/180;(w*abs(sin(aa))+h*abs(cos(aa)))/min(w,h)], $angle" \
     beijing_rot_correction.png
[IM Output]
并且图像看起来很干净,墙壁完全平整。角度计算相当直接,使用的是图像中长直线两端的像素位置。但是我发现,简单地通过反复试验以各种小角度旋转图像,可以相对快速地找到一个合适的旋转角度。在查看特定角度的优劣时,请仔细放大查看你使用的线或边缘的像素。这张照片中墙壁的顶部。请记住,在图像旋转中,向左或逆时针旋转为负数(因为 Y 轴向下指向)。还要记住,如果可能的话,始终将操作应用于原始图像,避免使用中间图像(尤其是中间 JPEG 图像)。始终从原始源开始应用任何照片修改,而不是任何保存的中间副本。

倾斜移位效果-- 使风景看起来像人工模型

[IM 输出]“倾斜移位”是一种技术,会导致图像在顶部和底部模糊,而图像的中心保持清晰。它最初是在非常古老的皮腔式相机中完成的,在这些相机中,镜头会倾斜以使图像的顶部和底部失焦。由于在 ImageMagick v6.5.4-0 中添加了 可变模糊映射,现在很容易做到这一点。如果你在此基础上添加非常高的对比度以增强阴影,并饱和颜色,典型结果是,普通图像可以被制作成看起来很人工。就像你在拍摄一个小型、高度详细、光线充足的模型一样。
我们需要做的第一件事是增强图像中的颜色,使其具有非常高的对比度,也许还要稍微亮一些,使其看起来像是在强烈的工作室灯光下照射得很好。

  magick beijing_md.jpg -sigmoidal-contrast 15x30% beijing_contrast.jpg
[IM Output]
请注意,我使用了强烈的 S形对比度操作 来实现这些颜色效果。我没有简单地使用线性对比度,因为我不想“剪切”图像中最亮和最暗的颜色。“15”的对比度值是一个非常非常强的对比度。我还通过将对比度阈值中心偏移到“30%”的灰色值来稍微提亮了图像。如果对比度增强图像的颜色不够卡通化,你可能想尝试使用 调制运算符 来增加图像的颜色饱和度。这张图片不需要这样做,因为它已经具有瓷砖屋顶和明亮的绿树,提供了足够的颜色效果。如果你查看图像的放大版(点击缩略图),你会发现即使只是增强颜色也会让图像有一种人工光的感觉,尽管它看起来不像一个模型,背景中的汽车和前景中的人太详细了。
现在进行倾斜移位。为此,我们准备一个渐变图像,顶部和底部为白色,中间为黑色。有些人可能会为此使用线性渐变,但我发现抛物线渐变更好。

  magick beijing_contrast.jpg \
          -sparse-color Barycentric '0,0 black 0,%h white' \
          -function polynomial 4,-4,1   beijing_blurmap.jpg
[IM Output]
请注意,我使用了带有两点 重心稀疏着色 的原始图像本身来在整个图像上生成线性渐变。然后使用基本 多项式函数 修改该线性渐变,使其成为中间为黑色的抛物线渐变。现在只需根据模糊图模糊图像即可创建“倾斜移位”效果。结果是,原始图像看起来更像一个比例模型,而不是对真实事物的快速快照。

  magick beijing_contrast.jpg  beijing_blurmap.jpg \
          -compose Blur -set option:compose:args 10 -composite \
          beijing_model.jpg
[IM Output]
正如你在最终图像中看到的,由于颜色强烈,树木和建筑物看起来非常人工,而近处和远处部分的模糊使图像具有“小型”模型般的感觉。虽然这肯定是一个非常详细的模型!通过在倾斜移位处理过程中执行 旋转校正(见上文)可以进一步改善结果。完美的相机方向只会增强人工感。当然,你可以将所有这些操作串联起来,一次性执行所有操作,并避免临时文件或质量损失。

  magick beijing_md.jpg -sigmoidal-contrast 15x30% \
          \( +clone -sparse-color Barycentric '0,0 black 0,%h gray80' \
             -solarize 50% -level 50%,0 \) \
          -compose Blur -set option:compose:args 10 -composite \
          beijing_model.jpg
在上面的示例中,我将抛物线渐变替换为更传统的线性黑白灰渐变(具有相同的斜率)到“倾斜移位”模糊图。使用 反转颜色和色阶 技术使线性渐变水平峰值大约位于图像底部的 1/3 处。但是我发现线性渐变中的焦点区域太小,不太实用。还有许多其他方法可以为倾斜移位效果生成合适的渐变。例如,使用 调整大小的渐变。或者水平缩放一列像素的 谢泼德稀疏颜色。正弦曲线渐变也可能有用。
速度优化
可变模糊映射 操作本质上使用的是单次二维模糊方法(等效于均匀高斯模糊)。但是,你可以通过执行两个一维可变模糊操作来获得整体速度提升。例如,这里我先水平模糊,然后垂直模糊…

  magick beijing_md.jpg -sigmoidal-contrast 15x30% \
          \( +clone -sparse-color Barycentric '0,0 black 0,%h gray80' \
             -solarize 50% -level 50%,0 -write mpr:blur_map \) \
          -compose Blur -set option:compose:args 10x0 -composite \
          mpr:blur_map \
          -compose Blur -set option:compose:args 0x10 -composite \
          beijing_model_2pass.jpg
结果实际上是一样的(尽管略有不同),但处理速度要快得多。旁注:我认为交换操作(先垂直模糊,然后水平模糊)会为这种类型的模糊映射生成更准确的结果。基本上,由于水平模糊在该模糊方向上是恒定的,因此应该最后进行。
倾斜移位效果与真实模型的问题
如果你仔细观察生成的图片,你会发现它是一个假的倾斜移位,而不是真实模型的照片。你可以看到,与建筑物的底部相比,较大建筑物的屋顶过于模糊。尽管它与底部距离大致相同。类似地,“墙”的底部比墙的顶部更模糊。也就是说,它可以被看作是假的。问题是,大型垂直物体应该在整个表面上模糊相同程度,而不仅仅是根据高度变化地模糊。请记住,模糊梯度旨在代表图像中各个物体的焦深或距离,因此垂直物体的表面应始终处于相同的“距离”,因此模糊程度相同。为了修正,我需要调整模糊梯度,使这些区域相对于图像的其余部分具有“底部”的恒定(或接近恒定)颜色。也就是说,垂直表面具有恒定的模糊量,而所有水平表面具有模糊梯度。基本上,模糊梯度应该代表图像中每个点的实际“深度”,对于大多数图像而言,这是一个非常复杂的梯度。这种调整可能难以实现,因为它很可能需要对什么是水平墙以及物体在图像中的距离进行人工解释。它也不太可能被轻松地自动化。你能用这种效果做什么?给我发你倾斜移位图像的邮件!我会在这里引用它们。或者也许你可以修正上面示例中的倾斜移位错误。

PNG-JPEG 分层图像

通过将一个大的报纸或杂志页面分离成一个保存为 PNG 的文本层和一个保存为 JPG 的图像层,两者都使用纯白色背景,可以比两个图像合在一起使用更少的磁盘空间!更重要的是,图像可以使用有损压缩(JPEG),文本部分将保持清晰锐利(PNG)。听起来很愚蠢和奇怪,但实际上是真的。分离后的图像可以节省与单个组合图像相比多达 3 到 4 倍的磁盘空间。通常,这两个图像是在出版过程中作为单独的图层生成的。但你也可以在事后分离图像。这些图像只是叠加在一起……

  magick ny_family.jpg ny_family.png -composite   ny_family_merged.jpg
[IM Output] ==> [IM Output] ==> [IM Output]
选择生成的图像以查看更大副本。
这使用了一个普通的 叠加合成,它要求 PNG(叠加)图像为透明。这种透明性有两种形式。要么是布尔(纯开/关)掩码,如上所示。欢迎提供图像分离的示例代码。

重叠照片-- 模糊的附加照片叠加

创建一系列叠加的照片(我指的不是全景图)是一项常见的任务,特别是在网站创建中。但是,除非你了解 IM 运算符,否则这样做可能很棘手。最简单的方法是使用两个图像的 蒙版合成 和一个蒙版来选择要叠加的图像。然而,首先你需要进行简单的数学运算。在这个示例中,我使用两个尺寸为 120x90 像素的缩略图图像,我想将它们水平叠加 40 像素。这意味着生成的图像应为 120 + 120 - 40 像素宽,即 200x90 像素图像。接下来,我们需要一个蒙版。它需要在一侧为黑色,另一侧为白色,中间有一个 40 像素的渐变,大小与最终输出图像相同。也就是说,120 像素 - 40 像素,为两个非重叠区域分别提供 80 像素区域。所以,让我们生成一个蒙版图像……

  magick -size 90x80 xc:white xc:black   -size 90x40 gradient: \
          +swap -append -rotate 90    overlap_mask.png
[IM Output]
生成蒙版图像的另一种方法是使用 Fred Weinhaus 的“plmlut”水平渐变生成器脚本。与我在上面生成的线性渐变相比,它对渐变曲率有更精细的控制。现在数学部分都完成了,剩下的就是进行一个三图像蒙版合成,使用我们刚刚生成的蒙版。但是,我们还需要放大目标(左侧)图像,以便为重叠的右侧图像(任何颜色)提供足够的空间,并使用适当的重力(右侧或“East”)正确放置第二个图像。

  magick holocaust_tn.gif -extent 200x90  spiral_stairs_tn.gif \
          overlap_mask.png  -gravity East -composite   overlap_photos.jpg
[IM Output] [IM Output]  + [IM Output] ==> [IM Output]
现在我们有两个图像,它们使用线性渐变叠加在一起。当然,这两个命令可以合并成一个命令,这样你就无需保存“蒙版”中间图像。这留作读者练习。一个轻微的改进是使用更弯曲的渐变在图像之间进行更大的重叠。这减少了在最终图像重叠区域的开始和结束处可见的尖锐变化。特别是当图像包含大面积颜色差异很大的区域时。例如,这使用了一些 扭曲渐变 技术,不仅生成更平滑的渐变曲线,而且还旋转渐变,以实现高度倾斜的重叠。

  magick -page +0-15 -size 1x30 gradient: \
          -sigmoidal-contrast 5,50% -contrast-stretch 0 \
          -set option:distort:viewport 180x90-90-45 \
          +distort SRT 115 +repage \
          holocaust_tn.gif -extent 180x90 +swap \
          spiral_stairs_tn.gif +swap \
          -gravity East -composite   overlap_angled.jpg
[IM Output]
是的,上面的内容相当复杂,但它展示了可能实现的功能。如果你计划处理超过两个图像,更好的方法是使用蒙版直接设置第二张和后续图像的透明度。然后,可以使用 分层图像示例 中所示的技术将多个图像叠加在一起。其中一些技术不需要你计算最终图像大小,因为 IM 可以为你完成。你只需要确保将图像放置在正确的位置即可。例如,在这里我将 30 像素的渐变添加到第二张和第三张图像,要求图像相互放置 90 像素(宽度 120 减去 30 像素重叠)。当所有图像都具有适当的透明度和定位后,我们只需 马赛克 这些层(所有偏移量均为正),让 IM 计算最终画布大小。

  magick -size 90x90 xc:white -size 90x30 gradient: -append -rotate 90 \
          hatching_tn.gif \
          \( chinese_chess_tn.gif -clone 0 \
                 -compose CopyOpacity -alpha off -composite -repage +90+0 \) \
          \( holocaust_tn.gif -clone 0 \
                 -compose CopyOpacity -alpha off -composite -repage +180+0  \) \
          \( spiral_stairs_tn.gif -clone 0 \
                 -compose CopyOpacity -alpha off -composite -repage +270+0 \) \
          -delete 0   -compose Over  -mosaic     overlap_series.jpg
[IM Output]
与其预先计算重叠蒙版图像的位置,不如使用在 附加重叠 中找到的技术,以及 增量计算位置 用于更长的图像序列。最终说明:这种叠加照片最适合具有相当共同整体颜色的图像。此外,你可能会注意到,对于序列两端的图像,由于只有一侧的图像重叠,所以居中的主题可能看起来并不太居中。可以通过将这些图像的外边缘淡化为透明,或切除一些外边缘以帮助重新居中这些图像的主题来改善此问题。旁注:也许在不同的颜色空间中进行合成会更好。有人愿意尝试一下并报告你的结果,无论好坏?

双重曝光-- 混合同一场景的多个照片

在旧式胶片相机中,有一种技术可以在不“滚动”胶片的情况下多次拍摄一张照片。这使你能够创建所谓的双重曝光,其中在略微不同的时间拍摄的两张图像合并在一起。结果通常是图像中移动或改变的部分出现重影或变暗。但是,通过仔细控制图像中的主题、灯光效果,甚至冲洗过程,就可以拍摄一些非常奇怪甚至“不可能”的照片。对于数字图像来说,这甚至更容易,因为你拥有对图像的更多控制。基本上……眼见为实,但相机说谎! 例如,假设我想在图像中出现两次!这很容易做到。例如,这里是我专门为这个示例拍摄的两个快速照片的缩略图,使用三脚架和定时器,我将直接使用它们。
[IM Output] [IM Output]
也许你可以提供一套更好更有趣的照片?
我将直接将双重曝光技术应用于这些缩略图,尽管更典型的是我会使用原始图像文件作为输入,以便获得最高质量的结果。现在,如果我使用旧式相机的传统胶片式“双重曝光”,结果将是这两张图像的平均值,生成我自己的透明“重影”。这是这种技术的数字模拟……

  magick anthony_1.jpg anthony_2.jpg -evaluate-sequence mean  anthony_ghosts.jpg
[IM Output]
但是,如果我不想看到重影,而是想看到我自己的真实图像呢?那么你需要使用一个蒙版来选择要来自哪个图像的哪些部分。这个蒙版可以通过两种方式生成。你可以通过沿着静止或不变的部分划分图像来手动创建蒙版。对于这种情况来说,这是一个相当简单的事情……

  magick -size 100x90 xc: -draw 'rectangle 0,0 50,89' \
          -blur 0x3  anthony_mask.jpg
[IM Output]
请注意,我模糊了蒙版,以便在两个图像之间“羽化”切割。在这里,我使用 蒙版合成 来合并图像。

  magick anthony_1.jpg anthony_2.jpg anthony_mask.jpg \
          -composite  anthony_doubled.jpg
[IM Output]
如果你有两张(或更多张)家庭照片,其中一些人闭着眼睛、说话、做鬼脸或只是看着别处,该怎么办?你可以从不同的图像中挑选每个“头部”并合并多个图像以形成蒙太奇,这样就可以得到一张每个人都看着相机,而且眼睛都睁开的照片。通过交换输入图像,或者仅仅反转蒙版,你可以将我完全从图像中移除,以便获得静态背景的无遮挡视图。

  magick anthony_2.jpg anthony_1.jpg anthony_mask.jpg \
          -composite  anthony_removed.jpg
[IM Output]
当拍摄公共纪念碑的照片时,这会很方便,因为你无法承受控制人群的费用。只需从三脚架上拍摄大量照片,希望你能将它们组合在一起,将所有人从场景中移除!生成背景图像的另一种方法是使用数百张图像(视频),或者只是创建所有图像的平均值。这将把所有人或其他瞬态物体变成“重影”的光晕。这本身可能是一种有趣的效果,但不一定总是人们想要的。平均图像可能是一个有用的步骤,因为一旦你拥有它,就可以将它与每张单独的图像进行比较,以从每个帧中屏蔽掉人(瞬态物体),然后再次将背景组合在一起,以创建一个干净(无光晕)的背景图像。关于从视频图像中自动生成“干净背景”的主要讨论在 IM 讨论论坛上,主题为 创建参考图像提取更改事件
使用干净的背景照片,我们可以对差值图像进行阈值处理,以屏蔽图像中发生变化的部分。你可能需要使用一些额外的模糊和阈值来适当地扩展该蒙版,以覆盖图像中的物体,以及它可能在背景景色上投下的任何阴影或反射。可能还需要进行一些尝试和错误才能获得正确的结果。

  magick anthony_removed.jpg anthony_2.jpg \
          -compose difference -composite \
          -threshold 5% -blur 0x3 -threshold 20% -blur 0x3 \
          anthony_automask.jpg
[IM Output]
现在让我们使用这个蒙版将我的“重影”图像与原始图像混合,这样看起来我的良心正在“困扰”我,因为我制作了这样的“不可能”的照片。

  magick anthony_1.jpg anthony_ghosts.jpg anthony_mask.jpg \
          -composite  anthony_haunted.jpg
[IM Output]
最后,所有上述技术都假设照片是从固定在固定三脚架上的相机拍摄的。如果不是这样,而是从手持位置拍摄的,我可以保证无论你多么努力地尝试,这些图像都不会正确匹配或“对齐”。在这种情况下,你可能需要对两个图像中的至少一个进行一些 仿射 甚至 透视 扭曲,以使背景正确对齐。背景越复杂,所需的重新对齐就越精确。如果使用了闪光灯,或者天气阴天且光线变化,你可能还需要对照片进行一些亮度调整。原因是大多数相机都会“自动调整”图像的亮度,闪光灯或变化的光线会改变它对每个图像的“自动级别”调整的处理方式。作为最后一个例子,这里是我从两张单独的照片中创建的另一张图像,我的侄子在攀岩墙前与自己击剑。因为我拿着相机并使用了闪光灯,所以我确实需要进行一些仿射扭曲调整,以及轻微的亮度调整,才能获得你看到的无缝结果。
[IM Output]
雅各布 vs 雅各布
如果你想判断这张照片是否为假,你会观察光线、阴影和反射。在上面,仔细观察地板会发现,右边的“雅各布”在地板上没有合适的反射(被照片边缘裁掉了)。但你需要仔细研究照片才能注意到这一点!现在想想你可以使用这种“双重曝光”技术来实现哪些可能性。例如,如何制作一些有趣的镜子。请将你的结果发邮件给我!如果你想进一步研究这个问题,研究论文 "交互式数字照片蒙太奇",探讨了使用“双重曝光”(或称“照片蒙太奇”)的方法,但利用用户选择并通过“图像分割”进行扩展,以选择图像的哪些部分来自哪里。例如,如果你有多张大型人群的照片,每张照片中都有人“看起来不好”。你可以使用这种技术来选择每个人来自哪张照片,这样你就可以得到一张完美的合影,每个人都:正面朝向镜头,眼睛睁开,面带微笑!

保护某人的匿名性-- 模糊照片的某一部分

上述使用 3 图像合成蒙版的技术也可以用在其他方面。例如,你可以对图像进行“像素化”,然后使用蒙版将效果限制在人的脸上,从而“保护他们的身份”。

  magick zelda_tn.gif -scale 25%  -scale 400%  zelda_pixelate.gif
  magick zelda_tn.gif -gamma 0 -fill white \
          -draw 'circle 65,53 50,40'   zelda_face_mask.gif
  magick zelda_tn.gif zelda_pixelate.gif zelda_face_mask.gif \
          -composite   zelda_anonymity.png
[IM Output] ==> [IM Output] [IM Output] ==> [IM Output]
当然,你可以在一步内完成所有操作,甚至可以使像素化到正常的过渡变得平滑。例如...

  magick zelda_tn.gif \( +clone -scale 25%  -scale 400% \) \
          \( +clone -gamma 0 -fill white \
             -draw 'circle 65,53 50,40' -blur  10x4 \) \
          -composite  zelda_anonymity.jpg
[IM Output]
当然,除了对有问题的部分进行像素化之外,你也可以对该区域进行模糊处理。只需将两个 "-scale" 运算符替换为一个 "-blur" 运算符即可模糊细节。这种替换蒙版区域的技术也可以用来从图像中移除不需要的文字和徽标。有关详细信息,请参阅填充孔洞

向图像添加纹理

使用强光 alpha 合成方法,甚至任何照明合成方法都可以为图像添加纹理图案。例如,这里我在一张我在中国南部昆明动物园拍摄的宝塔照片上添加了一块粗布纹理。

  magick tile_fabric.gif -colorspace gray  -normalize \
          -fill gray50 +level 35%      texture_fabric.gif
  magick composite texture_fabric.gif  pagoda_sm.jpg \
            -tile   -compose Hardlight    photo_texture.jpg
[IM Output] ==> [IM Output] ==> [IM Output]
请注意,如果你想在图像上真正平铺纹理,你需要使用 "magick composite" 命令,而不是更通用的 "magick" 命令,虽然还有其他几种使用 convert 命令在内存中平铺图像的方法。另外请注意,在添加这种纹理时,原始照片中的较小细节可能会因叠加纹理的过量噪声而丢失,纹理应该保持简单,或者它们的效应对原始照片的影响要适度,比如上面使用的降低对比度的级别调整。要使用图像图案作为纹理,应该对其进行修改,以便在原始图像中未改变的区域使用完美的灰色。也就是说,图像的平均颜色应该约为 50% 的灰色。在示例中,我演示了一种方法,可以用几乎任何可平铺的图像来实现这一点,尽管这种特定方法可能并不总是有效。这种纹理可以在网络上随处可见,比如各种网页的背景图案。它们可能看起来不像纹理,也可能很鲜艳,甚至很亮或很暗。但是,在调整之后,你会发现你可以得到一些非常有趣的效果。就像我们之前做的那样,你可以通过创建一个合适的蒙版来限制图像的哪些部分实际上是纹理化的。例如,让我们创建一个只包含宝塔照片中附近的“白色”天空的蒙版。

  magick pagoda_sm.jpg -fuzz 10% -transparent white \
          -alpha extract -negate  pagoda_mask.png
  magick pagoda_sm.jpg  photo_texture.jpg  pagoda_mask.png \
          -composite  photo_texture_masked.jpg
[IM Output] ==> [IM Output]
现在想象一张女士穿着连衣裙的照片。你可以得到任何图案,将其适当地阴影化,然后将其叠加到原始图像上,以用完全不同的设计替换连衣裙。当然,为了获得最终效果,还有很多方法可以对上述方法进行变体,你使用哪种特定技术取决于你,但基本思想是一样的。对图像进行纹理化,蒙版并叠加结果。顺便说一下,我还建议你看看叠加 alpha 合成方法,它与强光合成方法完全相同,只是将两个图像交换了位置。还有很多其他的阴影合成方法可以用来以各种方式对图像进行纹理化。
[IM Output]

色度键蒙版-- 通过特定颜色区域进行修改

左侧的照片是由一位用户在IM 论坛讨论中提供的。他希望更改女孩衬衫的颜色,衬衫的颜色是漂亮的“粉色”。问题是颜色不仅仅是“粉色”,而是各种不同的“粉色”色调。正如你上面所看到的,要对图像进行更改,第一步通常是生成要处理区域的合适蒙版。在这里,我将使用一种称为色度键的技术来生成特定颜色的蒙版。这种技术通常用于查找图像中的特定颜色,并将其用作蒙版。它也是用于“蓝色”和“绿色”屏幕效果的技术,这种技术在电视和电影中被广泛使用。
 
这基本上涉及通过分离通道图像来提取“色调”,然后查找所需的“色调阴影”。例如...

  magick shirt.jpg -colorspace HSL -channel Hue -separate shirt_hue.jpg
但是,这个色调图像存在一些问题。
  • 首先,“粉色”的颜色非常接近“红色”,而“红色”位于色调“翻转”的分界点。为了确保这不会成为问题,我使用调制来调整色调,使其远离色调中的这种“不连续性”。这对于提取“绿色”或“蓝色”屏幕的“色度键”来说不是问题。
  • 这种“粉色”颜色也不是一种饱和度很高的颜色,而是饱和度值非常低。这意味着它的“色调”不像它应该的那样强烈。
  • 另一个问题是灰色的背景!灰色几乎没有色调,所以我需要从最终蒙版中移除任何饱和度很低或没有饱和度的区域,否则我会改变背景中的东西。请注意,如果我将更改限制为色调滚动,这在技术上是不需要的,因为色调滚动不会影响不饱和的颜色。
简而言之,输入图像如果使用更亮、更强烈的颜色会效果更好,而且这种颜色也不应该与皮肤(或头发)的颜色相似。例如,一件强烈的蓝色或绿色衬衫。但我将使用我得到的图像。
[IM Output]
所以,让我们提取并组合这两个通道蒙版。请注意,在使用模数“滚动”图像色调后,色调 = 灰色 64,灰色背景的饱和度 = 黑色。

  magick shirt.jpg -modulate 100,100,33.3  -colorspace HSL \
          -channel Hue,Saturation -separate +channel \
          \( -clone 0 -background none -fuzz 5% +transparent grey64 \) \
          \( -clone 1 -background none -fuzz 10% -transparent black \) \
          -delete 0,1  -alpha extract  -compose multiply -composite \
          shirt_mask.png
这只是留下了一些小的孤立的“斑点”,可以通过一些形态学平滑-morphology Smooth Square)来移除。它并不完美,但它可以完成工作。更好的方法是用手工编辑蒙版以清理它。现在,可以使用蒙版与合成蒙版结合使用,就像我们在上面的双重曝光匿名示例中所做的那样。但是,如果你使用蒙版来修改现有图像(不失真或更改图像大小),那么更简单的方法是使用蒙版来定义哪些区域是不可写的。这些被称为剪切蒙版或写入蒙版(参见 "-mask")。
[IM Output]
这里我清理了之前蒙版中的小缺陷(可选),并将其取反,以定义我想“写入保护”的区域。然后我设置这个蒙版,将色调移位,将“粉色”变成“浅蓝色”,并保存生成的图像。

  magick shirt_mask.png -morphology Smooth Square \
          -negate   shirt_write_mask.png

  magick shirt.jpg  -mask shirt_write_mask.png \
          -modulate 100,100,25     +mask shirt_blue.jpg
是的,有一个轻微的“粉色”边框,特别是在内袖上。她手臂上的一个小块皮肤也变成了深蓝色。基本上这些都是蒙版缺陷,通过花更多的时间来完善蒙版,你可以解决这些问题。但结果还不错。生成更好的蒙版的一种方法是使用更大的高分辨率图像。当生成的图像稍后被调整大小后,这些小缺陷将(希望)也会被缩减到可以忽略不计的程度。
[IM Output]
这个特定示例的真正问题是,“关键颜色”与正常肤色非常接近,你真的就是在自找麻烦!这就是为什么使用这种技术的人使用“绿色”和“蓝色”屏幕,因为这些颜色与屏幕前的人的“肤色”差别最大。请注意,最好不要将 JPEG 用作源图像或工作图像。实际上,JPEG 应该只用于最终图像!这正是最初生成如此多“蒙版缺陷”的部分原因。

绿屏

未来的示例,使用“绿色屏幕背景”的色度键蒙版。扩展自维基百科文章色度键

“绿色屏幕”处理中的真正问题是“颜色溢出”,细小的淡色头发(金色)和半透明区域会产生最糟糕的颜色溢出效果。

简单的颜色溢出移除(颜色修复)
g(r,g,b) => (r, min(g, b), b)
Alpha 确定...
a(r,b,g) => K0 * b − K1 * g + K2
将所有 K 系数的值设置为 1.0 是一个好的初始猜测。

由于背景颜色是已知的,并且一旦知道“alpha”,你就可以使用使用两个背景移除背景中所示的技术来移除可能存在的任何“绿色屏幕光晕”,这比第一个颜色公式的效果更好。


艺术家炭笔素描图像

使用炭笔素描变换,用户可以非常简单地生成图像的简化灰度渲染。它不适用于“繁忙的图像”,但对于简单的图像,它可以产生非常引人注目的效果。

     magick holocaust_sm.jpg -charcoal 5 charcoal.gif
[IM Output] ==> [IM Output]

儿童着色轮廓图像

在关于生成着色页的 IM 用户论坛上的长期讨论中,开发了以下食谱,将一张简单的照片转换为孩子们可以着色的东西。这是迄今为止我们得到的最佳结果,应用于我在柏林拍摄的纳粹大屠杀纪念碑的照片。

  magick holocaust_sm.jpg \
          -edge 1 -negate -normalize \
          -colorspace Gray -blur 0x.5 -contrast-stretch 0x50% \
          color-in.gif
  # For heavily shaded pictures...
  #     #-segment 1x1 +dither -colors 2 -edge 1 -negate -normalize \
[IM Output] ==> [IM Output]
上述操作中的最后一步试图平滑线条,并改善整体效果。当然,上述技术仅适用于颜色变化鲜明且分辨率高于我上面使用的图像的图像。对于已经具有黑色轮廓和浅色背景的卡通图像,使用边缘检测与上述方法结合使用会直接产生黑色轮廓的“双重”效果。你可以在通往纪念碑的路径上的瓷砖的双重线条中看到这种效果,位于左下角。这是边缘检测工作方式的结果,你可以在 IM 示例的该部分中看到更多示例。解决方案是在使用 "-edge" 来描绘彩色区域之前,对这种类型的图像进行取反。

  magick piglet.gif -background white -flatten \
          -colorspace Gray -negate -edge 1 -negate -normalize \
          -threshold 50% -despeckle \
          -blur 0x.5 -contrast-stretch 0x50% \
          color-in_cartoon.gif
[IM Output] ==> [IM Output]
我还会使用 "-threshold" 来去除 "-edge" 命令生成的单个点。之后,我再次尝试平滑图像中的锯齿线条。以上内容是在关于 GIMP Photocopy Filter 的讨论中添加的,旨在利用 Compose Divide 方法来查找轮廓。

  magick taj_mahal_sm.png -colorspace gray \
          \( +clone -blur 0x2 \) +swap -compose divide -composite \
          -linear-stretch 5%x0%   photocopy.png
[IM Output] ==> [IM Output]
以上命令中的 "-linear-stretch" 操作调整图像暗区的黑色程度,而 "-blur" 的 'sigma' 定义了阴影的锐度。

铅笔素描

利用 Photoshop (PSP) 教程 中关于将图像转换为 铅笔素描 的内容,dognose 来自 IM 用户论坛,成功创建了等效的 ImageMagick 命令。这是他的转换,简化为几个 IM 命令,允许你将大量图像批量处理为“艺术家铅笔素描”形式。首先,我们需要一个特殊的 "pencil.gif" 图像。这可能需要很长时间,因此在本例中,我将它缩小了一些,同时保留了它在更大图像上平铺的能力。有关技术的详细信息,请参阅 修改平铺图像
这只需要完成一次,然后就可以重复使用。因此,你可以生成一个更大的图像供自己使用,以避免任何平铺效果。理想情况下,使它的尺寸与你计划转换的图像一样大。


magick -size 256x256 xc: +noise Random -virtual-pixel tile \ -motion-blur 0x20+135 -charcoal 1 -resize 50% pencil_tile.gif
[IM Output]
现在,只需要将这个“铅笔”阴影图像叠加并混合到照片中。铅笔图像被平铺以生成与我们正在处理的图像大小相同的画布。然后,它使用 平铺画布 中找到的技术应用于图像。然后,它被合并到原始图像的灰度副本中。

     magick pagoda_sm.jpg -colorspace gray \
          \( +clone -tile pencil_tile.gif -draw "color 0,0 reset" \
             +clone +swap -compose color_dodge -composite \) \
          -fx 'u*.2+v*.8' sketch.gif
[IM Output] ==> [IM Output]
请注意,由于 "-blend" 操作符在 "composite" 命令中不可用,我选择使用 DIY "-fx" 操作符来执行等效操作。可能存在更好的、更快的,但也更复杂的方法来实现这一点。(欢迎提供建议)这不是最终版本,因为操作符缺少一些边缘增强方面,这些方面对于突出显示图像中一些更浅但更锐利的颜色变化的轮廓是必要的。你能改进以上内容吗?以上算法已作为艺术转换 "-sketch" 集成到 IM 中,但没有为生成的“铅笔平铺”提供 "-resize" 平滑...


magick pagoda_sm.jpg -colorspace gray -sketch 0x20+120 sketch_new.gif
[IM Output] ==> [IM Output]

去除暗角

拍摄照片时(无论是否使用数码相机),相机镜头通常会使图像边缘和角落变暗。这被称为“暗角”。事实上,这种镜头效果非常普遍,以至于人们经常使用 "-vignette" 操作符故意制造暗角效果。请参阅 暗角转换。Martin Herrmann <Martin-Herrmann@gmx.de> 想要从照片中去除相机暗角。基本上,他拍摄了一张白色纸张的照片,在明亮的光线下没有使用闪光灯。然后,他想要将这张照片与他的实际照片结合起来,以适当地提亮图像的边缘和角落。基本上,我们要做的就是将原始照片除以明亮白色纸张照片的灰度图像,这样就可以根据“白色纸张”照片变暗的程度提亮图像的相应部分。这实际上就是“Divide”的合成方法,它将“源”图像除以“背景”图像。例如,

  magick nikon18-70dx_18mm_f3.5.jpg  vegas_orig.jpg \
          -compose Divide -composite  vegas_fixed.jpg
[photo]  + [photo] ==> [photo]
(点击查看更大的照片图像)
然而,由于“白色纸张”的照片可能不是真正的白色,而且你可能不想用这种“偏白”的颜色提亮图像。为了解决这个问题,我们需要将除数图像乘以其中心像素的颜色。以下是提供给 Martin 的最终解决方案,它使用了非常慢的 FX DIY 操作符。这早于 Divise Compose 方法 的添加,而该方法可以用来极大地加快这一过程。白色照片也进行了灰度化,以去除任何颜色失真,请注意我改变了顺序,这也将保留原始照片中的任何“元数据”(因为它是这种情况下的“目标”图像)。

  magick vegas_orig.jpg \( nikon18-70dx_18mm_f3.5.jpg -colorspace Gray \) \
          -fx '(u/v)*v.p{w/2,h/2}'   vegas_fixed_fx.jpg
[photo]
如果你仔细观察放大后的照片,特别是左上角和右上角的“天空”角落,你可以看到暗角效果以及所做的校正。这不是一个完美的解决方案,可以进行一些微调。例如,与其使用缩放像素,我们可以对“白页”图像进行预处理,并对其进行调整,以获得更好的暗角去除效果。请注意,不建议使用 JPEG 格式进行任何摄影工作,因为这种格式会在结果中引入一些伪影和不一致。这种格式只适合存储和显示最终结果。关于校正暗角的重大讨论在 IM 用户论坛中的讨论 针孔相机算法暗角校正? 中。以下因素可能会影响暗角...
  • 胶片与镜头的距离,距离越远,光线散射越多。
  • 光圈“圆圈”(镜头或针孔)的面积,由于光线角度而变化。
  • 光圈周围相机材料的排列。例如,镜头支架或针孔厚度。