直方圖計算: 輸入圖像Mat,儲存直方圖Mat,直方圖畫布Mat
void R_histogram(Mat src,Mat histimg)
{
//------------------------計算直方圖----------------------------//
int histsize =256;//bin數量
float range[] = {0,255};//2個數的數組
const float* histRange = {range};//取值範圍,histRange指針指向range數組
Mat r_Hist;
//輸入數組的個數1,單通道0,儲存直方圖的矩陣r_Hist,直方圖維數1,每個維度的bin數目&histsize,每個維度的取值範圍&histRange,bin大小相同,清除直方圖痕跡
calcHist(&src,1,0,Mat(),r_Hist,1,&histsize,&histRange,true,false);
//------------------------直方圖歸一化----------------------------//
//直方圖的畫布histImage
histimg = Scalar::all(0);//只在R直方圖上清零
int bin_w = cvRound( (double) histimg.cols/histsize );//四捨五入
//將直方圖歸一化到範圍 [0, hist_h]
normalize(r_Hist,r_Hist,0,histimg.rows,NORM_MINMAX,-1,Mat());
//------------------------畫直方圖----------------------------//
for (int i = 1; i<histsize; i++)
{
line( histimg, Point( bin_w*(i-1), histimg.rows - cvRound(r_Hist.at<float>(i-1)) ) ,
Point( bin_w*(i), histimg.rows - cvRound(r_Hist.at<float>(i)) ),
Scalar( 0, 0, 255), 0.1 );
}
}
void G_histogram(Mat src,Mat histimg)
{
//vector<Mat> rgb_channel;
//split(src, rgb_channel);
//------------------------計算直方圖----------------------------//
int histsize =256;//bin數量
float range[] = {0,255};//2個數的數組
const float* histRange = {range};//取值範圍,histRange指針指向range數組
Mat g_Hist;
//輸入數組的個數1,單通道0,儲存直方圖的矩陣g_Hist,直方圖維數1,每個維度的bin數目&histsize,每個維度的取值範圍&histRange,bin大小相同,清除直方圖痕跡
calcHist(&src,1,0,Mat(),g_Hist,1,&histsize,&histRange,true,false);
//------------------------直方圖歸一化----------------------------//
//直方圖的畫布histimg
int bin_w = cvRound( (double) histimg.cols/histsize );//四捨五入
//將直方圖歸一化到範圍 [0, histimg.rows]
normalize(g_Hist,g_Hist,0,histimg.rows,NORM_MINMAX,-1,Mat());
//------------------------畫直方圖----------------------------//
for (int i = 1; i<histsize; i++)
{
line( histimg, Point( bin_w*(i-1), histimg.rows - cvRound(g_Hist.at<float>(i-1)) ) ,
Point( bin_w*(i), histimg.rows - cvRound(g_Hist.at<float>(i)) ),
Scalar( 0, 255, 0), 0.1 );
}
}
void B_histogram(Mat src,Mat histimg)
{
//------------------------計算直方圖----------------------------//
int histsize =256;//bin數量
float range[] = {0,255};//2個數的數組
const float* histRange = {range};//取值範圍,histRange指針指向range數組
Mat b_Hist;
//輸入數組的個數1,單通道0,儲存直方圖的矩陣b_Hist,直方圖維數1,每個維度的bin數目&histsize,每個維度的取值範圍&histRange,bin大小相同,清除直方圖痕跡
calcHist(&src,1,0,Mat(),b_Hist,1,&histsize,&histRange,true,false);
//------------------------直方圖歸一化----------------------------//
// 創建顯示直方圖的畫布histImage[hist_w ,hist_h]
int bin_w = cvRound( (double) histimg.cols/histsize );//四捨五入
//將儲存直方圖的Mat歸一化到範圍 [0, hist_h]
normalize(b_Hist,b_Hist,0,histimg.rows,NORM_MINMAX,-1,Mat());
//------------------------畫直方圖----------------------------//
for (int i = 1; i<histsize; i++)
{
line( histimg, Point( bin_w*(i-1), histimg.rows - cvRound(b_Hist.at<float>(i-1)) ) ,
Point( bin_w*(i), histimg.rows - cvRound(b_Hist.at<float>(i)) ),
Scalar(255,0,0), 0.1 );
}
}
void main()
{
Mat src,src1;
src = imread("weed.jpg");
src1 = imread("beijing.jpg");
Mat histimg = Mat(400, 400, CV_8UC3);
vector<Mat> rgb_channel;
split(src, rgb_channel);
Mat R=rgb_channel[2];
Mat G=rgb_channel[1];
Mat B=rgb_channel[0];
R_histogram(R,histimg);
G_histogram(G,histimg);
B_histogram(B,histimg);
namedWindow("rgb_Histogram");
imshow("rgb_Histogram",histimg);
waitKey(0);
}