我的小问题
如何检测下图中的黑点? (我只粘贴了一张测试图像,以使问题看起来紧凑。可以找到更多图像 →here←)。
我的长问题
如上图,底色大致为蓝色,圆点颜色为“黑色”。如果选择一个黑色像素并用 RGB 测量它的颜色,该值可以是 (0, 44, 65) 或 (14, 69, 89)....因此,我们不能设置一个范围来判断像素是黑点的一部分还是背景的一部分。
我测试了10张不同颜色的图像,但我希望我能找到一种方法来检测更复杂的背景中的黑点,这些背景可能由三种或更多种颜色组成,只要人眼可以轻松识别黑点.可以忽略一些非常小或模糊的点。
以前的工作
上个月,我问过a similar question在 stackoverflow,但还没有一个完美的解决方案,虽然有一些很好的答案。如果您有兴趣,请查找有关我的工作的更多详细信息。
以下是我尝试过的方法:
转换为图像的灰度或亮度。困难是我找不到自适应阈值来进行二值化。显然,将彩色图像转为灰度或使用亮度 (HSV) 会丢失很多有用的信息。 Otsu algorithm计算自适应阈值也不起作用。
计算 RGB 直方图。在我的最后一个问题中,natan 的方法是通过直方图来估计黑色。省时,但是自适应阈值也是个问题。
聚类。我试过k-means clustering并发现它对于只有一种颜色的背景非常有效。不足之处(看我自己的回答)是需要提前设置聚类中心的个数,但不知道后台会怎么样。而且,它太慢了!我的应用程序用于在 iPhone 上进行实时捕获,现在它可以使用 k-means 每秒处理 7~8 帧(我认为 20 FPS 很好)。
总结
我认为不仅相似的颜色而且相邻的像素都应该“聚集”或“合并”以提取黑点。请指导我正确的方法来解决我的问题。任何建议或算法将不胜感激。天下没有免费的午餐,但我希望在成本和准确性之间取得更好的权衡。
最佳答案
通过使用 rgb2hsv
转换为 HSV 颜色空间,我能够获得一些相当不错的首次通过结果。 ,然后使用图像处理工具箱函数 imopen
和 imregionalmin
在值(value) channel 上:
rgb = imread('6abIc.jpg');
hsv = rgb2hsv(rgb);
openimg = imopen(hsv(:, :, 3), strel('disk', 11));
mask = imregionalmin(openimg);
imshow(rgb);
hold on;
[r, c] = find(mask);
plot(c, r, 'r.');
以及生成的图像(对于问题中的图像和从您的链接中选择的图像):
您可以看到一些误报和遗漏点,以及一些标有多个点的点,但一些改进(例如修改在开始步骤中使用的结构元素)可以清理一些这些。
关于algorithm - 从彩色背景中检测黑点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23999205/