/*
直方图均衡化
*/
#include<opencv2\opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
void histogramcalculation(const Mat &img, Mat &histoImage); //得到直方图
int main() {
Mat img_org, img_tem;
Mat histImage,histImage2;
img_org = imread("D://图片//5.jpg");
if (img_org.empty()) {
cout << "图片加载失败!" << endl;
return -1;
}
imshow("show_org", img_org); //显示原始图片
vector<Mat> bgr_channels;
split(img_org, bgr_channels); //把每个通道的信息分离出来
histogramcalculation(img_org, histImage); //调用函数得到直方图
imshow("histImage_show", histImage);
equalizeHist(bgr_channels[0], bgr_channels[0]);
equalizeHist(bgr_channels[1], bgr_channels[1]);
equalizeHist(bgr_channels[2], bgr_channels[2]); //直方图均衡化,每个通道分别均衡
merge(bgr_channels, img_tem); //把处理完的通道信息合并到新的图像中去
imshow("result_show", img_tem); //显示均衡化后的图像
histogramcalculation(img_tem, histImage2); //再次调用画直方图函数,显示均衡处理后的图像的直方图
imshow("histImage_result", histImage2);
waitKey(0);
return 0;
}
void histogramcalculation(const Mat & img, Mat & histoImage) //画直方图,后者为输出图像,引用改变其值
{
int histSize = 255;
float range[] = { 0,256 }; //每个像素值在0~255间
const float* histRange = { range };
bool uniform = true;
bool accumulate = false;
Mat b_hist, g_hist, r_hist;
vector<Mat> bgr_channels;
split(img, bgr_channels); //得到每个通道的信息
calcHist(&bgr_channels[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate); //计算各直方图
calcHist(&bgr_channels[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate);
calcHist(&bgr_channels[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate);
int hist_w = 600, hist_h = 400; //直方图的整体大小
int bin_w = cvRound((double)hist_w / histSize); //根据图的宽度均分得到每个bin的宽度
Mat histImage(hist_h, hist_w, CV_8UC3, Scalar(120, 55, 133)); //组合整合所有的直方图显示的最后结果图片
normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat()); //结果归一化到直方图显示图上
normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
for (int i = 1; i < histSize; i++) { //绘制直方图
line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))), Point(bin_w*i, hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2);
line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))), Point(bin_w*i, hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2);
line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))), Point(bin_w*i, hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2);
}
histoImage = histImage; //赋值
}
运行结果:
也可以分开显示:
/*
分开显示直方图
*/
#include<opencv2\opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main() {
Mat img_org = imread("D://图片//5.jpg");
Mat b_hist, g_hist, r_hist;
int histSize = 255;
float range[] = { 0,256 };
const float* histRange = { range };
if (img_org.empty()) {
cout << "图片加载失败!" << endl;
return -1;
}
vector<Mat> bgr_channels;
split(img_org, bgr_channels);
int hist_w = 600, hist_h = 400;
int bin_w = cvRound((double)hist_w / histSize);
Mat B_hist(hist_h, hist_w, CV_8UC3, Scalar(33, 0, 122));
Mat G_hist(hist_h, hist_w, CV_8UC3, Scalar(33, 0, 122));
Mat R_hist(hist_h, hist_w, CV_8UC3, Scalar(33, 0, 122));
calcHist(&bgr_channels[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange);
calcHist(&bgr_channels[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange);
calcHist(&bgr_channels[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange);
normalize(b_hist, b_hist, 0, B_hist.rows, NORM_MINMAX, -1, Mat());
normalize(g_hist, g_hist, 0, G_hist.rows, NORM_MINMAX, -1, Mat());
normalize(r_hist, r_hist, 0, R_hist.rows, NORM_MINMAX, -1, Mat());
for (int i = 1; i < histSize; i++) {
line(B_hist, Point(bin_w*(i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))), Point(bin_w*i, hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2);
line(G_hist, Point(bin_w*(i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))), Point(bin_w*(i), hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2);
line(R_hist, Point(bin_w*(i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))), Point(bin_w*(i), hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2);
}
imshow("b_hist", B_hist);
imshow("g_hist", G_hist);
imshow("r_hist", R_hist);
waitKey(0);
destroyAllWindows;
return 0;
}
运行结果如下: