SeamCarving算法实现
核心思想
每次选择梯度变化最小的一个路径删除
梯度的计算
g(x,y)=|dI/dx|+|dI/dy|
根据这个公式可以用sobel算子求得每个位置的梯度
找最小权值路径
利用动态规划选取最小路径。由于是考虑8联通的情况,每个位置的值只会传到下方的三个位置。考虑水平方向切割,(x,y)上的值只会传递到(x,y-1),(x,y),(x,y+1)三个位置上。因此可以将每一行看成一个向量用numpy来处理来加快处理速度。1
2
3
4
5
6
7
8
9
10
11
12
13def get_M(self, e):
M = e.copy()
w, h = e.shape
v1 = np.zeros(h,np.float)
v1[0]=float('inf')
v2 = np.zeros(h,np.float)
v2[h-1]=float('inf')
for i in range(1, w):
v1[1:h] = M[i-1, 0:h-1]
v2[0:h-1] = M[i-1, 1: h]
M[i] = np.min(np.stack([v1, v2, M[i-1]], axis=1), axis=1)+M[i]
return M
关于两个方向
当一个方向的切割代码完成,切割另一个方向时可以现将图像转置,利用已经写好的操作切割后再转置回来。
1 | def carve_col(self, src): |
完整代码
1 | import numpy as np |