基于图像的主颜色分析

一般来说,直接分析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);
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;
}

 

posted on   jsxyhelu  阅读(79)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示