【问题标题】:Unable to get histogram image in OpenCV无法在 OpenCV 中获取直方图图像
【发布时间】:2013-11-15 12:43:42
【问题描述】:

我是 OpenCV 新手,正在学习绘制单通道图像的直方图。当我运行程序时,我只得到一条白线。请告诉我这段代码有什么问题。

int histSize[1] = {256};
float hranges[2] = {0.0, 255.0};
const float* ranges[1] = {hranges};
int channels[1] = {0};

cv::MatND getHistogram(const cv::Mat &image) {
    cv::MatND hist;

    cv::calcHist(&image,1,channels,cv::Mat(),hist,1,histSize,ranges);

    return hist;
}

cv::Mat getHistogramImage(const cv::Mat &image) {
    cv::MatND hist = getHistogram(image);

    double minVal = 0;
    double maxVal = 0;

    cv::minMaxLoc(hist,&minVal,&maxVal,0,0);

    cv::Mat histImg(histSize[0],histSize[0],CV_8U,cv::Scalar(255));

    int hpt = static_cast<int>(0.9*histSize[0]);

    for(int h=0; h<256; ++h){
        float binVal = hist.at<float>(h);

        int intensity = static_cast<int>(binVal*hpt/maxVal);

        cv::line(histImg,cv::Point(h,histSize[0]),
                         cv::Point(h,histSize[0]-intensity),
                         cv::Scalar::all(0));
    }
    return histImg;
}

【问题讨论】:

  • 你见过official documentation进行直方图计算吗?我认为它会给你所有你需要的答案..
  • 是的,我指的是同一页面。谢谢。
  • @Shubham 从that page 获取代码,编译它,运行它并确保它可以工作。然后,将其调整为单通道图像。我相信你会发现你的错误。
  • 是的,我使用了该代码并且现在工作正常,但我仍然无法在上面的代码中发现任何错误。
  • 我已经测试了你的代码,它对我来说很好。

标签: c++ opencv histogram


【解决方案1】:

对于单通道(也来自hue通道),可以使用以下代码:

{
    Mat input("filepath/image.jpg", 1);
    Mat hsv_input;

cvtColor( input, hsv_input, CV_BGR2HSV );

int h_bins = 5; 
int histSize[] = { h_bins}; 
float h_ranges[] = { 0, 180 };

const float* ranges[] = { h_ranges};
int channels[] = { 0 };

MatND original_hist_input;
calcHist( &hsv_input, 1, channels, Mat(), original_hist_input, 1, histSize, ranges, true, false );
normalize( original_hist_input, original_hist_input, 0, 1, NORM_MINMAX, -1, Mat() );    

}

【讨论】:

    【解决方案2】:
    #include <opencv2/opencv.hpp>
    #include <iostream>
    
    
        using namespace cv;
       using namespace std;
    
    
    
        class Histogram1D
    {
    
    
       public:
    
            int hitsize[1];
            float hrange[2];
            const float *ranges[1];
            int channel[1];
    
    
        Histogram1D()
        {
            hitsize[0]=256;
            hrange[0]=0.0;
            hrange[1]=256.0;
            ranges[0]=hrange;
            channel[0]=0;
    
        }
    
        MatND gethistogram(Mat &image)
        {
            MatND hist;
    
            calcHist(&image,1,channel,Mat(),hist,1,hitsize,ranges);
            return hist;
        }
    };
    
    
    int main()
    
    
    {
    
            Mat image = imread("1.jpg",0);
            Histogram1D h;
            double minval=0;
        double maxval=0;
    
    
        MatND result= h.gethistogram(image);
    
        for (int i=0;i<256;i++)
        {
            cout << "value" << i << "=" << result.at<float>(i)<< endl;
    
        }
    
        minMaxLoc(result,&minval,&maxval,0,0);
    
        Mat histImg(h.hitsize[0],h.hitsize[0],CV_8U,Scalar(255));
    
        int hpt=static_cast<int>(0.9*h.hitsize[0]);
    
            for(int i=0;i<h.hitsize[0];i++)
            {
                float binval=result.at<float>(i);
                int intensity=static_cast<int>(binval*hpt/maxval);
    
                line(histImg,Point(i,h.hitsize[0]),Point (i,h.hitsize[0]-intensity),Scalar::all(0));
    
    
            }
    
            namedWindow("Histogram");
            imshow("Histogram", histImg);
            waitKey(0);
    }
    

    【讨论】:

      【解决方案3】:

      您在第二行中声明了错误的色调通道范围

      float hranges[2] = {0.0, 255.0}; 
      

      这是错误的,色调通道范围是 0 到 180。因此,由于色调通道范围是 0 到 180,因此如果您采用更少/或等于 180 个 bin,即“histSize”,那将是很好的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-03
        • 1970-01-01
        • 2021-06-28
        • 2011-01-09
        • 1970-01-01
        • 2016-08-04
        • 2010-12-04
        • 2016-07-12
        相关资源
        最近更新 更多