一、概述
二、一维灰度直方图
#include "opencv2/opencv.hpp"
#include<iostream>
using namespace cv;
using namespace std; void main()
{
Mat img = imread("E://0.jpg", ); //以灰度方式打开,灰度图和彩色图直方图结果不同
imshow("src", img); Mat dstHist; //定义存储直方图变量
int dims = ; //需要统计的特征数目(只统计灰度值)
float hranges[] = {, }; //范围[0,256),注意是最大值加1
const float* ranges[] = {hranges};
int bins = ;//组距:简单理解为直方图分为几个柱子
int channels = ;
//计算直方图
calcHist(&img, , &channels, Mat(), dstHist, dims, &bins, ranges); int scale = ;
Mat dstImg(bins * scale, bins*, CV_8UC3, Scalar()); //定义直方图输出图像,长×宽
double minValue = ;
double maxValue = ;
minMaxLoc(dstHist, &minValue, &maxValue);//统计直方图dstHist的最小最大值,并返回该值位置
int hpt = saturate_cast<int>(0.9*bins); //设置最大值并防止溢出
int j=;
//绘制直方图
for(int i=; i<; i++)
{
float binValue = dstHist.at<float>(i);
//if(i>250)
cout<<"i="<<i<<"---Value="<<binValue<<endl;
int realValue = saturate_cast<int>(binValue*hpt/maxValue); //归一化数据
//cout<<"i="<<i<<"---Value="<<realValue<<endl;
line(dstImg, Point(i*scale, bins-), Point(i*scale, bins-realValue), Scalar(, , ), , );//左上角和右下角坐标,坐标系如下图所示
//rectangle(dstImg, Point(i*scale, bins-1), Point(i*scale+1, bins-realValue), Scalar(0, 255, 0), 1);
//rectangle(dstImg, Point(j*scale, bins-1), Point(j*scale+1, bins-realValue), Scalar(rand()%255, rand()%255, rand()%255), -1);
//rectangle(dstImg, Point(j*scale, bins-1), Point(j*scale+1, bins-realValue), Scalar(rand()%255, rand()%255, rand()%255), -1);
//j=j+3;
}
imshow("Histogram", dstImg);
waitKey();
destroyAllWindows();
}
第35行代码的坐标为Point(i*scale, bins-1), Point(i*scale, bins-realValue)的原因。
如果觉得直方图太密集了,可以调整宽度
三、不均匀灰度直方图
#include "opencv2/opencv.hpp"
#include<iostream>
using namespace cv;
using namespace std; void main()
{
Mat img = imread("E://0.jpg",);
imshow("src", img); Mat dstHist;
int channels = ;
int histSize[]={};
float hranges[]={,,,,,};
const float* ranges[]={hranges};
int size=;
//计算直方图
calcHist(&img,,&channels,Mat(),dstHist,,histSize,ranges,false); int scale=;
Mat dstImg(size*scale,size,CV_8UC3,Scalar());
double minValue=;
double maxValue=;
minMaxLoc(dstHist,&minValue,&maxValue,,);
int hpt=saturate_cast<int>(0.9*size);//设置最大值并防止溢出
int j=;
for (int i = ; i < ; i++)
{
float binValue=dstHist.at<float>(i);
cout<<"i="<<i<<"---Value="<<binValue<<endl;
int realValue=saturate_cast<int>(binValue*hpt/maxValue);
rectangle(dstImg,Point(j*scale,size-),Point((j+)*scale-,size-realValue),Scalar(, , ), -);
j+=;
} imshow("Histogram", dstImg);
waitKey();
destroyAllWindows(); }
四、RGB三色直方图
#include "opencv2/opencv.hpp"
using namespace cv; void main()
{
Mat src=imread("E://0.jpg");
int bins = ;
int hist_size[] = {bins};
float range[] = { , };
const float* ranges[] = { range};
Mat hist_r,hist_g,hist_b; int channels_r[] = {};
calcHist( &src, , channels_r, Mat(), // do not use mask
hist_r, , hist_size, ranges,
true, // the histogram is uniform
false ); int channels_g[] = {};
calcHist( &src, , channels_g, Mat(),hist_g, , hist_size, ranges,true,false);
int channels_b[] = {};
calcHist( &src, , channels_b, Mat(),hist_b, , hist_size, ranges,true,false); double max_val_r,max_val_g,max_val_b;
minMaxLoc(hist_r, , &max_val_r, , );
minMaxLoc(hist_g, , &max_val_g, , );
minMaxLoc(hist_b, , &max_val_b, , );
int scale = ;
int hist_height=;
Mat hist_img = Mat::zeros(hist_height, bins*+, CV_8UC3);
for(int i=;i<bins;i++)
{
float bin_val_r = hist_r.at<float>(i);
float bin_val_g = hist_g.at<float>(i);
float bin_val_b = hist_b.at<float>(i);
int intensity_r = cvRound(bin_val_r*hist_height/max_val_r); //要绘制的高度
int intensity_g = cvRound(bin_val_g*hist_height/max_val_g); //要绘制的高度
int intensity_b = cvRound(bin_val_b*hist_height/max_val_b); //要绘制的高度
rectangle(hist_img,Point(i*scale,hist_height-),
Point((i+)*scale - , hist_height - intensity_r),
CV_RGB(,,)); rectangle(hist_img,Point((i+bins)*scale,hist_height-),
Point((i+bins+)*scale - , hist_height - intensity_g),
CV_RGB(,,)); rectangle(hist_img,Point((i+bins*)*scale,hist_height-),
Point((i+bins*+)*scale - , hist_height - intensity_b),
CV_RGB(,,)); }
imshow( "src", src );
imshow( "RGB Histogram", hist_img ); waitKey();
destroyAllWindows(); }
五、二维直方图
#include "opencv2/opencv.hpp"
using namespace cv; void main()
{
Mat src=imread("E://0.jpg");
Mat hsv;
int Bbins = , Gbins = ;
int histSize[] = {Bbins, Gbins};
float hranges[] = { , };
float sranges[] = { , };
const float* ranges[] = { hranges, sranges };
Mat hist; int channels[] = {, };
calcHist( &src, , channels, Mat(), hist, , histSize, ranges);
double maxVal=;
minMaxLoc(hist, , &maxVal, , );
int scale = ;
Mat histImg = Mat::zeros(Bbins*(scale), Bbins*(scale), CV_8UC3);
for( int h = ; h < Bbins; h++ )
for( int s = ; s < Bbins; s++ )
{
float binVal = hist.at<float>(h, s);
//cout<<"h="<<h<<"s="<<s<<"binValue="<<binVal<<endl;
//int intensity = cvRound(binVal*255/maxVal);
int intensity = int(binVal*/maxVal);
rectangle( histImg, Point(h*scale, s*scale),
Point((h+)*scale - , (s+)*scale - ),
Scalar::all(intensity),CV_FILLED );
}
namedWindow( "Source", );
imshow( "Source", src );
namedWindow( "B-G Histogram", );
imshow( "B-G Histogram", histImg ); waitKey();
destroyAllWindows(); }