前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【手撕算法】K-means算法实现主题色提取

【手撕算法】K-means算法实现主题色提取

作者头像
周旋
发布2022-08-07 12:19:51
5140
发布2022-08-07 12:19:51
举报
文章被收录于专栏:行走的机械人行走的机械人

K - Means是一种对图像进行聚类的算法,属于无监督分割聚类方法,这种方法不对聚类进行层次划分,只是通过分析聚类的性质和均值,将像素简单地划分为不相交的聚类。

今天结合一个在知乎看到的问题来说:

一张图片上有上百种颜色,如何在一张图上筛选出小于五种的基本色,或者在一张图上进行颜色划分归类? 为了做品牌,我们需要从符合品牌调性的图片中提取品牌色,但一张图片的颜色有上百种 我们怎么把这些颜色归类划分 提取呢?

有答友已经回答了该问题,我们今天就是C++实现K-means算法来解决这个问题。该问题链接:

代码语言:javascript
复制
https://www.zhihu.com/question/29268904

下图回答里的链接是python版代码,本文为C++代码。

K-means算法原理

K-means算法需要我们自己定义K值,如前面知乎的问题,需要提取图片的五种基本色,所以我们就定义K为5,即将图片分为5个簇。means是均值的意思,在本问题背景下,均值代表每个簇的颜色均值。

指定K值后,我们随机生成五个像素坐标,并取这五个像素坐标的颜色作为五个簇的初始均值。

需要注意的是,K-means算法关注的是图像的像素值,我们需要将各个簇包含的像素的像素值记录下来,而不是像素坐标。

然后我们开始迭代,迭代次数也是自己定义的,每一次迭代,我们都遍历图像所有像素,并计算该像素与各个簇的颜色均值的颜色距离,选择最接近的簇,将该像素值加入到此簇中(以便计算该簇新的均值)。

在一次遍历像素完毕后,都需要重新计算各个簇的颜色均值,并判断该新的均值与上次均值是否有差别,如果没有则说明收敛了,就无需继续迭代了。如果相差巨大,则需要再一次迭代。

如果需要再一次迭代,便将所有簇的元素清空,仅保留计算的均值,然后再一次遍历所有像素,重复上一步。

算法实现

主函数:读取图片,定义Kmeans算法的K值以及迭代次数,并对图片进行K-means算法。

代码语言:javascript
复制
int main()
{
  Mat srcImage;
  srcImage = imread("4.jpg",17);
  Mat dstImage(Size(100,600), CV_8UC3, Scalar(0,0,0));
  if (srcImage.empty())
  {
    printf_s("图片读取失败");
    return -1;
  }
  imshow(WINDOW_1, srcImage);

  int clusters_num = 5;//kmeans算法的k值
  int iterations = 10;//迭代次数
  KMean(srcImage, dstImage, clusters_num, iterations);
  imshow(WINDOW_2, dstImage);

  waitKey();
  return 0;
}

程序中用到了K-means算法函数

代码语言:javascript
复制
KMean(srcImage, dstImage, clusters_num, iterations);

此函数就实现了对输入图像srcImage 进行聚类操作,并将结果输出到dstImage参数中。clusters_num为K值,iterations为迭代次数。

除了K-means算法函数本身,程序还定义了一个簇类,用来存放簇的一些成员变量以及对簇的操作,例如向簇中添加一个像素,清空簇等等操作。

代码(详细注释)就不在这儿贴了,太长了

算法效果

试两张七龙珠的照片看一下效果:

THE END

本文所用代码是我以前在github上下的,也找不到原项目地址了。稍微改了一下末尾代码实现了K-means算法提取基本色的可视化。原代码是英文注释,我结合自己理解改成了中文注释。因为代码非原创,所以仅作学习分享。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 周旋机器视觉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档