opencv02直方图均衡

实验内容:

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

2、灰度图像直方图均衡处理

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

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

实验原理:

算法过程:

img

完整课程PPT和实验要求戳:https://github.com/MintLucas/Digital_image_process

讲解用注释标注在代码中

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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#include "Lab02_hisBalance.hpp"
#include<iostream>
#include<string>
#include<vector>

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

Mat equalize_hist(Mat& input)
{
int gray[256] = { 0 };
double gray_prob[256] = { 0 };
double gray_distribution[256] = { 0 };
int gray_equal[256] = { 0 };

int MN = 0;
Mat output = input.clone();
MN = input.cols * input.rows;

Mat_<uchar>::iterator it = output.begin<uchar>();
Mat_<uchar>::iterator end = output.end<uchar>();

for (; it < end; it++)
gray[*it]++;//统计像素值出现次数

it = output.begin<uchar>();
for(; it < end; it++)
gray_prob[*it] = ((double)gray[*it]/MN);//计算PDF

it = output.begin<uchar>();
gray_distribution[0] = gray_prob[0];
for (int i = 1; i < 256; i++)
//计算cdf
gray_distribution[i] = gray_distribution[i - 1] + gray_prob[i];

//映射后的像素值
for (int i = 0; i < 256; i++)
gray_equal[i] = (uchar)(255 * gray_distribution[i]);

it = output.begin<uchar>();
for(; it < end; it++)
*it = gray_equal[*it];

return output;
}

Mat color_equalize_hist(Mat input)
{
vector<Mat> channels;
split(input, channels);

for (int i = 0; i < channels.size(); i++)
channels[i] = equalize_hist(channels[i]);

Mat res;
merge(channels, res);
return res;
}

int drawHisRGB(Mat image)
{
int bins = 256;
int hist_size[] = { bins };
float range[] = { 0, 256 };
const float* ranges[] = { range };

MatND hist_r, hist_g, hist_b;
int channels_r[] = { 0 };
calcHist(&image, 1, channels_r, Mat(), // do not use mask
hist_r, 1, hist_size, ranges,
true, // the histogram is uniform
false);

int channels_g[] = { 1 };
calcHist(&image, 1, channels_g, Mat(), // do not use mask
hist_g, 1, hist_size, ranges,
true, // the histogram is uniform
false);

int channels_b[] = { 2 };
calcHist(&image, 1, channels_b, Mat(), // do not use mask
hist_b, 1, hist_size, ranges,
true, // the histogram is uniform
false);

double max_val_r, max_val_g, max_val_b;
minMaxLoc(hist_r, 0, &max_val_r, 0, 0);
minMaxLoc(hist_g, 0, &max_val_g, 0, 0);
minMaxLoc(hist_b, 0, &max_val_b, 0, 0);
int scale = 1;

int hist_height = 256;
Mat colorHis = Mat::zeros(hist_height, bins * 3, CV_8UC3);
for (int i = 0; i < bins; i++)
{
float bin_val_r = hist_r.at<float>(i);
float bin_val_g = hist_g.at<float>(i);
float bin_val_b = hist_b.at<float>(i);
int intensity_r = cvRound(bin_val_r*hist_height / max_val_r); //“™ªÊ÷∆µƒ∏fl∂»
int intensity_g = cvRound(bin_val_g*hist_height / max_val_g); //“™ªÊ÷∆µƒ∏fl∂»
int intensity_b = cvRound(bin_val_b*hist_height / max_val_b); //“™ªÊ÷∆µƒ∏fl∂»
rectangle(colorHis, Point(i*scale, hist_height - 1),
Point((i + 1)*scale - 1, hist_height - intensity_r),
CV_RGB(255, 0, 0));

rectangle(colorHis, Point((i + bins)*scale, hist_height - 1),
Point((i + bins + 1)*scale - 1, hist_height - intensity_g),
CV_RGB(0, 255, 0));

rectangle(colorHis, Point((i + bins * 2)*scale, hist_height - 1),
Point((i + bins * 2 + 1)*scale - 1, hist_height - intensity_b),
CV_RGB(0, 0, 255));

}
imgShow(colorHis, "colorHis");
return 0;

}

int drawHisGray(Mat image)
{
int bins = 256;
int hist_size[] = { bins };
float range[] = { 0, 256 };
const float* ranges[] = { range };

MatND hist;
int channels[] = { 0 };
calcHist(&image, 1, channels, Mat(), // do not use mask
hist, 1, hist_size, ranges,
true, // the histogram is uniform
false);

double max_val;
minMaxLoc(hist, 0, &max_val, 0, 0);

int scale = 2;
int hist_height = 256;
Mat hist_img = Mat::zeros(hist_height, bins*scale, CV_8UC3);
for (int i = 0; i < bins; i++)
{
float bin_val = hist.at<float>(i);
int intensity = cvRound(bin_val*hist_height / max_val);

rectangle(hist_img, Point(i*scale, hist_height - 1),
Point((i + 1)*scale - 1, hist_height - intensity),
CV_RGB(255, 255, 255));
}

imgShow(hist_img, "histOfImg");
return 0;
}

int drawHis2D(Mat image)
{
int hbins = 256, sbins = 256;
int histSize[] = { hbins, sbins };

float hranges[] = { 0, 256 };
float sranges[] = { 0, 256 };
const float* ranges[] = { hranges, sranges };
MatND hist;

int channels[] = { 0, 1 };
calcHist(&image, 1, channels, Mat(), // do not use mask
hist, 2, histSize, ranges,
true, // the histogram is uniform
false);
double maxVal = 0;
minMaxLoc(hist, 0, &maxVal, 0, 0);
int scale = 2;
Mat histImg = Mat::zeros(sbins*scale, hbins*scale, CV_8UC3);
for (int h = 0; h < hbins; h++)
for (int s = 0; s < sbins; s++)
{
float binVal = hist.at<float>(h, s);
int intensity = cvRound(binVal * 255 / maxVal);
rectangle(histImg, Point(h*scale, s*scale),
Point((h + 1)*scale - 1, (s + 1)*scale - 1),
Scalar::all(intensity),
FILLED);
}
imgShow(histImg, "2Dhist");
return 0;
}

//int main()
//{
// // 以黑白方式载入图像
// Mat img = imread("/Users/zhipeng/ustc_term2/Opencv/Opencv/Opencv/Digital_imgae_process/CSet12/lena.png", 0);
// Mat colorImg = imread("/Users/zhipeng/ustc_term2/Opencv/Opencv/Opencv/Digital_imgae_process/CSet12/lena.png", 1);
// // 检测图像是否真的被载入
// if(img.empty() || colorImg.empty())
// return -1;
// drawHisGray(img);
// Mat gray_equalized = equalize_hist(img);
// drawHisGray(gray_equalized);
//
// drawHisRGB(colorImg);
// Mat color_equalized = color_equalize_hist(colorImg);
// drawHisRGB(color_equalized);
//
// imgShow(colorImg, "colorImg");
// imgShow(color_equalized, "color_equalized");
// return 0;
//}

`