OpenCV4学习笔记(53)——基于K-Means聚类算法建立图像主色卡

今天继续整理记录关于K-Means聚类算法的一个小应用,那就是对图像进行主色彩提取,从而建立属于图像的主色卡。关于K-Means算法的一些介绍,可以看我之前的博文《OpenCV4学习笔记(50)》。

有时候我们想要知道图像中有哪些主要色彩,尤其是在印刷、印制的时候,如果有针对模板图像的主色卡做参考,那么取色的时候能更加精准,避免色差。

利用K-Means聚类算法实现图像主色卡建立的步骤如下:
(1)先进行K-Means图像分割,可以参考《OpenCV4学习笔记(51)——基于K-Means聚类算法实现的图像分割》。

(2)然后计算每一种类别的像素点在整幅图像中所占的比率及其中心RGB值。

(3)根据每张类别颜色占整幅图像的比率来绘制每种主要色彩,从而建立图像的主色卡。

代码演示如下:

	//读取图像并制作数据集
	Mat test_image = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\opencv-logo.png");
	resize(test_image, test_image, Size(600, 600));
	int width = test_image.cols;
	int height = test_image.rows;
	int samplesNum = width * height;
	Mat data = test_image.reshape(3, samplesNum);
	data.convertTo(data, CV_32F);
	//进行K-Means聚类
	int K = 5;
	Mat bestLabels, centers;
	TermCriteria criteria = TermCriteria(TermCriteria::Type::COUNT + TermCriteria::Type::EPS, 10, 0.01);
	kmeans(data, K, bestLabels, criteria, K, KMEANS_PP_CENTERS, centers);
	//计算每一种类别像素点在图像中所占的比例
	vector<float>color_radio(K);
	for (int i = 0; i < samplesNum; i++)
	{
		color_radio[bestLabels.at<int>(i, 0)]++;
	}
	for (int j = 0; j < K; j++)
	{
		color_radio[j] = color_radio[j] / samplesNum;
	}
	//绘制图像的主色卡
	Mat color_card = Mat::zeros(Size(width, 50), test_image.type());
	int x = 0, y = 0;
	for (int k = 0; k < K; k++)
	{
		int color_width = int(color_radio[k] * width);
		int color_height = color_card.rows;
		Rect color(x, y, color_width, color_height);
		uchar b = uchar(centers.at<float>(k, 0));
		uchar g = uchar(centers.at<float>(k, 1));
		uchar r = uchar(centers.at<float>(k, 2));
		color_card(color) = Scalar(b, g, r);
		x += color_width;
		cout << "色彩所占比例:" << color_radio[k] << endl;
	}
	//合并显示
	Mat dst = Mat::zeros(Size(width, height + 50), test_image.type());
	Rect c_card(0, 0, width, 50);
	Mat roi_c_card = dst(c_card);
	color_card.copyTo(roi_c_card);
	Rect img(0, 50, width, height);
	Mat roi_img = dst(img);
	test_image.copyTo(roi_img);
	imshow("dst", dst);

下面是对不同图像建立主色卡的效果:
OpenCV4学习笔记(53)——基于K-Means聚类算法建立图像主色卡_第1张图片
OpenCV4学习笔记(53)——基于K-Means聚类算法建立图像主色卡_第2张图片
下方显示的是输入图像,上方的小长方形就是提取出的主色卡了,包含了图像中的主要颜色及其大致占比,从控制台中也可以看到各种颜色所占的具体比例是多少。不过前提是,我们需要事先设定好要将图像分为几种颜色,也即是K个颜色分类,这是由于K-Means聚类算法的特性所决定的。

好了,本次笔记到此结束,谢谢阅读~

PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!

你可能感兴趣的:(学习笔记,opencv,计算机视觉,c++)