OpenCV處理直方圖

直方圖能夠用來描述各類不一樣的事物,如物體的色彩分佈、物體邊緣梯度模板,以及表示目標位置的當前假設。html

簡單的說,直方圖就是對數據進行統計,將統計值組織到一系列事先定義好的bin中。bin中的數值是從數據中計算出特徵的統計量,這些數據能夠是諸如梯度、方向、色彩或者任何其餘特徵。不管如何,直方圖得到的是數據分佈的統計圖。一般直方圖的維數要低於原始數據。數組

../../../../../_images/Histogram_Calculation_Theory_Hist1.jpg

具體可參見:ui

http://docs.opencv.org/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html#histogram-calculationspa

下面參考《Learning OpenCV》一個例子。根據輸入的圖像計算出一個色相飽和度的2維直方圖。3d

/**
  *    file:參考《learning OpenCV》P227
  *    author: Jacky_Liu
  *    date:   2013-12-06
  */

#include <QtCore/QCoreApplication>
#include <cv.h>
#include <highgui.h>

int main(int argc, char *argv[])
{
//    QCoreApplication a(argc, argv);
//    return a.exec();

    IplImage *src = NULL;

    if(argc != 2 || (src = cvLoadImage(argv[1], 1)) == 0)
    {
        printf("The number of the arguments is wrong, or the fail to load image.");
        return 0;
    }

    //轉換顏色空間
    IplImage *hsv = cvCreateImage(cvGetSize(src), 8, 3);
    cvCvtColor(src, hsv, CV_BGR2HSV);

    //分割到3個獨立通道的圖像
    IplImage *h_plane = cvCreateImage( cvGetSize(src), 8, 1);
    IplImage *s_plane = cvCreateImage( cvGetSize(src), 8, 1);
    IplImage *v_plane = cvCreateImage( cvGetSize(src), 8, 1);

    IplImage *planes[] = {h_plane, s_plane};
    cvCvtPixToPlane(hsv, h_plane, s_plane, v_plane, 0);

    //創建直方圖結構,並計算
    int h_bins = 30, s_bins = 32;
    CvHistogram *hist = NULL;

    //數組每個元素對應直方圖對應維數的bin的個數
    int hist_size[] = {h_bins, s_bins};
    //hue範圍[0,180]
    float h_ranges[] = {0, 180};
    float s_ranges[] = {0, 255};
    float *ranges[] = {h_ranges, s_ranges};

    hist = cvCreateHist(2,                      //直方圖維數爲2維
                        hist_size,              //直方圖每一維對應的bin數
                        CV_HIST_ARRAY,          //稠密矩陣存儲
                        ranges,                 //直方圖每一維的維數
                        1);                     //均勻直方圖
    //計算直方圖
    cvCalcHist(planes, hist, 0, 0);

    //顯示2維直方圖
    int scale = 20;
    IplImage *hist_img = cvCreateImage(cvSize(h_bins * scale, s_bins * scale),
                                       8, 3);
    cvZero( hist_img );

    float max_value = 0;
    cvGetMinMaxHistValue(hist, 0, &max_value, 0, 0);

    for(int h = 0; h < h_bins; h++)
    {
        for(int s = 0; s < s_bins; s++)
        {
            //獲取bin對應的最大值
            float bin_val = cvQueryHistValue_2D(hist, h, s);
            //顏色歸一化到[0,255]顯示
            int intensity = cvRound( bin_val * 255 / max_value);
            //顯示
            cvRectangle(
                        hist_img,
                        cvPoint( h*scale, s*scale),
                        cvPoint( (h+1)*scale - 1, (s+1)*scale - 1),
                        CV_RGB(intensity,intensity, intensity),
                        CV_FILLED
                        );
        }
    }
    cvNamedWindow("Source", 1);
    cvShowImage("Source", src);

    cvNamedWindow("H-S Histogram", 1);
    cvShowImage("H-S Histogram", hist_img);
    cvWaitKey(0);

    return 0;
}

 

 

相關文章
相關標籤/搜索