一般来说,直接分析RGB色彩域的颜色分布不是一个好的思路,我们一般转换到HSV域来分析。但是本文只要是应网友提问,实现最基本的RGB
色彩域的主颜色分析。
代码分为以下部分:
1、生成测试图片。为了测试算法是否准确,主动生成
具有25种不同颜色同比重的图片(每种4%)的
测试图片。
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维数组中去。
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 colorAppeared;
for (int i=0;i
{
for (int j=0;j
{
int b = src.at(i,j)[0];
int g = src.at(i,j)[1];
int
r = src.at(i,j)[2];
if (iTable[b,g,r] == 0)
colorAppeared.push_back(src.at(i,j));
iTable[b,g,r] ++;
}
}
3、将数组结果保存到vector中,使用标准库的排序方法。需要注意的是这里重载了vector的比较函数
bool Comp(const std::pairint> &a,const std::pairint> &b)
{
return a.second > b.second;
}
for (int i=0;i
{
Vec3b vec3b = colorAppeared[i];
int b = vec3b[0];
int g = vec3b[1];
int r = vec3b[2];
std::pairint> apair(vec3b,iTable[b,g,r]);
result.push_back(apair);
}
sort(result.begin(),result.end(),Comp);
4、显示最后结果
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);
5、完整的代码如下。感谢阅读,希望有所收获,欢迎交流。
#include
"stdafx.h"
#include
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include
#include
#include
using namespace cv;
using namespace std;
bool Comp(const std::pairint> &a,const std::pairint> &b)
{
return a.second > b.second;
}
int main( int argc, const char** argv )
{
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::pairint>> result;
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 colorAppeared;