0
点赞
收藏
分享

微信扫一扫

基于图像的主颜色分析

一般来说,直接分析RGB色彩域的颜色分布不是一个好的思路,我们一般转换到HSV域来分析。但是本文只要是应网友提问,实现最基本的RGB 色彩域的主颜色分析。



代码分为以下部分:



1、生成测试图片。为了测试算法是否准确,主动生成 具有25种不同颜色同比重的图片(每种4%)的 测试图片。



 

创建具有25种不同颜色同比重的图片

Mat src
= Mat(
250,
250,CV_8UC3,Scalar(
0));


//生成时间种子

time_t t;time(
&t);

RNG rng(t);


//创建图片


for (
int i
=
0;i
<
250;i
+=
10)

rectangle(src,Point(
0,i),Point(src.cols,i
+
9),Scalar(rng.uniform(
0,
255),rng.uniform(
0,
255),rng.uniform(
0,
255)),
-
1);

imshow(
"src",src);

imwrite(
"e:/template/maincolor.jpg",src);



基于图像的主颜色分析_读取数据


生成的结果大概是这个样子的。


2、读取图片数据,保存到3维数组中去。


 

//bgr立方体 

int *iTable
=
new int [ 256,
256,
256];

for ( int b =
0;b
<
256;b
++)

{
for ( int g =
0;g
<
256;g
++)

{
for ( int r =
0;r
<
256;r
++)

{
iTable[b,g,r] =
0;

}
}
}
//出现过的颜色

vector <Vec3b
> colorAppeared;

//读取数据

for ( int i =
0;i
<src.cols;i
++)

{
for ( int j =
0;j
<src.rows;j
++)

{
int b = src.at
<Vec3b
>(i,j)[
0];

int g = src.at
<Vec3b
>(i,j)[
1];

int r = src.at
<Vec3b
>(i,j)[
2];

if (iTable[b,g,r] ==
0)

colorAppeared.push_back(src.at <Vec3b
>(i,j));

iTable[b,g,r] ++;

}
}

 


3、将数组结果保存到vector中,使用标准库的排序方法。需要注意的是这里重载了vector的比较函数


//重载用于排序的比较函数

bool Comp( const std :
:pair
<Vec3b,
int
>
&a,
const std :
:pair
<Vec3b,
int
>
&b)

{
return a.second > b.second;

}
//将出现过的数据插入标准库

for ( int i =
0;i
<colorAppeared.size();i
++)

{
Vec3b vec3b = colorAppeared[i];

int b = vec3b[
0];

int g = vec3b[
1];

int r = vec3b[
2];

std :
:pair
<Vec3b,
int
> apair(vec3b,iTable[b,g,r]);

result.push_back(apair);
}
//进行排序

sort(result.begin(),result.end(),Comp);

 


4、显示最后结果


显示结果 前20

Mat matResult = Mat(
200,
200,CV_8UC3,Scalar(
0));

for ( int i =
0;i
<
20;i
++)

{
Vec3b vec3b = result[i].first;

int iint = result[i].second;

float dpercent = (
float)iint / (src.rows
* src.cols);

rectangle(matResult,Point( 0,i
*
10),Point(
200,i
*
10
+
9),vec3b,
-
1);

printf( "第%d种颜色,占比例为%f\n",i
+
1,(
float)dpercent);
}
imshow( "matResult",matResult);



基于图像的主颜色分析_数据_02


5、完整的代码如下。感谢阅读,希望有所收获,欢迎交流。



// jsxyhelu (jsxyhelu@foxmail.com)

# include "stdafx.h"
# include <opencv2 /core
/utility.hpp
>

# include "opencv2/imgproc.hpp"
# include "opencv2/imgcodecs.hpp"
# include "opencv2/highgui.hpp"
# include <opencv2 /photo.hpp
>

# include <fstream >

# include <iostream >

using namespace cv;
using namespace std;

//重载用于排序的比较函数

bool Comp( const std : :pair
<Vec3b,
int
>
&a,
const std : :pair
<Vec3b,
int
>
&b)

{
return a.second > b.second;
}
int main( int argc, const char
*
* argv )

{
创建具有25种不同颜色同比重的图片
Mat src = Mat( 250,
250,CV_8UC3,Scalar(
0));

//生成时间种子
time_t t;time( &t);
RNG rng(t);
//创建图片
for ( int i = 0;i
<
250;i
+=
10)

rectangle(src,Point( 0,i),Point(src.cols,i +
9),Scalar(rng.uniform(
0,
255),rng.uniform(
0,
255),rng.uniform(
0,
255)),
-
1);

imshow( "src",src);
imwrite( "e:/template/maincolor.jpg",src);
进行主要颜色分析
//用于保存当前出现过的颜色数据结构
std : :vector
<std
:
:pair
<Vec3b,
int
>> result;

//bgr立方体
int *iTable =
new int [ 256, 256,
256];

for ( int b = 0;b
<
256;b
++)

{
for ( int g = 0;g
<
256;g
++)

{
for ( int r = 0;r
<
256;r
++)

{
iTable[b,g,r] = 0;

}
}
}
//出现过的颜色
vector <Vec3b > colorAppeared;

//读取数据
for ( int i = 0;i
<src.cols;i
++)

{
for ( int j = 0;j
<src.rows;j
++)

{
int b = src.at <Vec3b
>(i,j)[
0];

int g = src.at <Vec3b
>(i,j)[
1];

int r = src.at <Vec3b
>(i,j)[
2];

if (iTable[b,g,r] == 0)

colorAppeared.push_back(src.at <Vec3b >(i,j));

iTable[b,g,r] ++;
}
}
//将出现过的数据插入标准库
for ( int i = 0;i
<colorAppeared.size();i
++)

{
Vec3b vec3b = colorAppeared[i];
int b = vec3b[ 0];

int g = vec3b[ 1];

int r = vec3b[ 2];

std : :pair
<Vec3b,
int
> apair(vec3b,iTable[b,g,r]);

result.push_back(apair);
}
//进行排序
sort(result.begin(),result.end(),Comp);
显示结果 前20
Mat matResult = Mat( 200,
200,CV_8UC3,Scalar(
0));

for ( int i = 0;i
<
20;i
++)

{
Vec3b vec3b = result[i].first;
int iint = result[i].second;
float dpercent = ( float)iint / (src.rows * src.cols);

rectangle(matResult,Point( 0,i *
10),Point(
200,i
*
10
+
9),vec3b,
-
1);

printf( "第%d种颜色,占比例为%f\n",i +
1,(
float)dpercent);
}
imshow( "matResult",matResult);
waitKey();
return 0;
}


 


举报

相关推荐

0 条评论