图片能不能变窄,却不把里面的一切都挤扁?
普通缩放改变整张图的间距,裁剪丢掉靠近边缘的一块。接缝裁剪走第三条路:删除一条贯穿各行、每行恰含一个像素的连接路径,再合上空隙。反复操作,就能选择性改变宽度。真正有趣的是,算法怎样判断图片失去哪一些像素也没关系。
数值代价低,不等于重要性低。
给每个像素一个代价
合成图宽240像素、高150像素,缓慢变化的深色背景上有金色圆和蓝色竖条。脚本先对三个颜色通道作算术平均,再将这个标量图的水平、竖直梯度绝对值相加,作为像素评分。
这个分数常叫“能量”,但不是物理能量,也不是校准亮度测量,只是局部对比度代理。强边界代价高,近乎均匀区域代价低。名称不应掩盖选择:算法被要求避开这个特定数值场的变化,而不是理解画里的物体。
通道平均有一种明确的颜色盲点。通道为 (1, 0, 0) 的纯红像素,与 (0, 1, 0) 的纯绿像素,平均后都是三分之一。两种原始颜色差别很大,但它们之间的边界可能从这张标量评分图里完全消失。这不是算术错误,而是说明路径搜索之前已经丢弃了哪些信息。仅仅更换搜索算法,无法恢复输入成本中根本不存在的边界。

在代价图里找连接路径
竖直接缝每行恰好包含一个像素。相邻两行之间,可以向左一列、保持同列或向右一列。约束保证路径相连,也允许它绕开昂贵区域,而不只是硬切掉一整列。
动态规划寻找当前能量图中总成本最低的接缝。每个像素,把本地成本加到上一行合法前驱中最低的累计成本上。再从末行最便宜端点回溯,得到完整路径。独立小测试将答案与所有合法路径的穷举比较。

删掉一条,下一道题就变了
删除选中像素后,每行剩余像素合上空隙,宽度减一,高度不变。重新计算梯度场,再在变过的图上寻找接缝,重复直到删去70条。最终尺寸为170 × 150。
每条单独接缝在当前成本场和规则下最优,但不证明70次删除序列对所有可能终图整体最优。早先选择会改变后续邻接关系与成本。这个简单实现展示反复的局部决策,不声称复制所有现代内容感知缩放技术。
填合空隙还会创造新的邻居:原本隔着接缝的两个像素,删除后相邻,可能形成很显眼的新边界。这里的后向能量评分衡量的是删除前当前图像中的对比,没有明确为所有新产生的关系计费。删除后重算虽然有用,却不会撤销已经造成的损伤。因此,除了检查所选路径成本低不低,还必须检查编辑后的图像。

有利例子保住了圆
在这个特定样例中,属于金色圆的2,809个像素,在接缝裁剪后全部保留。背景承担删除,圆保留像素形状。普通缩放到同一输出尺寸,则会横向压缩圆,让它相对高度变窄。
成功范围刻意限制在这幅构造图:物体边缘强烈,周围低成本空白充足。没有测试人脸、文字、建筑或自然照片。即使成功,间距和构图也改变了,所以保住物体像素,并不等于保住图像的全部含义。
平滑主体,暴露盲点
失败样例换成宽阔金色前景和细微重复条纹。即使视觉上属于主要对象,内部在梯度评分下仍可能很便宜。删除90条接缝后,前景像素数从21,000降到14,550,区域明显变窄。
算法完全遵循了指令。它没有语义理由保护平滑人脸、朴素标牌或图形安静的中心。保护蒙版、不同成本,以及考虑新生成边缘的方法,可以改善某些情况,但也引入更多判断。自动缩放仍需检查形状和关系。
保护区域可以表达为给用户希望保留的像素附加惩罚。这让目标包含更多信息,却并非万无一失:有限惩罚仍可能被其他成本压过,而完全禁止经过的区域可能导致没有连通路径。受保护主体也可能保住像素,却改变了周围间距。因此,最好同时说明必须保留的对象与必须合理的视觉关系,再以相同显示比例检查实际输出。
优化目标,也是编辑的一部分
接缝叠加图有用,因为它让隐藏选择可见。接受窄版图片前,应检查删了什么、哪些线弯了,以及熟悉比例是否改变。很小的数值成本,可能隐藏很大的视觉或事实后果,尤其当图片用于证据而非装饰时。
接缝裁剪吸引人,因为它说明图像编辑可以优化的不只是尺寸。它也说明目标必须谨慎选择。图片可以聪明地变小,同时更不忠实于观看者希望保留的内容。
为什么只找下一步最便宜的像素还不够
新增的四行五列网格是一张可以手算的成本图。贪心走法从首行最便宜的格子起步,再不断选择下一行可达邻居中最便宜的一个。并列时取左边,它会始终留在第一列,付出 1 + 1 + 9 + 9 = 20。但从稍贵的格子出发可能更好:沿第 2、3、3、3 列走,成本是 2 + 2 + 1 + 1 = 6。
动态规划会保留到达每个候选位置的最低累计成本,而不是马上锁定眼前最便宜的下一步。在累计成本图中,每个数字都包含最佳路径此前各行的费用。末行的最小值为六,回溯即可找到更好的路径。枚举全部 95 条允许的连通路径,证实它在此网格中是唯一最优解。这个小计算明确展示了“当前接缝最优”和“逐像素贪心”并不是一回事。
现在给第三行第三列增加 100 的保护惩罚。最优路径改为第 1、1、2、3 列,成本为 12,避开了该格;穷举同样证实新答案。附加惩罚是一项明确偏好,不是算法自行理解了图片。这个小例子不删除真实图像像素,只演示目标变化如何改变解;完整图像示例仍保留原先不加保护的对比度评分。

