直方圖
-
直方圖是對數據的集合 統計 ,並將統計結果分布於一系列預定義的 bins 中。
-
這里的 數據 不僅僅指的是灰度值 , 統計數據可能是任何能有效描述圖像的特征。
-
先看一個例子吧。 假設有一個矩陣包含一張圖像的信息 (灰度值
):
#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大小相同,清楚直方圖痕跡