第二种滤除非黑色像素的方法的实现

Implementation of second way to filter out non-black pixels

所以我正在分析相机图像并想从中检索黑色字母。首先,我为所有通道定义了阈值并将它们应用于图像,例如

low = [0, 0, 0]
up = [0.42, 0.42, 0.42]

然后,我通过使用

对我的图像进行阈值化,从中检索了一个掩码以供进一步使用

mask = cv2.inRange(图像,低,上)

现在这一直有效,直到我发现不同的光照条件让我 运行 陷入困境。例如,如果图像更亮,我可以将阈值上限调整为 0.65,这足以在我分析的所有情况下区分黑白。但是:现在其他颜色会产生问题,因为在这个区间内还有更多颜色。我认为将所有可能值限制为灰色的第二个条件会起作用,即只允许每个像素的三个通道的值之间存在一定差异的条件。

现在的问题是,我怎样才能顺利地实现第二个条件,这样 [0.4, 0.6, 0.4] 的像素将被踢出,而 [0.6, 0.62, 0.57] 的像素将留在(随机示例,我会自己调整参数)?什么是不需要对整个图像进行及时迭代的最平滑的组合这两者的方法?

非常感谢,这会很有帮助!

跨通道的强度范围是轴 2 上最大和最小强度之间的差异。您可以利用 NumPy broadcasting 开发完全矢量化的解决方案:

import numpy as np

def in_range(rgb, rgb_min, rgb_max):
    masks = np.logical_and(rgb >= rgb_min, rgb <= rgb_max)
    return np.all(masks, axis=2)

def small_deviation(rgb, rgb_dev):
    return (np.max(rgb, axis=2) - np.min(rgb, axis=2)) < rgb_dev

演示

在下面的示例 运行 中,我使用随机生成的 4 行和 5 列的 3 通道图像。

In [80]: np.random.seed(0)

In [81]: image = np.random.random(size=(4, 5, 3))

In [82]: np.set_printoptions(precision=2)

In [83]: np.rollaxis(image, 2, 0)
Out[83]: 
array([[[ 0.55,  0.54,  0.44,  0.38,  0.57],
        [ 0.09,  0.78,  0.8 ,  0.12,  0.94],
        [ 0.26,  0.57,  0.61,  0.68,  0.7 ],
        [ 0.67,  0.32,  0.44,  0.21,  0.25]],

       [[ 0.72,  0.42,  0.89,  0.79,  0.93],
        [ 0.02,  0.87,  0.46,  0.64,  0.52],
        [ 0.77,  0.02,  0.62,  0.36,  0.06],
        [ 0.21,  0.36,  0.99,  0.16,  0.47]],

       [[ 0.6 ,  0.65,  0.96,  0.53,  0.07],
        [ 0.83,  0.98,  0.78,  0.14,  0.41],
        [ 0.46,  0.62,  0.94,  0.44,  0.67],
        [ 0.13,  0.57,  0.1 ,  0.65,  0.24]]])

阈值设置为 low = [.0, .0, .0]up = [.6, .5, 0.7]dev = .4

In [84]: low = [.0, .0, .0]

In [85]: up = [.6, .5, 0.7]

In [86]: mask1 = in_range(image, low, up)

In [87]: mask1
Out[87]: 
array([[False,  True, False, False, False],
       [False, False, False, False, False],
       [False,  True, False, False, False],
       [False,  True, False,  True,  True]], dtype=bool)

In [88]: dev = .4

In [89]: mask2 = small_deviation(image, dev)

In [90]: mask2
Out[90]: 
array([[ True,  True, False, False, False],
       [False,  True,  True, False, False],
       [False, False,  True,  True, False],
       [False,  True, False, False,  True]], dtype=bool)

In [91]: mask = np.logical_and(mask1, mask2)

In [92]: mask
Out[92]: 
array([[False,  True, False, False, False],
       [False, False, False, False, False],
       [False, False, False, False, False],
       [False,  True, False, False,  True]], dtype=bool)