直方圖計算


直方圖

  • 直方圖是對數據的集合 統計 ,並將統計結果分布於一系列預定義的 bins 中。

  • 這里的 數據 不僅僅指的是灰度值 , 統計數據可能是任何能有效描述圖像的特征。

  • 先看一個例子吧。 假設有一個矩陣包含一張圖像的信息 (灰度值 0-255):

 

 

直方圖對比可查看:直方圖對比

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

/** @函數 main */
int main(int argc, char** argv)
{
    Mat src, dst;

    /// 裝載圖像
    src = imread(argv[1], 1);

    if (!src.data)
    {
        return -1;
    }

    /// 分割成3個單通道圖像 ( R, G 和 B )
    vector<Mat> rgb_planes;
    split(src, rgb_planes);

    /// 設定bin數目
    int histSize = 255;

    /// 設定取值范圍 ( R,G,B) )
    float range[] = { 0, 255 };
    const float* histRange = { range };

    bool uniform = true; bool accumulate = false;

    Mat r_hist, g_hist, b_hist;

    /// 計算直方圖:
    calcHist(&rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate);
    calcHist(&rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate);
    calcHist(&rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate);

    // 創建直方圖畫布
    int hist_w = 400; int hist_h = 400;
    int bin_w = cvRound((double)hist_w / histSize);

    Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));

    /// 將直方圖歸一化到范圍 [ 0, histImage.rows ]
    normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
    normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
    normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());

    /// 在直方圖畫布上畫出直方圖
    for (int i = 1; i < histSize; i++)
    {
        line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),
            Point(bin_w*(i), hist_h - cvRound(r_hist.at<float>(i))),
            Scalar(0, 0, 255), 2, 8, 0);
        line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),
            Point(bin_w*(i), hist_h - cvRound(g_hist.at<float>(i))),
            Scalar(0, 255, 0), 2, 8, 0);
        line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
            Point(bin_w*(i), hist_h - cvRound(b_hist.at<float>(i))),
            Scalar(255, 0, 0), 2, 8, 0);
    }

    /// 顯示直方圖
    namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE);
    imshow("calcHist Demo", histImage);

    waitKey(0);

    return 0;

}

上面代碼計算一幅圖像的直方圖!

最重要的代碼:

OpenCV函數 calcHist 計算直方圖:

/// 計算直方圖:
calcHist( &rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate ); calcHist( &rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate ); calcHist( &rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate ); 

參數說明如下:

  • &rgb_planes[0]: 輸入數組(或數組集)
  • 1: 輸入數組的個數 (這里我們使用了一個單通道圖像,我們也可以輸入數組集 )
  • 0: 需要統計的通道 (dim)索引 ,這里我們只是統計了灰度 (且每個數組都是單通道)所以只要寫 0 就行了。
  • Mat(): 掩碼( 0 表示忽略該像素), 如果未定義,則不使用掩碼
  • r_hist: 儲存直方圖的矩陣
  • 1: 直方圖維數
  • histSize: 每個維度的bin數目
  • histRange: 每個維度的取值范圍
  • uniform 和 accumulate: bin大小相同,清楚直方圖痕跡

 


免責聲明!

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



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