最佳縫合線能夠有效的去除拼接中運動物體移動出現的鬼影,如何尋找最佳縫合線對於圖像拼接去除鬼影比較的重要。尋找最佳縫合線涉及到比較重要的一個思想是動態規劃,尋找強度值最優的路徑。
關於強度值的計算,具體情況如下:
以上公式是重疊像素點的顏色值之差,是結構值之差。這裏的結構值計算採用Sobel算子,也可以考慮其他的邊緣檢測算子,其中x,y方向的算子如下:
最後利用動態規劃思想尋找最佳縫合線,步驟:
1、考慮強度值E的每一列都爲一條最佳縫合線,首先從第一行開始,累計添加下一行的強度值;
2、每一列強度值向下一行的左、中、右進行掃描,獲取最小的強度累計值,並記錄最小前度值的列號;
3、統計出強度值最小的一條最爲最佳縫合線。
4、最後根據最佳縫合線進行圖像的拼接融合,融合也可以採用改進加權平均融合。
直接看效果圖
重影圖
最佳縫合線融合圖
def optimal_seam_rule_value(self, I1, I2):
I1 = cv2.cvtColor(I1, cv2.COLOR_BGR2GRAY)
I2 = cv2.cvtColor(I2, cv2.COLOR_BGR2GRAY)
Sx = np.array([[-2, 0, 2], [-1, 0, 1], [-2, 0, 2]])
Sy = np.array([[-2, -1, -2], [0, 0, 0], [2, 1, 2]])
I1_Sx = cv2.filter2D(I1, -1, Sx)
I1_Sy = cv2.filter2D(I1, -1, Sy)
I2_Sx = cv2.filter2D(I2, -1, Sx)
I2_Sy = cv2.filter2D(I2, -1, Sy)
E_color = (I1 - I2) ** 2
E_geometry = (I1_Sx - I2_Sx) * (I1_Sy - I2_Sy)
E = E_color + E_geometry
return E.astype(float)
def optimal_seam_rule2(self, I1, I2):
E = self.optimal_seam_rule_value(I1, I2)
# optimal seam
paths_weight = E[0, 1:-1].reshape(1, -1) # Cumulative strength value
paths = np.arange(1, E.shape[1] - 1).reshape(1, -1) # save index
for i in range(1, E.shape[0]):
# boundary process
lefts_index = paths[-1, :] - 1
lefts_index[lefts_index < 0] = 0
rights_index = paths[-1, :] + 1
rights_index[rights_index > E.shape[1] - 1] = E.shape[1] - 1
mids_index = paths[-1, :]
mids_index[mids_index < 0] = 0
mids_index[mids_index > E.shape[1] - 1] = E.shape[1] - 1
# compute next row strength value(remove begin and end point)
lefts = E[i, lefts_index] + paths_weight[-1, :]
mids = E[i, paths[-1, :]] + paths_weight[-1, :]
rights = E[i, rights_index] + paths_weight[-1, :]
# return the index of min strength value
values_3direct = np.vstack((lefts, mids, rights))
index_args = np.argmin(values_3direct, axis=0) - 1 #
# next min strength value and index
weights = np.min(values_3direct, axis=0)
path_row = paths[-1, :] + index_args
paths_weight = np.insert(paths_weight, paths_weight.shape[0], values=weights, axis=0)
paths = np.insert(paths, paths.shape[0], values=path_row, axis=0)
# search min path
min_index = np.argmin(paths_weight[-1, :])
return paths[:, min_index]