迭代式的图像分割的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)处理后:

 

posted @   HanselHuang  阅读(206)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示