我正在尝试在opencv cv2图像上进行多色阈值处理。我试图解决的问题如下:
例如
然后,如果像素具有以下任何值(RGB顺序)
它将转换为(0,0,0),否则(255,255,255)
目前,我正在使用嵌套for循环:
for x in range(width):
for y in range(height):
imcv[y, x] = threshold(imcv[y, x])
其中threshold
函数执行上述逻辑。请注意,虽然我就地执行了此操作,但不需要进行就地转换。
我目前使用的方法有效,但非常慢。我相信在OpenCV / Numpy中必须有一个更好的方法。我对这两个框架都很陌生,无法弄清楚如何。
我研究了OpenCV阈值处理功能,看来它们只能在单通道灰度图像上工作,而且范围也需要连续范围。我需要的是在离散值上对所有3个通道进行阈值处理。我想有一个自定义函数需要传入,但我无法在他们的文档中找到合适的API。
我也查找了可以使用的numpy API,例如ufunc
。看来我无法实现我在这里使用它,或者我没有看到如何。
感谢任何帮助。
编辑:
感谢AbidRahmanK和HYRY,两种解决方案在性能上都取得了超过x1500的改进。
ncalls tottime percall cumtime percall filename:lineno(function)
1 1.576 1.576 1.576 1.576 test.py:48(preprocess_cv2_image)
1 0.000 0.000 0.001 0.001 test.py:79(preprocess_cv2_image3)
1 0.000 0.000 0.001 0.001 test.py:66(preprocess_cv2_image2)
答案 0 :(得分:2)
请试试这个:
z1 = np.dstack([np.in1d(img[...,0],B),np.in1d(img[...,1],G),np.in1d(img[...,2],R)]).reshape(img.shape)
q = np.all(z1,axis=2)
out = np.uint8(q)*255
如果该元素在b中,则 np.in1d(a,b)
为您提供与True
相同长度的布尔数组,否则为False
。它只是Python中in
方法的矢量化对应物。或者简而言之:
np.in1d(a,b)< ==> [对于我来说,如果我在其他地方,则为真假)
您对所有通道执行此操作,即检查第一个通道中B中的有效值,第二个带G,第三个带R。
然后使用np.dstack
将它们沿z方向堆叠。为什么z方向?因为我们想要 BGR-BGR-BGR ... 格式。
但请记住,这是一维数组,因此我们使用X.reshape(img.shape)
方法将其重塑为原始图像形状。
所以现在你有一个布尔掩码,如果有效则为True,否则为False。
这一切都在第一行代码中。
现在您想要查看有效的BGR组合。如果所有B,G,R分量都为True,则组合有效。所以你在z方向上应用np.all()。再次得到一个布尔掩码q
q将是一个布尔掩码,有效颜色为True,其他为False。
所以你转换为整数数据类型,True - > 1和假 - > 0
然后将它乘以255.如果您想要倒置图像,可以使用np.bitwise_not
答案 1 :(得分:1)
你可以为R,G,B制作三个布尔数组,如果该值对R有效,那么R[value]
为True,那么你可以使用Rm[img[:, :, 2]] & Gm[img[:, :, 1]] & Bm[img[:, :, 0]]
得到结果:
import numpy as np
img = np.random.randint(0, 256, (2000, 2000, 3))
def make_mask(idx):
b = np.zeros(256, np.bool)
b[idx] = True
return b
R = [221, 180, 50]
G = [23, 18, 2]
B = [84, 22, 48]
Rm, Gm, Bm = [make_mask(v) for v in [R, G, B]]
a = Rm[img[:, :, 2]] & Gm[img[:, :, 1]] & Bm[img[:, :, 0]]
最后,要获得结果图像:
v = np.array([[255,255,255], [0,0,0]], np.uint8)
v[a.astype(np.uint8)]