(基于接缝裁剪(seam carving)的图像压缩)给定一幅彩色图像,它由一个
m
×
n
m×n
m×n的像素数组
A
[
1..
m
,
1..
n
]
A[1..m, 1..n]
A[1..m,1..n]构成,每个像素是一个红绿蓝(RGB)亮度的三元组。假定我们希望轻度压缩这幅图像。具体来说,我们希望从每一行中删除一个像素,使得图像变窄一个像素。但为了避免影响视觉效果,我们要求相邻两行中删除的像素必须位于同一列或相邻列。也就是说,删除的像素构成从顶端行到底端行的一条“接缝”(seam),相邻像素均在垂直或对角线方向上相邻。
a. 证明:可能的接缝的数量是
m
m
m的指数函数,假定
n
>
1
n > 1
n>1。
b. 假定现在对每个像素
A
[
i
,
j
]
A[i, j]
A[i,j],我们都已计算出一个实型的“破坏度”
d
[
i
,
j
]
d[i, j]
d[i,j],表示删除像素
A
[
i
,
j
]
A[i, j]
A[i,j]对图像可视效果的破坏程序。直观地,一个像素的破坏度越低,它与相邻像素的相似度越高。再假定一条接缝的破坏度定义为它包含的像素的破坏度之和。设计算法,寻找破坏度最低的接缝。分析算法的时间复杂度。
解
a.
从第一行开始依次到最后一行选择删除点。第一行的删除点可以任意选择,即有
n
n
n种选择。由于相邻两行的删除点也必须相邻,所以从第二行开始的每一行,删除点要么有2种选择,要么有3种选择,如下图所示。删除点有2种选择的情况出现在上一行的删除点为行首点或行末点的时候。
根据以上分析,采用计数原理即可得到一个
m
×
n
m×n
m×n的图像的可能的接缝的数量在
n
•
2
m
−
1
n•2^{m-1}
n•2m−1和
n
•
3
m
−
1
n•3^{m-1}
n•3m−1之间。所以,可能的接缝数量是
m
m
m的指数函数。
b.
本题相对简单。用
s
d
[
i
,
j
]
sd[i, j]
sd[i,j]表示以点
[
i
,
j
]
[i, j]
[i,j]结尾的接缝的破坏度。以点
[
i
,
j
]
[i, j]
[i,j]结尾的意思是,该条接缝只包含
1
1
1~
i
i
i行,后面的行不考虑,并且第
i
i
i行的删除点是
[
i
,
j
]
[i, j]
[i,j]。
对于一条以点
[
i
,
j
]
[i, j]
[i,j]结尾的接缝,第
i
−
1
i-1
i−1行的删除点有2种或3种选择。如果第
i
−
1
i-1
i−1行的删除点有3种选择,那么删除点可以是
[
i
−
1
,
j
−
1
]
[i-1, j-1]
[i−1,j−1]、
[
i
−
1
,
j
]
[i-1, j]
[i−1,j]或
[
i
−
1
,
j
+
1
]
[i-1, j+1]
[i−1,j+1]。从以第
i
−
1
i-1
i−1行的这3个点结尾的接缝中选择破坏度最小的,再加上点
[
i
,
j
]
[i, j]
[i,j],即可得到以点
[
i
,
j
]
[i, j]
[i,j]结尾的破坏度最小的接缝。再用
l
i
n
k
[
i
,
j
]
link[i, j]
link[i,j]表示第
i
−
1
i-1
i−1行选择的是哪个点,
−
1
-1
−1表示选择
[
i
−
1
,
j
−
1
]
[i-1, j-1]
[i−1,j−1],
0
0
0表示选择
[
i
−
1
,
j
]
[i-1, j]
[i−1,j],
+
1
+1
+1表示
[
i
−
1
,
j
+
1
]
[i-1, j+1]
[i−1,j+1]。
第
i
−
1
i-1
i−1行的删除点有2种选择的情况也可以做同样的分析。由此可以得到以下递归式。
最后,我们要选择最后一行中最小的
s
d
[
m
,
j
]
sd[m, j]
sd[m,j]的对应的接缝。
很容易得出,该算法的时间复杂度为
Θ
(
m
n
)
Θ(mn)
Θ(mn)。
以下是本题相关的code链接。
https://github.com/yangtzhou2012/Introduction_to_Algorithms_3rd/tree/master/Chapter15/Problems/Problem_15-8