【发布时间】:2014-02-18 15:24:57
【问题描述】:
我正在尝试对 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,这两种解决方案的性能提升超过了 1500 倍。
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)
【问题讨论】:
-
首先,使用
xrange而不是range。后者实际上构建了一个指定大小的整个列表,然后您对其进行迭代,而前者返回一个生成器,它不必预先计算整个列表,并且允许您对其进行迭代。 -
嗨@SchighSchagh,感谢您的建议。使用
range的 C 实现肯定有帮助。我认为我的瓶颈是访问和更改 python 中的每个像素。我认为如果有一个 api 允许我将其推送到 numpy 或 opencv 的 C 实现中会大大加快速度。 -
[221,18,48] 也有效吗?
-
嗨@AbidRahmanK 是的。