迭代式的图像分割的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 int main() { 37 int w=1080, h=786; 38 char file_name[] = "uni.jpg"; 39 40 initgraph(w, h, 0); 41 setcaption("迭代式阈值的图像分隔"); 42 43 int i, j; 44 45 /* 获取输入图像灰度图 */ 46 double *gray_mtx = (double *)malloc(w*h*sizeof(double)); 47 GetImageGray(file_name, gray_mtx, w, h, 0); 48 49 /* 打印输入图像灰度直方图 */ 50 // ShowHistogram(gray_mtx, w, h); 51 52 53 /* 迭代式阈值的图像分隔 */ 54 // 默认亮像素为背景,暗像素为前景,其实无关紧要 55 double min, max, tk; 56 GetMinMaxDouble(gray_mtx, w*h, min, max); 57 // 设置初始阈值 58 tk = (min+max) / 2.0; 59 // 背景和前景像素的个数 60 int flag=1, back_num, fore_num; 61 // 背景和前景像素值的总和 62 double back_sum, fore_sum, tmp, back_avg, fore_avg; 63 // 根据阈值将图像分割为背景和前景,分别求平均灰度 64 while(flag) { 65 back_num=0; 66 fore_num=0; 67 back_sum=0.0; 68 fore_sum=0.0; 69 for(i=0; i<w; i++) { 70 for(j=0; j<h; j++) { 71 tmp = *(gray_mtx+h*i+j); 72 if(tmp >= tk) { 73 // 背景 74 back_num += 1; 75 back_sum += tmp; 76 } else { 77 // 前景 78 fore_num += 1; 79 fore_sum += tmp; 80 } 81 } 82 } 83 // 计算背景和前景的灰度平均值 84 back_avg = 1.0 * back_sum / back_num; 85 fore_avg = 1.0 * fore_sum / fore_num; 86 if((int)(tk*255.0) == (int)((back_avg+fore_avg)/2.0*255.0)) { 87 flag = 0; 88 } else { 89 tk = (back_avg+fore_avg) / 2.0; 90 } 91 } 92 93 /* 根据图像边缘分割图像 */ 94 double *edge_mtx = (double *)malloc(w*h*sizeof(double)); 95 for(i=0; i<w; i++) { 96 for(j=0; j<h; j++) { 97 if(*(gray_mtx+h*i+j) >= tk) { 98 *(edge_mtx+h*i+j) = 0.0; 99 } else { 100 *(edge_mtx+h*i+j) = 1.0; 101 } 102 } 103 } 104 105 /* 打印分割后的图像 */ 106 PrintGrayImage(edge_mtx, w, h); 107 108 109 getch(); 110 free(gray_mtx); 111 free(edge_mtx); 112 closegraph(); 113 return 0; 114 } 115 116 /* 在整型数组中找到最小值和最大值 */ 117 void GetMinMaxInt(int *arr, int n, int &min, int &max) { 118 min = 0x7fffffff; 119 max = 0x80000000; 120 for(int i=0; i<n; i++) { 121 if(arr[i] > max) max = arr[i]; 122 if(arr[i] < min) min = arr[i]; 123 } 124 } 125 /* 在浮点型数组中找到最小值和最大值 */ 126 void GetMinMaxDouble(double *arr, int n, double &min, double &max) { 127 min = 1.7976931348623158e+308; 128 max = 2.2250738585072014e-308; 129 for(int i=0; i<n; i++) { 130 if(arr[i] > max) max = arr[i]; 131 if(arr[i] < min) min = arr[i]; 132 } 133 } 134 135 136 137 /* 打印灰度图 */ 138 void PrintGrayImage(double *gray_mtx, int w, int h) { 139 int i, j, gray; 140 for(i=0; i<w; i++) { 141 for(j=0; j<h; j++) { 142 gray = *(gray_mtx+h*i+j) * 255.0; 143 putpixel(i, j, EGEGRAY(gray)); 144 } 145 } 146 } 147 /* 获取输入的彩色图像,并转为灰度图 */ 148 void GetImageGray(char *file, double *mx, int w, int h, int mode) { 149 color_t color; 150 int i, j, red, green, blue, gray; 151 PIMAGE pimg = newimage(); 152 getimage(pimg, file, w, h); 153 154 for(i=0; i<w; i++) { 155 for(j=0; j<h; j++) { 156 color = getpixel(i, j, pimg); 157 red = EGEGET_R(color); 158 green = EGEGET_G(color); 159 blue = EGEGET_B(color); 160 // 转化为灰度图 161 gray = (red*38 + green*75 + blue*15) >> 7; 162 *(mx+h*i+j) = gray / 255.0; 163 // printf("(%d,%d) %lf\n", i, j, gray/255.0); 164 } 165 } 166 // 是否打印灰度图像 167 if(mode) { 168 PrintGrayImage(mx, w, h); 169 } 170 delimage(pimg); 171 } 172 /* 打印灰度直方图 */ 173 void ShowHistogram(double *mx, int w, int h) { 174 int i, gray_level[256]={0}, gl; 175 for(i=0; i<w*h; i++) { 176 // 像素点的灰度级计数 177 gl = floor(*(mx+i) * 255.0); 178 gray_level[gl]++; 179 } 180 // 左上角的坐标,坐标轴最大像素高度,间隔像素点 181 int dgx=50, dgy=50, dgh=600, ii=2; 182 int min, max; 183 GetMinMaxInt(gray_level, 256, min, max); 184 int sX, sY, eX, eY; 185 for(i=0; i<256; i++) { 186 sX = dgx + i*(ii+1); 187 sY = dgy + dgh; 188 eX = dgx + i*(ii+1); 189 eY = dgy + dgh-dgh*gray_level[i]/max; 190 line(sX, sY, eX, eY); 191 } 192 }
(1)原图:
(2)处理后:
【推荐】国内首个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 绘制太阳,地球,月球 运作规律