Python 颜色阈值:为什么遮罩会根据指定的限制产生巨大的差异?

Python 颜色阈值:为什么遮罩会根据指定的限制产生巨大的差异?,python,opencv,computer-vision,image-masking,image-thresholding,Python,Opencv,Computer Vision,Image Masking,Image Thresholding,我们希望对RGB图像应用颜色阈值: 当我们将下限指定为[0,0,0]并将上限指定为[255,255,255]时,结果如下: 并且,当下限为[1,1,1]且上限为[255,255,255]时,结果如下: 为什么一个像素的差异会使掩蔽发生如此剧烈的变化 代码: 您的主要“问题”是Matplotlib的函数 在第一种情况下,只需遮罩图像中的所有像素,mask中的所有像素都有值255。当在此类图像上不使用任何参数而使用imshow时,将应用自动颜色缩放,以便将所有像素的对应绘图设置为0,因为所有像

我们希望对RGB图像应用颜色阈值:

当我们将下限指定为
[0,0,0]
并将上限指定为
[255,255,255]
时,结果如下:

并且,当下限为
[1,1,1]
且上限为
[255,255,255]
时,结果如下:

为什么一个像素的差异会使掩蔽发生如此剧烈的变化

代码:

您的主要“问题”是Matplotlib的函数

在第一种情况下,只需遮罩图像中的所有像素,
mask
中的所有像素都有值
255
。当在此类图像上不使用任何参数而使用
imshow
时,将应用自动颜色缩放,以便将所有像素的对应绘图设置为
0
,因为所有像素都具有相同的值。如果在
imshow
调用中显式设置
vmin
vmax
(请参见链接的文档页面),则会看到预期的全白色绘图

第二种情况中的微小更改会导致
掩码中的某些像素
0
,因此即使是标准
imshow
调用也会产生“正确”的颜色缩放,因为
掩码中的像素覆盖整个“范围”
[0…255]
,因为只有
0
255
的像素值

现在,要检测蓝色背景:在您的例子中,蓝色背景似乎有一个固定的RGB值,因此将OpenCV与标准BGR图像一起使用可能是合适的。一般来说,在我看来,对于颜色掩蔽,将图像转换为HSV/HSL颜色空间更复杂。有关简短的介绍,请选择适当的
H
S
L
值,请参阅我在前面的问题上所做的说明

我为上述比较和实际检测蓝色背景制作了一些代码:

导入cv2
将numpy作为np导入
将matplotlib.pyplot作为plt导入
image=cv2.imread('8au0O.jpg')
lower_blue=np.array([0,0,0])
upper_blue=np.array([255,255,255])
遮罩lb000=cv2.inRange(图像,下部蓝色,上部蓝色)
plt.图()
小地块(2、3、1)
plt.imshow(mask_lb000,cmap='gray')
plt.title('imshow没有明确的vmin,vmax')
plt.子地块(2、3、4)
plt.imshow(mask_lb000,cmap='gray',vmin=0,vmax=255)
plt.title('imshow带有显式vmin,vmax')
lower_blue=np.array([1,1,1])
upper_blue=np.array([255,255,255])
遮罩lb111=cv2.inRange(图像,下部蓝色,上部蓝色)
plt.子地块(2、3、2)
plt.imshow(mask_lb111,cmap='gray')
plt.title('imshow没有明确的vmin,vmax')
小地块(2、3、5)
plt.imshow(mask_lb111,cmap='gray',vmin=0,vmax=255)
plt.title('imshow带有显式vmin,vmax')
#检测HSL转换图像中的淡蓝色区域
#H值必须适当(参见HSL颜色空间),例如在[200…260]范围内
#L值可以是任意的(我们希望所有颜色介于亮蓝色和深蓝色之间),例如在[0.0…1.0]范围内
#S值必须高于某个阈值(我们至少需要一些饱和度),例如在[0.35…1.0]范围内
下_蓝=np.数组([np.圆形(200/2),np.圆形(0.00*255),np.圆形(0.35*255)])
上蓝=np.数组([np.圆形(260/2),np.圆形(1.00*255),np.圆形(1.00*255)])
遮罩lb=cv2.inRange(cv2.cvtColor(图像,cv2.COLOR\u BGR2HSV),下蓝,上蓝)
plt.子地块(2、3、3)
plt.imshow(蒙版,cmap='gray')
plt.title('imshow没有明确的vmin,vmax')
小地块(2、3、6)
plt.imshow(mask_lb,cmap='gray',vmin=0,vmax=255)
plt.title('imshow带有显式vmin,vmax')
plt.show()
这是生成的输出:

希望有帮助

您的主要“问题”是Matplotlib的函数

在第一种情况下,只需遮罩图像中的所有像素,
mask
中的所有像素都有值
255
。当在此类图像上不使用任何参数而使用
imshow
时,将应用自动颜色缩放,以便将所有像素的对应绘图设置为
0
,因为所有像素都具有相同的值。如果在
imshow
调用中显式设置
vmin
vmax
(请参见链接的文档页面),则会看到预期的全白色绘图

第二种情况中的微小更改会导致
掩码中的某些像素
0
,因此即使是标准
imshow
调用也会产生“正确”的颜色缩放,因为
掩码中的像素覆盖整个“范围”
[0…255]
,因为只有
0
255
的像素值

现在,要检测蓝色背景:在您的例子中,蓝色背景似乎有一个固定的RGB值,因此将OpenCV与标准BGR图像一起使用可能是合适的。一般来说,在我看来,对于颜色掩蔽,将图像转换为HSV/HSL颜色空间更复杂。有关简短的介绍,请选择适当的
H
S
L
值,请参阅我在前面的问题上所做的说明

我为上述比较和实际检测蓝色背景制作了一些代码:

导入cv2
将numpy作为np导入
将matplotlib.pyplot作为plt导入
image=cv2.imread('8au0O.jpg')
lower_blue=np.array([0,0,0])
upper_blue=np.array([255,255,255])
遮罩lb000=cv2.inRange(图像,下部蓝色,上部蓝色)
plt.图()
小地块(2、3、1)
plt.imshow(mask_lb000,cmap='gray')
plt.title('imshow没有明确的vmin,vmax')
plt.子地块(2、3、4)
plt.imshow(mask_lb000,cmap='gray',vmin=0,vmax=255)
plt.title('imshow带有显式vmin,vmax')
lower_blue=np.array([1,1,1])
upper_blue=np.array([255,255,255])
遮罩lb111=cv2.inRange(图像,下部蓝色,上部蓝色)
plt.子地块(2、3、2)
plt.imshow(mask_lb111,cmap='gray')
plt.title('imshow没有明确的vmin,vmax')
plt.子地块(2,3
lower_blue = np.array([0,0,0]) 
upper_blue = np.array([255,255,255])
mask = cv2.inRange(image_copy, lower_blue, upper_blue)
plt.imshow(mask,cmap='gray')