zoukankan      html  css  js  c++  java
  • opencv2 直方图之calchist函数使用(转)

    OpenCV提供了calcHist函数来计算图像直方图。

             其中C++的函数原型如下:void calcHist(const Mat* arrays, int narrays, const int* channels, InputArray mask, OutputArray
    hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=
    false );

              void calcHist(const Mat* arrays, int narrays, const int* channels, InputArray mask, SparseMat&
    hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=
    false );

             参数解释:

            arrays。输入的图像的指针,可以是多幅图像,所有的图像必须有同样的深度(CV_8U or CV_32F)。同时一副图像可以有多个channes。

            narrays。输入的图像的个数。

            channels。用来计算直方图的channes的数组。比如输入是2副图像,第一副图像有0,1,2共三个channel,第二幅图像只有0一个channel,

    那么输入就一共有4个channes,如果int channels[3] = {3, 2, 0},那么就表示是使用第二副图像的第一个通道和第一副图像的第2和第0个通道来计

    算直方图。

            mask。掩码。如果mask不为空,那么它必须是一个8位(CV_8U)的数组,并且它的大小的和arrays[i]的大小相同,值为1的点将用来计算

    直方图。

            hist。计算出来的直方图

            dims。计算出来的直方图的维数。

            histSize。在每一维上直方图的个数。简单把直方图看作一个一个的竖条的话,就是每一维上竖条的个数。

            ranges。用来进行统计的范围。比如

             float rang1[] = {0, 20};

            float rang2[] = {30, 40};

            const float *rangs[] = {rang1, rang2};那么就是对0,20和30,40范围的值进行统计。

           uniform。每一个竖条的宽度是否相等。

           accumulate。Accumulation flag. If it is set, the histogram is not cleared in the beginning
    when it is allocated. This feature enables you to compute a single histogram from several
    sets of arrays, or to update the histogram in time.  是否累加。如果为true,在下次计算的时候不会首先清空hist。这个地方我是这样理解的,不知道有没有错,

    请高手指点。

     1 Histogram1D::Histogram1D(){  
     2     histSize[0] = 256;   
     3     hranges[0] = 0.0;  
     4     hranges[1] = 255.0;  
     5     ranges[0] = hranges;  
     6     channels[0] = 0;  
     7 }  
     8   
     9 cv::MatND Histogram1D::getHistogram(const cv::Mat &image){  
    10     cv::MatND hist;  
    11     cv::calcHist(&image,   //source image  
    12              1,        //histogram from 1 image only  
    13              channels, //the channel used  
    14              cv::Mat(),//no mask is uesd  
    15              hist,     //the resulting histogram  
    16              1,        //it is a 1D histogram  
    17              histSize, //number of bins  
    18              ranges    //pixel value range  
    19                 );//直方图函数  
    20     return hist;  
    21 }  

    下面是计算1维图像的直方图:

    cv::Mat Histogram1D::getHistogramImage(const cv::Mat &image){  
        //compute histogram first  
        cv::MatND hist = getHistogram(image);  
        //get min and max bin values  
        double maxVal = 0;  
        double minVal = 0;  
        cv::minMaxLoc(hist,&minVal,&maxVal,0,0);  
        //Image on which to display histogram  
        cv::Mat histImg(histSize[0],histSize[0],CV_8U,cv::Scalar(255));  
        //set highest point at 90% of nbins   
        int hpt = static_cast<int>(0.9*histSize[0]);  
        //Draw a vertical line for each bin   
        for (int h =0;h<histSize[0];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;  
    }  

    计算H-S直方图分布:

    /********************************************* 
                 内容:计算H-S 直方图分布       
                 时间:2013 5.27 
             作者:恋上蛋炒面       
    *********************************************/  
    #include <opencv2/core/core.hpp>  
    #include <opencv2/highgui/highgui.hpp>  
    #include <opencv2/imgproc/imgproc.hpp>  
    using namespace cv;  
      
    void main()  
    {  
        Mat source = imread("baboon.jpg");  
        namedWindow("Source");  
        imshow("Source",source);  
        Mat hsv;  
        cvtColor(source,hsv,CV_BGR2HSV);  
        //Quantize the hue to 60 levels  
        //and the saturation to 64 levels  
        int hbins = 60,sbins = 64;  
        int histSize[] = {hbins,sbins};  
       int histSize[] = {hbins,sbins};  
        //hue varies from 0 to 179  
        float hranges[] = {0,180};  
        //saturation varies from 0 to 255  
        float sranges[] = {0,255};  
        const float *ranges[] = {hranges,sranges};  
        //two channels 0th,1th  
        int channels[] = {0,1};  
        MatND hist;  
        //compute h-s histogram  
        calcHist(&hsv,1,channels,Mat(),hist,2,histSize,ranges);  
        //get the max value  
        double maxVal = .0;  
        minMaxLoc(hist,0,&maxVal,0,0);  
        int scale = 8;  
        //show the histogram on the image  
        Mat histImg = Mat::zeros(sbins*scale,hbins*scale,CV_8UC3);  
        for (int h = 0;h < hbins;h++)  
    {  
            for (int s = 0;s<sbins;s++)  
            {  
                float binVal = hist.at<float>(h,s);  
                int intensity = cvRound(binVal*0.9*255/maxVal);  
                rectangle(histImg,Point(h*scale,s*scale),Point((h+1)*scale-1,(s+1)*scale-1),Scalar::all(intensity),CV_FILLED);  
            }  
        }  
      
        namedWindow("H-S Histogram");  
        imshow("H-S Histogram",histImg);  
        imwrite("hshistogram.jpg",histImg);  
        waitKey(0);  
    }  

      RGB直方图:

     1 #include <opencv2/core/core.hpp>  
     2 #include <opencv2/highgui/highgui.hpp>  
     3 #include <opencv2/imgproc/imgproc.hpp>  
     4   
     5 #include <fstream>  
     6   
     7 using namespace cv;  
     8 using namespace std;  
     9   
    10 void main()  
    11 {  
    12     //Mat source = imread("red.jpg");  
    13     Mat source = imread("baboon.jpg"); //读取图片  
    14     //Mat source(300,300,CV_8UC3,Scalar(1,1,244));  
    15     //imwrite("red.jpg",source);  
    16     namedWindow("Source");//窗口显示图片  
    17     imshow("Source",source);  
    18     //初始化calcHist函数的参数  
    19     int channels_r[1],channels_g[1],channels_b[1],histSize[1],range;  
    20     float hranges[2];  
    21     const float *ranges[1];  
    22     histSize[0] = 256;  
    23     hranges[0] = 0.0;  
    24     hranges[1] = 255.0;  
    25     ranges[0] = hranges;  
    26     channels_b[0] = 0;  
    27     channels_g[0] = 1;  
    28     channels_r[0] = 2;  
    29     MatND hist_r,hist_g,hist_b;  
    30   
    31     double max_val_r,max_val_g,max_val_b;  
    32     Mat histImage(histSize[0],3*histSize[0],CV_8UC3); //定义一个显示直方图的图片,长256*3 高256  
    33     //R  
    34     calcHist(&source,1,channels_r,Mat(),hist_r,1,histSize,ranges);//分别计算R,G,B的直方图分布  
    35     minMaxLoc(hist_r,0,&max_val_r,0,0);//计算直方图中统计最大值  
    36     //G  
    37     calcHist(&source,1,channels_g,Mat(),hist_g,1,histSize,ranges);  
    38     minMaxLoc(hist_g,0,&max_val_g,0,0);  
    39     //B  
    40     calcHist(&source,1,channels_b,Mat(),hist_b,1,histSize,ranges);  
    41     minMaxLoc(hist_b,0,&max_val_b,0,0);  
    42   
    43     //将r,g,b的最大统计值,以及像素点从0-255的统计值写入txt中  
    44     ofstream outfile1("d:\r.txt");  
    45     ofstream outfile2("d:\g.txt");  
    46     ofstream outfile3("d:\b.txt");  
    47   
    48     //在txt中写入最大统计值  
    49     outfile1<<"max_val_r = "<<max_val_r<<endl;  
    50     outfile2<<"max_val_g = "<<max_val_g<<endl;  
    51     outfile3<<"max_val_b = "<<max_val_b<<endl;  
    52   
    53     for (int i =0;i<histSize[0];i++)  
    54     {         
    55         //R,G,B= i的统计值  
    56         float binVal_r = hist_r.at<float>(i);  
    57         float binVal_g = hist_g.at<float>(i);  
    58         float binVal_b = hist_b.at<float>(i);  
    59         //统一R,G,B统计值的大小,以高度的90%封顶  
    60         int intensity_r = static_cast<int>(0.9*histSize[0]*binVal_r/max_val_r);  
    61         outfile1<<i<<" "<<binVal_r<<" "<<intensity_r<<endl;  
    62         int intensity_g = static_cast<int>(0.9*histSize[0]*binVal_g/max_val_g);  
    63         outfile2<<i<<" "<<binVal_g<<" "<<intensity_g<<endl;  
    64         int intensity_b = static_cast<int>(0.9*histSize[0]*binVal_b/max_val_b);  
    65         outfile3<<i<<" "<<binVal_b<<" "<<intensity_b<<endl;  
    66         //画出R,G,B的直方图直线  
    67         line(histImage,Point(i,histImage.rows),Point(i,histImage.rows-intensity_r),Scalar(0,0,255));  
    68         line(histImage,Point(i+histSize[0],histImage.rows),Point(i+histSize[0],histImage.rows-intensity_g),Scalar(0,255,0));  
    69         line(histImage,Point(i+histSize[0]*2,histImage.rows),Point(i+histSize[0]*2,histImage.rows-intensity_b),Scalar(255,0,0));  
    70     }  
    71     namedWindow("RGB Histogram");  
    72     imshow("RGB Histogram",histImage);  
    73  imwrite("RGB_Histogram.jpg",histImage);  
    74     waitKey(0);  
    75 }  
  • 相关阅读:
    dsu on tree题表
    [BZOJ4129]Haruna’s Breakfast(树上带修改莫队)
    [BZOJ3757]苹果树(树上莫队)
    [BZOJ3585]mex(莫队+分块)
    Prufer codes与Generalized Cayley's Formula
    [luogu4459][BJOI2018]双人猜数游戏(DP)
    [BZOJ5292][BJOI2018]治疗之雨(概率DP+高斯消元)
    [BZOJ5291][BJOI2018]链上二次求和(线段树)
    [luogu4389]付公主的背包(多项式exp)
    [CF1086E]Beautiful Matrix(容斥+DP+树状数组)
  • 原文地址:https://www.cnblogs.com/wyuzl/p/6702785.html
Copyright © 2011-2022 走看看