如何在Python中实现Matlab bwmorph(bw,'remove')

时间:2017-02-21 02:05:22

标签: python image matlab image-processing boundary

我正在尝试在Python中实现Matlab函数bwmorph(bw,'remove')。如果所有4个连接的相邻像素都是1,则此函数通过将像素设置为0来移除内部像素。生成的图像应返回边界像素。我写了一段代码,但我不确定这是不是这样做。

# neighbors() function returns the values of the 4-connected neighbors
# bwmorph() function returns the input image with only the boundary pixels

def neighbors(input_matrix,input_array):
    indexRow = input_array[0]
    indexCol = input_array[1]
    output_array = []
    output_array[0] = input_matrix[indexRow - 1,indexCol]
    output_array[1] = input_matrix[indexRow,indexCol + 1]
    output_array[2] = input_matrix[indexRow + 1,indexCol]
    output_array[3] = input_matrix[indexRow,indexCol - 1]
    return output_array


def bwmorph(input_matrix):
    output_matrix = input_matrix.copy()
    nRows,nCols = input_matrix.shape
    for indexRow in range(0,nRows):
        for indexCol in range(0,nCols):
            center_pixel = [indexRow,indexCol]
            neighbor_array = neighbors(output_matrix,center_pixel)
            if neighbor_array == [1,1,1,1]:
                output_matrix[indexRow,indexCol] = 0
    return output_matrix

enter image description here

1 个答案:

答案 0 :(得分:3)

由于您使用的是NumPy数组,我的一个建议是更改if语句以使用numpy.all来检查邻居的所有值是否都为非零。此外,您应确保输入是单通道图像。由于彩色灰度图像在所有通道中共享所有相同的值,因此只需提取第一个通道。您的注释表示彩色图像,因此请确保执行此操作。您还在使用输出矩阵,该矩阵在检查时在循环中被修改。您需要使用未修改的版本。这也是你获得空白输出的原因。

def bwmorph(input_matrix):
    output_matrix = input_matrix.copy()
    # Change. Ensure single channel
    if len(output_matrix.shape) == 3:
        output_matrix = output_matrix[:, :, 0]
    nRows,nCols = output_matrix.shape # Change
    orig = output_matrix.copy() # Need another one for checking 
    for indexRow in range(0,nRows): 
        for indexCol in range(0,nCols): 
            center_pixel = [indexRow,indexCol] 
            neighbor_array = neighbors(orig, center_pixel) # Change to use unmodified image
            if np.all(neighbor_array): # Change
                output_matrix[indexRow,indexCol] = 0 

    return output_matrix

此外,我对您的代码提出的一个小问题是,在确定四个邻居时,您不会检查超出边界的条件。您提供的测试图像不会引发错误,因为您没有任何白色的边框像素。如果沿任何边框都有像素,则无法检查所有四个邻居。但是,减轻这种情况的一种方法是使用模运算符来循环:

def neighbors(input_matrix,input_array):
    (rows, cols) = input_matrix.shape[:2] # New
    indexRow = input_array[0]
    indexCol = input_array[1]
    output_array = [0] * 4 # New - I like pre-allocating

    # Edit
    output_array[0] = input_matrix[(indexRow - 1) % rows,indexCol]
    output_array[1] = input_matrix[indexRow,(indexCol + 1) % cols]
    output_array[2] = input_matrix[(indexRow + 1) % rows,indexCol]
    output_array[3] = input_matrix[indexRow,(indexCol - 1) % cols]
    return output_array