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

时间:2015-04-28 12:09:08

标签: c++ opencv

我开始了一个关于检测的项目。 我的想法是对图像的每个像素(Mat)进行排名。 然后,我将能够退出哪种颜色占主导地位。

困难是颜色不单一。例如,Green是rgb(0,255,0),但也几乎是rgb(10,240,20)。

我的排名目标是退出几乎相同颜色的像素。然后,有了一个pourcentage,我想我可以找到我的对象。

所以,我的问题是:这是按颜色对像素进行排序的方法吗?

提前了解你的答案。

2 个答案:

答案 0 :(得分:3)

对于颜色中的像素,没有直接的排名方法。 但是,您可以找到最主要的近似值。

有几种方法可以做到:

  1. 您可以计算每个颜色通道的直方图 - split将其直接计入R,G,B并计算直方图。然后你可以看到结果图的峰值在哪里 - 例如
  2. 如果k-means聚类图像上的像素 - 换句话说,将每个像素表示为具有协调(R,G,B)的3D点。然后,您可以将像素分割成k个最常出现的颜色。
  3. 如果您将图像调整为1x1像素图像,则可以找到所有像素值的平均值。如果存在主色,大多数像素都非常接近,那么它将给出一个很好的近似值。
  4. 但是,所有近似值都是如此。您最好的选择是使用k-means并找到具有最多元素或最密集的集群。

    如果您正在寻找使用特定颜色定位对象的方法,则可以使用最大似然估计。东西like this,用于对卫星图像中的草,汽车,建筑物和人行道等不同物体进行分类。您可以使用单一颜色,并根据属于您的对象的像素的可能性(概率百分比)获得对象所在位置的热图。

答案 1 :(得分:0)

在普通图像中,总是涉及多种颜色。为了达到最佳平均水平,带有几乎相同颜色的像素是通过色彩量化完成的,色彩量化使用K均值聚类技术减少了图像中的色彩数量。最好用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)