• 基于图像的主颜色分析


    一般来说,直接分析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;
    }
  • 相关阅读:
    Jenkins安装
    Python操作yaml文件
    class 中构造函数与析构函数
    python发送邮件(yagmail模块)
    filter、map函数的区别
    python redis操作
    多个 python的pip版本选择
    python Excel操作
    python MD5操作
    缓存淘汰算法之LRU实现
  • 原文地址:https://www.cnblogs.com/jsxyhelu/p/16948008.html
Copyright © 2020-2023  润新知