直方图均衡化 — OpenCV 2.3.2 documentation http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/histograms/histogram_equalization/histogram_equalization.html#histogram-equalization
图像的直方图是什么?
- 直方图是图像中像素强度分布的图形表达方式.
- 它统计了每一个强度值所具有的像素个数.
直方图均衡化
#include "pch.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include
#include
using namespace cv;
using namespace std;
/** @function main */
int main(int argc, char** argv)
{
Mat src, dst;
const char* source_window = "Source image";
const char* equalized_window = "Equalized Image";
/// 加载源图像
src = imread("test.jpg", 1);
if (!src.data)
{
cout << "Usage: ./Histogram_Demo " << endl;
return -1;
}
resize(src, src,Size(500,500));
/// 转为灰度图
cvtColor(src, src, CV_BGR2GRAY);
/// 应用直方图均衡化
equalizeHist(src, dst);
/// 显示结果
namedWindow(source_window, CV_WINDOW_AUTOSIZE);
namedWindow(equalized_window, CV_WINDOW_AUTOSIZE);
imshow(source_window, src);
imshow(equalized_window, dst);
/// 等待用户按键退出程序
waitKey(0);
return 0;
}
直方图计算
#include "pch.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include
#include
using namespace std;
using namespace cv;
/** @函数 main */
int main(int argc, char** argv)
{
Mat src, dst;
/// 装载图像
src = imread("test.jpg", 1);
if (!src.data)
{
return -1;
}
/// 分割成3个单通道图像 ( R, G 和 B )
vector rgb_planes;
split(src, rgb_planes);
/// 设定bin数目
int histSize = 255;
/// 设定取值范围 ( R,G,B) )
float range[] = { 0, 255 };
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
Mat r_hist, g_hist, b_hist;
/// 计算直方图:
calcHist(&rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate);
calcHist(&rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate);
calcHist(&rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate);
// 创建直方图画布
int hist_w = 400; int hist_h = 400;
int bin_w = cvRound((double)hist_w / histSize);
Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0, 0));
/// 将直方图归一化到范围 [ 0, histImage.rows ]
normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
normalize(b_hist, b_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(r_hist.at(i - 1))),
Point(bin_w*(i), hist_h - cvRound(r_hist.at(i))),
Scalar(0, 0, 255), 2, 8, 0);
line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(g_hist.at(i - 1))),
Point(bin_w*(i), hist_h - cvRound(g_hist.at(i))),
Scalar(0, 255, 0), 2, 8, 0);
line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(b_hist.at(i - 1))),
Point(bin_w*(i), hist_h - cvRound(b_hist.at(i))),
Scalar(255, 0, 0), 2, 8, 0);
}
/// 显示直方图
namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE);
imshow("calcHist Demo", histImage);
waitKey(0);
return 0;
}