Programming Assignment 2: Seam Carving
1. 题目阅读
这个题是课上讲过的,每次删除能量最小的一条路径。
Seam Carving是一种图像处理方法。在裁剪图片尺寸的同时,保留图像中最有趣的特征。横向缩减时,删除横向上的最短路径,纵向裁剪时,删除纵向上的最短路径。
整个方法的流程
- 符号,图像的像素从0开始计数。 矩阵的二维坐标,第一个表示列,第二个表示行!!!!!
- 能量计算,计算每个点的能量,越高越重要。这里要实现双梯度能量方程。
- 接缝识别。找到一条能量最小的接缝,和最短路径方法相似,不同之处在于,权重在顶点,而不在路径;路径从顶到底;图是无环的。每个顶点只与其左下,下方,右下三个顶点连接。
- 接缝删除。最后一步就是删除接缝上的每一个像素。
SeamCarver API
需要实现构造函数,能量计算函数,查找(删除)横向(纵向)的接缝。
能量计算函数
需要使用双梯度能量方程。懒得编辑公式,具体计算公式见原网站。根据像素四周的点的RGB值计算
寻找接缝
返回一位数组,表示需要删除的像素在每一行的位置。如果有相同的最小能量,只需要返回其中任意一个。
2.题目分析
实现顺序:
- 读取函数
- 能量计算函数
- 最短路径查找函数
- 删除
构造函数
使用algs4提供的picture构造,这里要求是mutate,就不需要再单独拷贝了。然后计算图片的宽和高。
能量计算函数
- 填充边界为1000
- 循环计算每个像素的能量,Rx,Gx这些实现为单独的函数
最短能量
1. 构造图,因为这里权重在点上,做个转变,认为v到w的edge的权重为v点的权重,这样就可以使用现有的方法了。 2. 为了使用最短路径算法,这里认为顶端的点都连接到一个虚拟起点,权重为0。末端点都连接到一个虚拟终点,权重问0。删除的点权重设置为1000. 自己实现最短路径查找,这个是一个DAG,先拓补排序,然后按照这个顺序找。
认为第一行为一个点和第二行所有点都相连。最后一个行也是。
只需要实现一个方向,另一个方向可以先转置矩阵,再用前一个实现。(这样效率低了,但是程序好写,可以想效率高,又优雅的方法)
这里的具体实现。因为接缝只跟能量矩阵相关,那么构造一个转置的能量矩阵,然后写一个函数,对能量矩阵进行查找。横向和纵向只需要构造不同的能量矩阵,然后传给函数。这样就不需要将图片转置。
将能量数组用二位数组表示,需要实现能量数组的DFS,求出拓补排序。然后根据拓补排序的顺序,对能量数组进行松弛。然后从最后一行反推回第一行,就是seam。
删除
将seam之外的点移动到新的数组,同时将seam之外点的能量移动到新的能量数组,然后重新计算seam上下左右点的能量。
新建立一个空白图片,将原图片除了删除点之外的都拷贝进去。