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

How to implement Matlab bwmorph(bw,'remove') in Python

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

# 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

由于您使用的是 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

此外,我对您的代码有一点不满,就是您在确定四个邻居时没有检查 out-of-boundary 条件。您提供的测试图像不会引发错误,因为您没有任何白色的边框像素。如果沿着任何边界有一个像素,则不可能检查所有四个邻居。但是,缓解这种情况的一种方法可能是使用模运算符环绕:

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