使用OpenCV按颜色对像素进行排序

5
我开始一个有关检测的项目。 我的想法是对一幅图像(Mat)中的每个像素进行排名。 然后,我将能够确定哪种颜色是主导的。
困难在于,某种颜色并不唯一。例如,绿色是rgb(0,255,0),但也几乎是rgb(10,240,20)。
我的排名目标是找出几乎相同颜色的像素。然后,通过百分比,我认为我可以定位我的对象。
因此,我的问题是:是否有一种方法按颜色对像素进行排名?
非常感谢您的回答。

你是想在图像中找到一个物体吗?如果你能展示一下你的图像,那会是一个好主意。 - Mark Setchell
1
一张静止的画面可以告诉我们关于物体的大小、形状、质地、颜色、光线或背景的重要信息... - Mark Setchell
@William:我尝试使用直方图,但并不完全符合我的要求。我将继续使用23PointsNorth提出的解决方案2。 - Stalyon
@MarkSetchell: 实际上,我想在视频中识别鱼类。水族馆里大约有 6/7 条鱼,目标是当我们点击它时能够识别出哪一条鱼。 - Stalyon
我想过这个,但是有光线反射和小波浪。所以我不确定背景减法在这里是否有效,你觉得呢? - Stalyon
显示剩余4条评论
2个回答

3

没有一种直接的方法对像素颜色进行排名,但是你可以找到最显著的近似值。

有几种方法可以做到这一点:

  1. 你可以为每种颜色通道计算直方图 - 分割成 R、G、B 并计算直方图。然后你可以看到结果图形的峰值在哪里。
  2. 如果你以 k-means 聚类图像中的像素 - 换句话说,将每个像素表示为具有坐标 (R、G、B) 的 3D 点。那么你可以将像素分成出现次数最多的 k 种颜色。
  3. 如果你将图像调整大小为 1x1 像素图像,则可以找到所有像素值的平均值。如果有一种主导颜色,在这种情况下大多数像素相互接近,它会给出一个很好的近似值。

然而,这些都是近似值。你最好的选择是使用 k-means,并找到元素最多或最密集的聚类。

如果您正在寻找一种定位具有特定颜色的对象的方法,可以使用最大似然估计。这类似于这个,它被用于从卫星图像中分类不同的物体,如草地、汽车、建筑和人行道。您可以使用单一颜色,并得到一个热力图,显示对象在可能性方面(即该像素属于您的对象的概率百分比)的位置。


点2是我可以探索的非常好的方法。谢谢23pointsNorth!问题是有时候我需要退出几种颜色(它们是主导的)。 - Stalyon
能否深入解释一下您提到的第二点?我尝试了一些方法,但处理一张120x75的图像需要7秒左右,速度太慢了。 - Stalyon
@Stalyon,我有一些演示,稍后会附上一些简短的说明链接。这不应该花费太多时间。即使对于VGA(640x480),它通常也可以快速运行。 - 23pointsNorth
我对此很感兴趣。 - Stalyon

1
在普通的图像中,涉及到许多颜色。为了更好地平均携带几乎相同颜色的像素,可以使用颜色量化来减少图像中的颜色数量,使用K-mean聚类等技术实现。这里可以通过Python代码进行最佳解释:

https://www.pyimagesearch.com/2014/07/07/color-quantization-opencv-using-k-means-clustering/

在成功量化之后,您只需尝试以下代码,根据图像中颜色的频率对其进行排名。
top_n_colors = []
n = 3
colors_count = {}
(channel_b, channel_g, channel_r) = cv2.split(_processed_image)

# Flattens the 2D single channel array so as to make it easier to iterate over it
channel_b = channel_b.flatten()
channel_g = channel_g.flatten()
channel_r = channel_r.flatten()

for i in range(len(channel_b)):
    RGB = str(channel_r[i]) + " " + str(channel_g[i]) + " " + str(channel_b[i])
    if RGB in colors_count:
        colors_count[RGB] += 1
    else:
        colors_count[RGB] = 1

# taking the top n colors from the dictionary objects
_top_colors = sorted(colors_count.items(), key=lambda x: x[1], reverse=True)[0:n]
for _color in _top_colors:
    _rgb = tuple([int(value) for value in _color[0].split()])
    top_n_colors.append(_rgb)

print(top_n_colors)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接