直方图均衡

Content

  • 计算灰度图像的归一化直方图

    具体内容:利用OpenCV对图像像素进行操作,计算归一化直方图。并在窗口中以图形的方式显示出来。

  • 灰度图像直方图均衡处理

    具体内容:通过计算归一化直方图,设计算法实现直方图均衡化处理。

  • 彩色图像直方图均衡处理

    具体内容:在灰度图像直方图均衡处理的基础上实现彩色直方图均衡处理。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <vector>
using namespace cv;
using namespace std;

// 计算归一化直方图
vector<float> computeNormalizedHistogram(const Mat& image)
{
vector<float> histogram(256, 0);
for (int r = 0; r < image.rows; r++)
{
for (int c = 0; c < image.cols; c++)
{
histogram[image.at<uchar>(r, c)]++;
}
}
// 归一化直方图
for (int i = 0; i < 256; i++)
{
histogram[i] /= (image.rows * image.cols);
}
return histogram;
}

// 显示直方图
void showHistogram(const vector<float>& histogram, string name)
{
//CV_8UC3 8位无符号整型,3通道
//Scalar(0, 0, 0) 初始化黑色
Mat histImage(256, 256, CV_8UC3, Scalar(0, 0, 0));
// 每一列宽度
int histWidth = histImage.cols / 256;
// 画出直方图
for (int i = 0; i < 256; i++) {
int histHeight = static_cast<int>(histogram[i] * histImage.rows*10);
rectangle(histImage, Point(i * histWidth, histImage.rows), Point((i + 1) * histWidth, histImage.rows - histHeight), Scalar(0, 0, 255), -1);
}

// 显示直方图
namedWindow(name, WINDOW_AUTOSIZE);
imshow(name, histImage);
imwrite(name + ".jpg", histImage);
}

// 计算累计直方图
vector<float> computecumulativeHistogram(const vector<float>& histogram)
{
vector<float> equalizedHistogram(256, 0);
// 计算累计直方图
vector<float> cumulativeHistogram(256, 0);
cumulativeHistogram[0] = histogram[0];
for (int i = 1; i < 256; i++)
{
cumulativeHistogram[i] = cumulativeHistogram[i - 1] + histogram[i];
}
return cumulativeHistogram;
}

// 灰度图像直方图均衡化处理
Mat equalizeHistogram(const Mat& image)
{
vector<float> hist = computeNormalizedHistogram(image);
vector<float> cumulativeHist = computecumulativeHistogram(hist);
Mat equalizedImage = image.clone();
for (int y = 0; y < image.rows; y++) {
for (int x = 0; x < image.cols; x++) {
int intensity = image.at<uchar>(y, x);
equalizedImage.at<uchar>(y, x) = cvRound(255 * cumulativeHist[intensity]);
}
}
return equalizedImage;
}

// 彩色图像直方图均衡化处理
Mat equalizedColorHistogram(const Mat& image)
{
Mat bgrChannels[3];
Mat equalizedBGRChannels[3];
split(image, bgrChannels);
for (int i = 0; i < 3; i++)
{
equalizedBGRChannels[i] = equalizeHistogram(bgrChannels[i]);
}
Mat equalizedColorImage;
merge(equalizedBGRChannels, 3, equalizedColorImage);
return equalizedColorImage;
}

int main()
{
Mat myImage = imread("wallhaven.jpg");
imshow("MyImage", myImage);
Mat grayImage;
cvtColor(myImage, grayImage, COLOR_BGR2GRAY); // 转换为灰度图像
imshow("GrayImage", grayImage);
imwrite("GrayImage.jpg", grayImage);

// 归一化直方图 0-1
vector<float> hist = computeNormalizedHistogram(grayImage);
showHistogram(hist,"Hist");

// 灰度图像直方图均衡化处理
Mat equalizedImage = equalizeHistogram(grayImage);
imshow("EqualizedImage", equalizedImage);
imwrite("EqualizedImage.jpg", equalizedImage);
// 显示直方图
vector<float> equalizedHist = computeNormalizedHistogram(equalizedImage);
showHistogram(equalizedHist, "equalizedHist");

// opencv直方图均衡化 用与对比正确性
//Mat equalizedImageCV;
//equalizeHist(grayImage, equalizedImageCV);
//imshow("OpenCV's Equalized Image", equalizedImage);

// 彩色图像直方图均衡化处理
Mat equalizedColorImage = equalizedColorHistogram(myImage);
imshow("EqualizedColorImage", equalizedColorImage);
imwrite("EqualizedColorImage.jpg", equalizedColorImage);

//opencv彩色图像直方图均衡化处理 用于对比正确性
//Mat bgrChannelsCV[3];
//split(myImage, bgrChannelsCV);
//for (int i = 0; i < 3; i++)
//{
// equalizeHist(bgrChannelsCV[i], bgrChannelsCV[i]);
//}
//Mat equalizedColorImageCV;
//merge(bgrChannelsCV, 3, equalizedColorImageCV);
//imshow("OpenCV's Equalized Color Image", equalizedColorImageCV);

waitKey(0);
return 0;
}

Output

灰图 彩图
GrayImage wallhaven
灰度图像直方图均衡处理 彩色图像直方图均衡处理
EqualizedImage EqualizedColorImage
直方图 均衡化直方图
Hist equalizedHist