直方图均衡化的C语言代码。
直接PO代码:
1 #include <stdio.h>
2 #include <math.h>
3 #include "graphics.h"
4
5 /*
6 功能: 在整型数组中找到最小值和最大值
7 输入: 整型数组;数组大小;接收最小值;接收最大值
8 结果: 得到数组中的最小值和最大值
9 */
10 void GetMinMaxInt(int *arr, int n, int &min, int &max);
11 /*
12 功能: 在浮点型数组中找到最小值和最大值
13 输入: 浮点型数组;数组大小;接收最小值;接收最大值
14 结果: 得到数组中的最小值和最大值
15 */
16 void GetMinMaxDouble(double *arr, int n, double &min, double &max);
17 /*
18 功能: 打印灰度图
19 输入: 存储灰度图的动态数组;宽;高
20 结果: 图像窗口显示灰度图
21 */
22 void PrintGrayImage(double *gray_mtx, int w, int h);
23 /*
24 功能: 获取输入的彩色图像,并转为灰度图
25 输入: 图像完整文件名;存储图像灰度图的动态数组;宽;高;是否在窗口打印
26 结果: 相应图像灰度数据赋值到动态数组mx中(1打印 0不打印)
27 */
28 void GetImageGray(char *file, double *mx, int w, int h, int mode);
29 /*
30 功能: 打印灰度直方图
31 输入: 存储灰度图的动态数组;宽;高
32 结果: 图像窗口打印灰度直方图
33 */
34 void ShowHistogram(double *mx, int w, int h);
35 /*
36 功能: 直方图均衡化
37 输入: 原图像及其尺寸;输出图像
38 结果: 对图像进行直方图均衡化处理
39 */
40 void HistogramEqualization(double *mtx, int w, int h, double *out);
41
42 int main() {
43 int w=640, h=640;
44 char file_name[] = "image.jpg";
45
46 initgraph(w, h, 0);
47 setcaption("直方图均衡化");
48
49 /* 获取输入图像灰度图 */
50 double *gray_mtx = (double *)malloc(w*h*sizeof(double));
51 GetImageGray(file_name, gray_mtx, w, h, 0);
52
53 /* 打印输入图像灰度直方图 */
54 // ShowHistogram(gray_mtx, w, h);
55
56
57 /* 直方图均衡化 */
58 double *out_mtx = (double *)malloc(w*h*sizeof(double));
59 HistogramEqualization(gray_mtx, w, h, out_mtx);
60
61
62 /* 打印处理后的图像 */
63 PrintGrayImage(out_mtx, w, h);
64
65 /* 打印处理后图像灰度直方图 */
66 // ShowHistogram(out_mtx, w, h);
67
68 getch();
69 free(gray_mtx);
70 free(out_mtx);
71 closegraph();
72 return 0;
73 }
74
75 /* 在整型数组中找到最小值和最大值 */
76 void GetMinMaxInt(int *arr, int n, int &min, int &max) {
77 min = 0x7fffffff;
78 max = 0x80000000;
79 for(int i=0; i<n; i++) {
80 if(arr[i] > max) max = arr[i];
81 if(arr[i] < min) min = arr[i];
82 }
83 }
84 /* 在浮点型数组中找到最小值和最大值 */
85 void GetMinMaxDouble(double *arr, int n, double &min, double &max) {
86 min = 1.7976931348623158e+308;
87 max = 2.2250738585072014e-308;
88 for(int i=0; i<n; i++) {
89 if(arr[i] > max) max = arr[i];
90 if(arr[i] < min) min = arr[i];
91 }
92 }
93
94
95 /* 打印灰度图 */
96 void PrintGrayImage(double *gray_mtx, int w, int h) {
97 int i, j, gray;
98 for(i=0; i<w; i++) {
99 for(j=0; j<h; j++) {
100 gray = *(gray_mtx+h*i+j) * 255.0;
101 putpixel(i, j, EGEGRAY(gray));
102 }
103 }
104 }
105 /* 获取输入的彩色图像,并转为灰度图 */
106 void GetImageGray(char *file, double *mx, int w, int h, int mode) {
107 color_t color;
108 int i, j, red, green, blue, gray;
109 PIMAGE pimg = newimage();
110 getimage(pimg, file, w, h);
111
112 for(i=0; i<w; i++) {
113 for(j=0; j<h; j++) {
114 color = getpixel(i, j, pimg);
115 red = EGEGET_R(color);
116 green = EGEGET_G(color);
117 blue = EGEGET_B(color);
118 // 转化为灰度图
119 gray = (red*38 + green*75 + blue*15) >> 7;
120 *(mx+h*i+j) = gray / 255.0;
121 // printf("(%d,%d) %lf\n", i, j, gray/255.0);
122 }
123 }
124 // 是否打印灰度图像
125 if(mode) {
126 PrintGrayImage(mx, w, h);
127 }
128 delimage(pimg);
129 }
130 /* 打印灰度直方图 */
131 void ShowHistogram(double *mx, int w, int h) {
132 int i, gray_level[256]={0}, gl;
133 for(i=0; i<w*h; i++) {
134 // 像素点的灰度级计数
135 gl = floor(*(mx+i) * 255.0);
136 gray_level[gl]++;
137 }
138 // 左上角的坐标,坐标轴最大像素高度,间隔像素点
139 int dgx=0, dgy=0, dgh=600, ii=1;
140 int min, max;
141 GetMinMaxInt(gray_level, 256, min, max);
142 int sX, sY, eX, eY;
143 for(i=0; i<256; i++) {
144 sX = dgx + i*(ii+1);
145 sY = dgy + dgh;
146 eX = dgx + i*(ii+1);
147 eY = dgy + dgh-dgh*gray_level[i]/max;
148 line(sX, sY, eX, eY);
149 }
150 }
151 /* 直方图均衡化 */
152 void HistogramEqualization(double *mtx, int w, int h, double *out) {
153 int i, j, sum;
154 /* 原图像灰度级像素点计数 */
155 int gray_level[256] = {0};
156 for(i=0; i<w*h; i++) {
157 // 像素点的灰度级计数
158 gray_level[int(*(mtx+i) * 255.0 + 0.5)]++;
159 }
160
161 /* 图像的归一化灰度分布及概率 */
162 double sk=0.0, tmp; // 变换函数
163 double ia=0.0, ib=1.0/255.0, mid; // 定义两个变量,用于寻找最接近的灰度级
164 /* 像素映射关系(用于对图像的像素进行处理) */
165 double corresponding[256];
166 for(i=0; i<256; i++) {
167 tmp = 1.0*gray_level[i]/(w*h);
168 sk += tmp;
169 // 寻找最接近的灰度级
170 while(sk > ib) {
171 ia += 1.0/255.0;
172 ib += 1.0/255.0;
173 }
174 mid = (ia+ib)/2.0;
175 if(sk > mid) corresponding[i] = ib;
176 else corresponding[i] = ia;
177 }
178
179 /* 图像的直方图均衡化转换 */
180 for(i=0; i<w; i++) {
181 for(j=0; j<h; j++) {
182 *(out+h*i+j) = corresponding[int(*(mtx+h*i+j) * 255.0 + 0.5)];
183 }
184 }
185 }
(1)原图:
(2)处理前后灰度图对比:
(3)处理前后灰度直方图对比:
(4)处理前后变换函数图对比: