1 直方圖
灰階直方圖的定義
灰階直方圖是灰階級的函數,描述圖像中該灰階級的像素個數(或該灰階級像素出現的頻率):其橫坐标是灰階級,縱坐标表示圖像中該灰階級出現的個數(頻率)。
一維直方圖的結構表示為
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLzMjN38FM3UTMxkzNzMTMvwVNy8CX1AjMxAjMvw1ckF2bsBXdvwFdl5mLuR2cj5Set1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
高維直方圖可以了解為圖像在每個次元上灰階級分布的直方圖。常見的是二維直方圖。如紅-藍直方圖的兩個分量分别表示紅光圖像的灰階值和藍光圖像灰階值的函數。其圖像坐标(Dr,Db)處對應在紅光圖像中具有灰階級Dr同時在藍光圖像中具有灰階級Db的像素個數。這是基于多光譜——每個像素有多個變量——的數字圖像,二維中對應每個像素統計個變量。
簡單的說,直方圖就是對資料進行統計,将統計值組織到一系列事先定義好的bin中。bin的數值是從資料中計算出的特征的統計量,這些資料可以是諸如梯度,方向,色彩或者任何其他特征。無論如何,直方圖獲得的是資料分布的統計圖。通常直方圖的資料要低于原始資料。由于原始資料點可以表征任何事情,是以直方圖實際上是一個友善表示圖像特征的手段。
2 灰階直方圖的計算
// Histogram.cpp : 定義控制台應用程式的入口點。
//
/***********************************************************************
* OpenCV 2.4.4 測試例程
* 杜健健 提供
***********************************************************************/
#include "stdafx.h"
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
//參數:Gray_img --輸入的灰階圖像
// hist 計算後輸出的直方圖
void myCal_Hist(Mat Gray_img,MatND hist){
int bins = 256;
int hist_size[] = {bins};
float range[] = { 0, 256 };
const float* ranges[] = { range};
int channels[] = {0};
//計算直方圖
calcHist( &Gray_img, 1, channels, Mat(), // do not use mask
hist, 1, hist_size, ranges,
true, // the histogram is uniform
false );
//繪制直方圖圖像
int hist_height=256;
//int bins = 256;
double max_val; //直方圖的最大值
int scale = 2; //直方圖的寬度
minMaxLoc(hist, 0, &max_val, 0, 0); //計算直方圖最大值
Mat hist_img = Mat::zeros(hist_height,bins*scale, CV_8UC3); //建立一個直方圖圖像并初始化為0
cout<<"max_val = "<<max_val<<endl;
//在直方圖圖像中寫入直方圖資料
for(int i=0;i<bins;i++)
{
float bin_val = hist.at<float>(i); // 第i灰階級上的數
int intensity = cvRound(bin_val*hist_height/max_val); //要繪制的高度
//填充第i灰階級的資料
rectangle(hist_img,Point(i*scale,hist_height-1),
Point((i+1)*scale - 1, hist_height - intensity),
CV_RGB(255,255,255));
}
imshow( "Gray Histogram2", hist_img );
}
//根據直方圖資料繪制并顯示直方圖圖像
void myShow_Histogram(MatND &hist,int scale){
int hist_height=256;
int bins = 256;
double max_val;
minMaxLoc(hist, 0, &max_val, 0, 0);
Mat hist_img = Mat::zeros(hist_height,bins*scale, CV_8UC3);
cout<<"max_val = "<<max_val<<endl;
for(int i=0;i<bins;i++)
{
float bin_val = hist.at<float>(i); //
int intensity = cvRound(bin_val*hist_height/max_val); //要繪制的高度
rectangle(hist_img,Point(i*scale,hist_height-1),
Point((i+1)*scale - 1, hist_height - intensity),
CV_RGB(255,255,255));
}
imshow( "Gray Histogram2", hist_img );
}
int _tmain(int argc, _TCHAR* argv[])
{
Mat src,gray,src2,gray2;
//src=imread("D://input//buti.jpg");
src = imread("D://input//yalefaces//01//s1.bmp");
cvtColor(src,gray,CV_RGB2GRAY); //轉換成灰階圖
src2 = imread("D://input//yalefaces//02//s1.bmp");
cvtColor(src2,gray2,CV_RGB2GRAY); //轉換成灰階圖
MatND hist2;
imshow( "Source", src );
//imshow( "Gray Histogram", hist_img );
imshow("Source2",src2);
myCal_Hist(gray2,hist2);
//myShow_Histogram(hist2,5);
waitKey();
return 0;
}
3 示例展示
4 參考
http://blog.csdn.net/xiaowei_cqu/article/details/7600666
http://blog.csdn.net/xiaowei_cqu/article/details/8833799#comments