我正在尝试对opencv cv2图像进行多色阈值处理。我要解决的问题如下:

  • R,G,B每个都有一个“有效”列表
  • 如果一个像素的R,G,B均被认为有效,则使该像素(0,0,0),否则使其变为(255,255,255)

  • 例如
  • [221、180、50]被认为在R通道
  • 中有效
  • [23,18,2]被认为在G通道
  • 中有效
  • [84、22、48]被认为在B通道中有效

  • 然后,如果像素具有以下任何值(RGB顺序)
  • (221,23,84)
  • (221、23、22)
  • (221,23,48)
  • (221、18、84)
  • (221、18、22)
  • (221、18、48)
  • ...
  • (50,2,48)

  • 它将转换为(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)
    

    最佳答案

    请尝试以下方法:

    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长度相同的 bool(boolean) 数组,否则为False。它只是Python中in方法的向量化对应物。或简而言之:



    您可以对所有通道执行此操作,即检查第一个通道中B中的有效值,第二个中G并第三个中R。

    然后使用np.dstack将它们沿z方向堆叠。为什么选择z方向?因为我们要使用 BGR-BGR-BGR ... 格式。

    但是请记住,这是一维数组,因此我们使用X.reshape(img.shape)方法将其整形为原始图像形状。

    因此,现在您有了一个 bool(boolean) 掩码,如果有效,则为True,否则为False。

    一切都在代码的第一行。

    现在,您要查看有效的BGR组合。如果所有B,G,R分量均为True,则组合有效。因此,您在z方向上应用了np.all()。再次,您得到 bool(boolean) 面罩q

    q将是一个 bool(boolean) 掩码,其有效颜色为True,其他颜色为False。

    因此您将转换为整数数据类型,True-> 1和False-> 0

    然后将其乘以255。如果要反转图像,则可以使用np.bitwise_not

    关于python - OpenCV多色阈值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21843513/

    10-11 20:04