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 }  

 


免責聲明!

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



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