直方图均衡化的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)处理前后变换函数图对比:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律