基於圖像的主顏色分析


一般來說,直接分析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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM