直接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)處理前后變換函數圖對比:

