//图像直方图均衡
#include <stdio.h>
#include <iostream>
#include <string>
#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;
void drawHist(Mat &hist, int hist_w, int hist_h, int type, string name);
int main()
{
/*
直方图均衡可以把原本灰度集中的情况变为分散,这样就可以避免图像过暗或者过亮,使得图像的轮廓更加清晰
*/
Mat img = imread("gearwheel.jpg", IMREAD_GRAYSCALE);
//统计0~255各个灰度值的像素个数
const int channels[1] = {
0 };
Mat hist;
const int histSize[1] = {
256 };
float a[2] = {
0,255 };
const float * ranges[1] = {
a };
calcHist(&img, 1, channels, Mat(), hist, 1, histSize, ranges);//得到的hist是一个单通道,width=1,height=256的Mat变量
//归一化的直方图比较
drawHist(hist, 512, 400, NORM_INF, "hist_nor");
Mat img_equ;
equalizeHist(img, img_equ);
calcHist(&img_equ, 1, channels, Mat(), hist, 1, histSize, ranges);//得到的hist是一个单通道,width=1,height=256的Mat变量
drawHist(hist, 512, 400, NORM_INF, "hist_equ_nor");
//均衡后的灰度图对比
imshow("img", img);
imshow("img_equ", img_equ);
waitKey(0);
return 0;
}
//画直方图函数,传入参数:hist,图像宽,图像高,归一化方式,窗口名称
void drawHist(Mat &hist, int hist_w, int hist_h,int type, string name)//这个函数适合用NORM_INF方法
{
int width = 2;
Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);
normalize(hist, hist, 1, 0, type, -1, Mat());
for (int i = 1; i <= hist.rows; i++)
{
rectangle(histImage, Point(width*(i - 1), hist_h - 1),
Point(width*i - 1, hist_h - cvRound(hist_h*hist.at<float>(i - 1)) - 1),
Scalar(255, 255, 255), -1);
}
imshow(name, histImage);
}