#include <iostream>
#include "highgui.h"
#include "cv.h"
#include "cxcore.h"
#include "math.h"
using namespace std;
using namespace cv;
//绘制1维直方图
Mat draw1DHistogram(Mat histogramMat) {
double maxVal = 0, minVal = 0;
minMaxLoc(histogramMat, &minVal, &maxVal, 0, 0);
Mat histImage(histogramMat.rows, histogramMat.rows, CV_8U, Scalar(255));
int hpt = static_cast<int>(0.9 * histogramMat.rows);
for (int h = 0; h < histogramMat.rows; h++) {
float binVal = histogramMat.at<float>(h);
int intensity = static_cast<int>((binVal / maxVal) * hpt);
line(histImage, Point(h, histogramMat.rows - 1),
Point(h, histogramMat.rows - 1 - intensity), Scalar::all(0));
}
return histImage;
}
//一维直方图计算(采用实际图像) 实验2
void get1DHistogramExperiment2(Mat& image) {
//计算直方图 使用的图片数量
int nImageArrays = 1;
//使用的直方图数组
Mat* imageArrays = new Mat[nImageArrays];
//加载实际图像
// Mat image = imread("e:\\citywall1.bmp", 0);
if (image.data == NULL) {
printf("加载图像失败\n");
return;
}
imageArrays[0] = image;
//直方图的维数
const int dims = 1;
//在图像的通道序列中 本次直方图计算使用了哪些通道,本代码中使用了编号为0的通道
int channels[dims] = { 0 };
//直方图中每一维上的bin数,本代码是创建一维直方图 并且 分为256个bin
int histBins[dims] = { 256 };
//保存直方图的结果 CV_32F,dims说明矩阵的维度,histBins说明矩阵每一维上的大小
Mat histND(dims, histBins, CV_32F, Scalar::all(0));
//手动指定各个bin的取值范围
//float image1Range[5]={0.0,50.0,200.0,220.0,256.0};
//统一分割,只需要指定bin[0]的下限值和bin[histBins[dims-1]-1]的上限值即可
float image1Range[5] = { 0.0, 256.0 };
//各个通道的 bin划分规则
const float* allRanges[dims] = { image1Range };
//直方图计算
calcHist(imageArrays, nImageArrays, channels, Mat(), histND, dims, histBins,
allRanges, true);
//绘制直方图
Mat histImage = draw1DHistogram(histND);
//显示直方图
namedWindow("hist");
imshow("hist", histImage);
waitKey(0);
}
/**
* 直方图均衡
*/
void HistogramEqual(Mat& src){
Mat dst;
equalizeHist(src,dst); //直方图均衡化
get1DHistogramExperiment2(dst);
namedWindow("equal");
imshow("equal",dst);
waitKey(0);
}
int main() {
Mat image = imread("e:\\test.bmp", CV_LOAD_IMAGE_GRAYSCALE);
namedWindow("src");
imshow("src",image);
get1DHistogramExperiment2(image);
HistogramEqual(image);
return 0;
}