在Python中检测普通背景上对象的主颜色

在Python中检测普通背景上对象的主颜色,python,colors,k-means,Python,Colors,K Means,我写了一个算法,假设背景是普通的,用一个对象检测图像的主颜色。以下是我目前正在执行的基本步骤: 对整个图像运行k-means算法(k=10) 删除与像素(0,0)具有相同类别的点 使用剩余的点(k=3)=>3种主颜色运行新的k-means算法 虽然这可能不是最聪明的算法,但我对结果非常满意,除非对象的大部分与背景颜色相同。例如,当对象在白色背景上主要为白色时,该算法自然倾向于将对象的白点与背景进行分类 我怎样才能有一个在所有情况下都有效的通用方法(我对白色物体没有任何先验知识)?可以假定对象

我写了一个算法,假设背景是普通的,用一个对象检测图像的主颜色。以下是我目前正在执行的基本步骤:

  • 对整个图像运行k-means算法(k=10)
  • 删除与像素(0,0)具有相同类别的点
  • 使用剩余的点(k=3)=>3种主颜色运行新的k-means算法
虽然这可能不是最聪明的算法,但我对结果非常满意,除非对象的大部分与背景颜色相同。例如,当对象在白色背景上主要为白色时,该算法自然倾向于将对象的白点与背景进行分类

我怎样才能有一个在所有情况下都有效的通用方法(我对白色物体没有任何先验知识)?可以假定对象在水平和垂直方向上居中。但是,不能假设对象的形状或其中的颜色数量(有时是普通的,有时有许多不同的颜色)。谢谢

(我相信我已经阅读了所有可能的相关帖子!)

编辑: 我得到的典型结果是:

这就是第一个k-means如何对点进行分类(左:k=10,右:k=3):
您不太清楚当前的问题是什么。你能贴张截图吗

可能您的意思是,对象边缘附近的区域(对象和背景之间)被错误地归类为背景色,即您的算法剪裁过多。在这种情况下,可以使用边缘检测算法来检测对象和背景之间的边界。一旦你知道了边,你就知道了内部,因此你应该能够切割除了内部之外的所有东西,然后重新运行你的算法

如果您的意思是对象的内部被分类为背景,那么您可以执行泛光填充算法。如果要对每个区域进行泛光填充,请拒绝任何无法一直泛光填充到像素(0,0)的区域。这将为您留下一个不与对象重叠的区域列表。

一些想法:

1) 如果背景颜色是恒定的(例如,所有像素都是相同的颜色),则可以通过查找空间连接的最大组件来查找背景,该组件包含所有相同(或在某个阈值内相同)颜色的像素。您可以删除背景,然后在剩余的图像上运行K-Means

2) 如果图像中的组件与背景属于同一集群,但在图像中没有连接,则可以通过运行“连接组件”算法来拆分它们。或者,如果在运行K-Means(例如,像素坐标)时未包含空间信息,则可以这样做


3) 您也可以尝试增加K,直到对象从背景中分离(对于大多数/所有图像)。

感谢您的回答,我发布了一个典型问题案例的结果。内部确实是被错误地归类为背景的东西。即使如此,检测边缘也应该有效,不是吗?很好。我还得出结论,增加钾可以有所帮助。是的,当K>20时,我对结果很满意。然而,你的其他想法也很有洞察力(还没有测试过!)。谢谢