【C++】【图像处理】直方图均衡算法解析(以.raw格式的图像为基础进行图像处理、gray levels:256)

 1 void hisEqualiz(BYTE* image, int w, int h, BYTE* outImg)
 2 {
 3     //直方图均衡
 4     int his[256];// 声明一个长度为256的数组,用于存储每个灰度级出现的频率
 5     int n, i, j;
 6 
 7     // 初始化直方图数组
 8     for (n = 0;n < 256;n++)
 9         his[n] = 0;
10 
11     // 统计原始图像的灰度直方图
12     for (i = 0;i < h;i++)
13         for (j = 0;j < w; j++)
14             his[image[i * w + j]]++; // 统计每个灰度级出现的频率
15 
16     /* 上述代码是生成灰度直方图 */
17 
18 
19     /* 
20     计算累积直方图——至关重要的步骤,这一步将his表示灰度级频率转换成了 <= 当前灰度级的所有像素点个数,
21         如 new_his[1] = old_his[0] + old_his[1] 假设=5,
22         而当new_his[2] = 100时,这就说明从灰度级1到灰度级2之间的数量跨度非常的大,我们需要重新对这100个像素点表示的灰度级重新分配。
23     */
24     for (n = 1;n < 256;n++)
25         hist[n] += his[n - 1];
26 
27     BYTE gray[256];// 存储经过均衡化后的灰度值
28     float cons;
29     cons = 255.0f / his[255];// 计算均衡化后的灰度值比例尺,即归一化因子 —— 这一步是将256个像素均匀的分配到每个像素点上,如图像有1000个像素点,则cons = 255 / 1000;
30 
31     // 计算均衡化后的灰度值
32     for (n = 0;n < 256;n++)
33         gray[n] = (BYTE)(cons * his[n]);// 对每个灰度级进行均衡化计算
34     /*
35     为什么是使用cons * new_his[],而不是和 old_his[]进行操作呢?
36     old_gray[] = {0, 1, 2, 3} —— 表示从0到3上的像素点的灰度级
37     假设old_his[] = {1, 201, 13, 50} —— 表示0到3这四个灰度级的个数
38     new_his[] = {1, 202, 215, 255} —— 经过累加后,变成 <= 当前灰度级的所有像素个数
39 
40     我们分别和cons(假设归一化因子是0.25)进行计算:
41     cons_old_his = {0.25, 50.25, 3.25, 12.5} = cons_old_gray —— cons_old_his此时表示每个像素点上的灰度级,我们对比 old_gray可以清晰的发现,原像素级是递增的,然是此时的cons_old_his确实第二个像素点的像素级最大,这不符合原图像
42     cons_new_his = {0.25, 50.5, 53.75, 63.75} = cons_new_gray —— 至此,这便是为什么是和 new_his 进行乘积,而不是 old_his 进行乘积。
43     
44     */
45 
46     // 应用均衡化后的灰度值到输出图像
47     for (i = 0;i < h;i++)
48         for (j = 0;j < w;j++)
49             outImg[i * w + j] = gray[image[i * w + j]];// 将均衡化后的灰度值应用到输出图像中
50 }

 

总结:直方图均衡的核心,即获取小于等于当前灰度级存在的所有的像素点,设定归一化因子,最后进行均衡化计算。

posted @ 2023-11-12 14:56  VanGoghpeng  阅读(66)  评论(0编辑  收藏  举报