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



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

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

然后,我通过阈值我的图像从中检索了一个蒙版以供进一步使用

掩码 = cv2.inRange(图像,低,向上)

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

现在的问题是,我如何才能以平滑的方式实现第二个条件,以便一个带有[0.4, 0.6, 0.4]的像素将被踢出,而一个带有[0.6, 0.62, 0.57]的像素将被保留(随机示例,我会自己调整参数)?将这两者组合在一起不需要对整个图像进行及时迭代的最流畅方法是什么?

谢谢很多,这将有很大帮助!

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

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

演示

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

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)

最新更新