找到边界之间错误的彩色像素

时间:2016-10-20 14:03:29

标签: python numpy colors

在图像中,我有大量不同颜色的细胞被黑色边界隔开。然而,边界没有完美绘制,现在一些单元格有一些错误颜色的像素(每个单元格只应包含1种颜色)。

在下图中,我已经包围了错误颜色的像素。左上角包围的蓝色像素应为灰色,其他三个点中包围的灰色像素应为蓝色。

cells

问题:如何找到错误的彩色像素,以便用正确的颜色替换它们?

目前我正在使用 Python NumPy 将图像加载到一个数组中,并使用双重for循环逐行检查每个像素。

我当前的方法涉及检查与其直接对齐的像素的每个像素(行+1,行-1,列+1和列-1)。如果它们是不同的非黑色,我会检查像素的边界像素,如果它们的颜色与原始像素不同,那么我会改变原始像素的颜色。

但是,如果有多个不正确的像素彼此相邻,则无法正常工作,从而产生以下图像:

wrong

以下是我使用的脚本。我正在寻找一种方法来改进它,或者完全不同的算法。代码所需的图像就在它下面。我已经在代码中将其名称与stackoverflow的名称相匹配。

import Image
import numpy as np

BLACK = (0,0,0)

im = Image.open("3gOg0.png").convert('RGB')
im.load()
im_array = np.asarray(im, dtype="int32")
(height, width, dim) = im_array.shape
newim_array = np.array(im_array)

for row in range(height):
    for col in range(width):
        rgb = tuple(im_array[row,col])
        if rgb == BLACK:
            continue

        n = tuple(im_array[row-1,col])
        s = tuple(im_array[row+1,col])
        e = tuple(im_array[row,col+1])
        w = tuple(im_array[row,col-1])

        if n != BLACK and n != rgb:
            nn = tuple(im_array[row-2,col])
            ne = tuple(im_array[row-1,col+1])
            nw = tuple(im_array[row-1,col-1])
            if (nn != BLACK and nn != rgb) or (nw != BLACK and nw != rgb) or (ne != BLACK and ne != rgb):
                newim_array[row,col] = n
                continue

        if s != BLACK and s != rgb:
            ss = tuple(im_array[row+2,col])
            se = tuple(im_array[row+1,col+1])
            sw = tuple(im_array[row+1,col-1])
            if (ss != BLACK and ss != rgb) or (sw != BLACK and sw != rgb) or (se != BLACK and se != rgb):
                newim_array[row,col] = s
                continue

        if e != BLACK and e != rgb:
            ee = tuple(im_array[row,col+2])
            ne = tuple(im_array[row-1,col+1])
            se = tuple(im_array[row+1,col+1])
            if (ee != BLACK and ee != rgb) or (se != BLACK and se != rgb) or (ne != BLACK and ne != rgb):
                newim_array[row,col] = e
                continue

        if w != BLACK and w != rgb:
            ww = tuple(im_array[row,col-2])
            nw = tuple(im_array[row-1,col-1])
            sw = tuple(im_array[row+1,col-1])
            if (ww != BLACK and ww != rgb) or (nw != BLACK and nw != rgb) or (sw != BLACK and sw != rgb):
                newim_array[row,col] = w

im2 = Image.fromarray(np.uint8(newim_array))
im2.save("fix.png")

这是正确的非缩放大小的示例图像:

enter image description here

2 个答案:

答案 0 :(得分:2)

听起来你有两个问题:

  1. 这些地区是什么?
  2. 每种颜色应该是什么颜色?
  3. 要查找区域,并在其中填充当前最常见的颜色:

    For each non-black pixel not visited yet:
        Start a new region; initialize a counter for each color
        Recursively:
            Mark the pixel as in-region
            Increment the counter for that color
            Visit each of the adjacent pixels that are not black nor in-region
        When done, 
            Color all of the in-region pixels to the color with the highest count, and mark them as visited
    

答案 1 :(得分:1)

我会采用连接组件标签方法..虽然有很多方法可以给猫皮肤......

  1. 仅提取连接组件蒙版的黑线
  2. 找到4个连接的白色区域(connected component labeling
  3. 对于每个连接的区域,找到最常出现的颜色
  4. 将整个区域设置为该颜色
  5. 示例实施:

    import numpy as np
    from scipy import ndimage
    from scipy import stats
    
    #input array assuming 0 for black 1 for blue and 2 for purple
    arr = np.array(...)
    
    labeled, labels = ndimage.measurements.label(arr != 0, #connect non-black regions
                                                 structure=[[0,1,0],
                                                            [1,1,1],
                                                            [0,1,0]]) #this is the default, but we'll specify it explicitly anyway...
    
    for labelnum in range(1, labels+1):
        region = arr[np.where(labeled==labelnum)] #get a flat list of the members of that region
        mode = stats.mode(region) #find the most occurring color
        arr[np.where(labeled==labelnum)] = mode #set that color to all pixels in that region