C++ 从HSV直方图中提取主色调值

C++ 从HSV直方图中提取主色调值,c++,image,opencv,histogram,hsv,C++,Image,Opencv,Histogram,Hsv,我正在从下面的图像创建hsv直方图 - (void)processImageWithHsv:(Mat&)image; { Mat image_hsv; cvtColor(image, image_hsv, CV_BGR2HSV); int hbins = 50, sbins = 60; int histSize[] = {hbins, sbins}; float hranges[] = { 0, 360 }; float srange

我正在从下面的图像创建hsv直方图

- (void)processImageWithHsv:(Mat&)image;
{
    Mat image_hsv;

    cvtColor(image, image_hsv, CV_BGR2HSV);

    int hbins = 50, sbins = 60;
    int histSize[] = {hbins, sbins};

    float hranges[] = { 0, 360 };
    float sranges[] = { 0, 256 };

    const float* ranges[] = { hranges, sranges };
    MatND hist;

    int channels[] = {0, 1};

    calcHist( &image_hsv, 1, channels, Mat(), // do not use mask
             hist, 2, histSize, ranges,
             true, // the histogram is uniform
             false );

    double maxVal = 0;
    minMaxLoc(hist, 0, &maxVal, 0, 0);

    // ???: HOW Convert this information to colour value

}
但是我不知道如何从这个
hist

我是否应该使用
maxVal

您犯了一些错误:

  • 您正在寻找主色
    ,但告诉
    calcHist
    使用色调和饱和度。你应该换频道
  • 你的
    hranges
    错了:应该是180
  • dims
    应该是1(而不是2),因为您只需要
    直方图
  • 在这些校正之后,
    maxVal
    应包含最经常出现的
    值。

    -(void)processImageWithHsv:(Mat&)image;
    
    - (void)processImageWithHsv:(Mat&)image;
    {
        Mat image_hsv;
    
        cvtColor(image, image_hsv, CV_BGR2HSV);
    
        // Quanta Ratio
        int scale = 10;
    
        int hbins = 36, sbins = 25, vbins = 25;
        int histSize[] = {hbins, sbins, vbins};
    
        float hranges[] = { 0, 180 };
        float sranges[] = { 0, 256 };
        float vranges[] = { 0, 256 };
    
        const float* ranges[] = { hranges, sranges, vranges };
        MatND hist;
    
        int channels[] = {0, 1, 2};
    
        calcHist( &image_hsv, 1, channels, Mat(), // do not use mask
                 hist, 3, histSize, ranges,
                 true, // the histogram is uniform
                 false );
    
        int maxVal = 0;
    
        int hue = 0; 
        int saturation = 0; 
        int value = 0; 
    
        for( int h = 0; h < hbins; h++ )
            for( int s = 0; s < sbins; s++ )
                 for( int v = 0; v < vbins; v++ )
                    {
                          int binVal = hist.at<int>(h, s, v);
                          if(binVal > maxVal)
                          {
                              maxVal = binVal;
    
                              hue = h;
                              saturation = s;
                              value = v;
                          }
                    }
    
        hue = hue * scale; // angle 0 - 360
        saturation = saturation * scale; // 0 - 255
        value = value * scale; // 0 - 255
    }
    
    { Mat image_hsv; CVT颜色(图像、图像、CV-BGR2HSV); //量子比 int标度=10; int hbins=36,sbins=25,vbins=25; int histSize[]={hbins,sbins,vbins}; float-hranges[]={0,180}; float sranges[]={0,256}; float vranges[]={0,256}; 常量浮点*范围[]={hranges,sranges,vranges}; 成熟的历史; int通道[]={0,1,2}; calcHist(&image_hsv,1,通道,Mat(),//不使用掩码 历史,3,历史大小,范围, true,//直方图是一致的 假); int maxVal=0; int色调=0; int饱和=0; int值=0; 对于(int h=0;hmaxVal) { maxVal=binVal; 色调=h; 饱和=s; 值=v; } } 色调=色调*比例;//角度0-360 饱和度=饱和度*刻度;//0-255 value=value*scale;//0-255 }
    最主要的问题还不清楚。你到底在找什么?最常见的颜色?最饱和的颜色?更换通道?你能再解释一下吗?我应该为香奈儿(h、s和v)创建hist吗?看起来你不知道你的代码是做什么的。我建议你读一些。如果还有其他问题,请回来。我想说的是,所有答案都建议创建直方图并从中获取最大值。我搞错了吗?在你链接的页面中,他们提出了一种不同、更复杂、更好的方法。然而,您想要使用的方法并不是那么糟糕。