将中心像素值复制到块中的多数值

时间:2018-08-28 03:59:44

标签: python numpy image-processing

我有一个图像像素预测数组,其大小为9085x10852。我想在每个像素周围得到一个10x10的块。如果中心像素值与块中的多数像素值不同,则将中央像素值替换为多数值。谁能帮助我

3 个答案:

答案 0 :(得分:4)

由于您对问题的细节有些不确定/不一致,我想提出一个非常简单的替代解决方案,而不是Python格式,但太大了以致无法注释,这可以帮助您和其他人探索您是否真正想要这和您真正想要的-在任何人花大量时间编写Python之前。

我建议您使用 ImageMagick ,它已安装在大多数Linux发行版中,并且可用于macOS和Windows。因此,只需在端子中制作一个示例图像,该示例图像是黑色的,中间有一个白色正方形,如下所示:

convert -size 100x100 xc:black -fill white -draw "rectangle 10,10 90,90" test.png

enter image description here

现在尝试使用过滤器,您可以看到圆角是圆的:

convert test.png -statistic mode 10x10 result.png

enter image description here

现在尝试使用更大的“半径”

convert test.png -statistic mode 20x20 result.png

enter image description here

也许您可以尝试一下,看看它是否可以满足您的要求,然后再浪费任何时间来编写任何代码。

答案 1 :(得分:4)

一种可能的方法是定义一个用模式替换中心值的函数...

import numpy as np
from scipy.ndimage import generic_filter

def most_frequent(x):
    central = x[x.size//2] 
    values, counts = np.unique(x, return_counts=True)
    max_freq = counts.max()
    modes = values[counts == max_freq]
    if central in modes:
        return central
    else:
        return modes[0]

...并将此类函数传递给scipy.ndimage.generic_filter

演示

In [143]: r = 2

In [144]: block_size = (2*r + 1, 2*r + 1)

In [145]: block_size
Out[145]: (5, 5)

In [146]: np.random.seed(329)

In [147]: arr = np.random.randint(low=0, high=10, size=(6, 8), dtype=np.uint8)

In [148]: arr
Out[148]: 
array([[9, 6, 2, 2, 0, 5, 6, 4],
       [9, 7, 0, 2, 0, 5, 4, 2],
       [1, 3, 8, 1, 4, 6, 5, 2],
       [5, 1, 7, 8, 5, 7, 0, 2],
       [8, 1, 0, 5, 4, 5, 4, 5],
       [4, 1, 5, 3, 6, 9, 4, 3]], dtype=uint8)

In [149]: generic_filter(arr, function=most_frequent, 
     ...:                size=block_size, mode='constant', cval=np.nan)
     ...: 
Out[149]: 
array([[9, 2, 2, 2, 0, 2, 4, 5],
       [9, 1, 0, 2, 0, 2, 5, 2],
       [1, 1, 0, 5, 5, 5, 5, 5],
       [1, 1, 1, 5, 5, 5, 4, 5],
       [1, 1, 1, 5, 5, 5, 4, 5],
       [1, 1, 5, 5, 5, 5, 4, 4]], dtype=uint8)

请注意,此代码可能需要一段时间才能在9085×10852阵列上运行。

答案 2 :(得分:3)

我今天在scikit-image处寻找其他内容,如果您深入scikit-image.filters,然后再深入rank,您会发现modal()!请参阅文档here

我使用了与@Tonechas相同的随机种子来生成可比较的结果:

import numpy as np
from skimage.morphology import rectangle   # for Structuring Elements (e.g. disk, rectangle)
from skimage.filters.rank import modal     # the puppy we want

# Same seed for directly comparable results
np.random.seed(329)

# Sample array/image
arr = np.random.randint(low=0, high=10, size=(6, 8), dtype=np.uint8)

# Run the filter with a 5x5 rectangular Structuring Element
result = modal(arr,rectangle(5,5))

print(result)

array([[9, 2, 0, 0, 0, 2, 4, 5],
       [1, 1, 0, 0, 0, 2, 5, 2],
       [1, 1, 0, 5, 5, 5, 5, 5],
       [1, 1, 1, 5, 5, 5, 4, 5],
       [1, 1, 1, 1, 5, 5, 4, 5],
       [1, 1, 5, 5, 5, 5, 4, 4]], dtype=uint8)

关键字:Python,numpy,scikit,skimage,图像处理,过程图像,中值,众数,众数,模态,结构元素,形态,过滤器,过滤器,等级。