python最佳缝合线(Image Stitching 2)

      最佳缝合线能够有效的去除拼接中运动物体移动出现的鬼影,如何寻找最佳缝合线对于图像拼接去除鬼影比较的重要。寻找最佳缝合线涉及到比较重要的一个思想是动态规划,寻找强度值最优的路径。

      关于强度值的计算,具体情况如下:

E(x,y) = E_{c}(x,y)^{2}+E_{g}(x,y)

以上公式E_{c}是重叠像素点的颜色值之差,E_{g}是结构值之差。这里的结构值计算采用Sobel算子,也可以考虑其他的边缘检测算子,其中x,y方向的算子如下:

S_{x}=\begin{bmatrix} -2 \;\;\;\; 0 \;\;\;\; 2 \\ -1 \;\;\;\; 0 \;\;\;\; 1 \\ -2 \;\;\;\; 0 \;\;\;\; 2 \\ \end{bmatrix}                    S_{y}=\begin{bmatrix} -2 \; -1 \; -2\\ 0 \;\;\;\;\; 0 \;\;\;\;\; 0 \\ 2 \;\;\;\;\; 1 \;\;\;\;\; 2 \end{bmatrix}

E_{g}=Diff(I_{1}x, I_{2}x)\cdot Diff(I_{1}y, I_{2}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]

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章