今天首次接触了图像编辑中的seam carving知识,感觉挺神奇的。虽然我自己可能理解的不是很深刻,但是记录下来,总是好的。
seam carving直接翻译过来是“线裁剪”的意思。它的主要用途是对图像进行缩放。不同于传统的按比例缩放图像的方式,seam carving的是内容感知的,它充分考虑了图像中像素的重要性,通过删除或增加seam线来实现图像尺寸的调整。它在缩放不是特别大的情况下,能够很好的保护图像中的显著物体。
具体来说,seam carving定义了穿过整幅图像的像素线(即seam),它是由图像中最低能量的像素组成的。如左下图中画出了一个横向的seam和一个纵向的seam。
接下来需要说明的是,seam的形成。seam是有图像中,最不重要的像素组成的。因此,首先要对图像中的像素点的重要性进行定义。给定一幅n x m的图像I,它的能量函数定义为:
在一幅图像中,某一像素点的能量越大,则它也越重要。换言之,像素的能量越小,它在图像中就越不重要。seam线(或缝合线)就是由图像中那些不重要的像素点组成的。
对于上述n x m 的图像I, 一个竖直的seam线定义如下:
这个公式乍看起来很复杂,其实际的意义很容易理解。式中i表示第 i 行,即像素的纵坐标, x(i)表示第 i 行中的某个像素的横坐标值。也就是说,一个竖直的seam线包含 n 行(图像是 n 行乘 m 列的),每行中取出一个像素点。而后面的约束表示的意思是相邻两行的像素点之间是相邻的(八连通领域),这样限制的作用是,去掉seam线之后,画面看起来不会出现很跳跃的感觉,直观表示如下图所示,(i,j)的前一点只能来自(i-1,j-1),(i-1,j),(i-1,j+1)中的某一点。
对于给定的能量函数 e( I ),可以将缝合线的代价函数定义:
当前要选择的缝合线即为代价函数值最小的缝合线。设当前状态下最优的缝合线为 S*:
应当利用动态规划(Dynamic Programming)来求解寻找最低代价的、竖直的、八连通的缝合线上所有像素点的问题。设将当前图像的累积最小能量存储在 M 矩阵里,而将图像的能量函数值存储在 NRG 矩阵里。然后把能量函数 NRG 的首行作为 M 的首行初始值。把当前行的能量函数值加上 M [i 1][ j 1]、M [i 1][ j]和M [i 1][ j1]中的最小值作为 M 下一行的值。通过存储以前计算的结果,可以对缝合线进行多次计算。下面以计算竖直缝合线为例来说明该算法。可以利用下式来填充 M 来计算最优缝合线: