📄 chamfer_sdt1.c
字号:
/* * computes salience distance transform * distance weighted by: * edge magnitude * * (serial) chamfer algorithm used, either 3-4 or 5-7-11 * * Paul Rosin * August 1994 */#include <stdio.h>#include <math.h>#ifndef FALSE# define FALSE 0# define TRUE (!FALSE)#endif#define K 1#define MAX_SIZE 1024#include "pgmio.h"#define CHAMFER34 0#define CHAMFER5711 1#define ALGORITHM CHAMFER34#if ALGORITHM == CHAMFER34# define MASK_SIZE 5 int x_offset[MASK_SIZE] = { -1, 0, 1, -1, 0 }; int y_offset[MASK_SIZE] = { -1, -1, -1, 0, 0 }; int i_offset[MASK_SIZE] = { 4, 3, 4, 3, 0 };#elif ALGORITHM == CHAMFER5711# define MASK_SIZE 9 int x_offset[MASK_SIZE] = { -1, 1, -2, -1, 0, 1, 2, -1, 0 }; int y_offset[MASK_SIZE] = { -2, -2, -1, -1, -1, -1, -1, 0, 0 }; int i_offset[MASK_SIZE] = { 11, 11, 11, 7, 5, 7, 11, 5, 0 };#endifunsigned char tmp[MAX_SIZE][MAX_SIZE];int image_dist[MAX_SIZE][MAX_SIZE];unsigned char image_mag[MAX_SIZE][MAX_SIZE];double image_measure[MAX_SIZE][MAX_SIZE];int height,width,depth;int max_iter = 10; /* usually terminates after 4 or 5 iterations anyway */main(argc,argv)int argc;char *argv[];{ int i,j,x,y; int change; int d[MASK_SIZE],m[MASK_SIZE]; double measure,min_measure,prev_measure; char *binary_file,*outfile,*edge_file; double min_dist,min_mag,max_val; int xn,yn; binary_file = outfile = edge_file = NULL; /* parse command line */ for(i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch(argv[i][1]) { case 'b': i++; binary_file = argv[i]; break; case 'e': i++; edge_file = argv[i]; break; case 'o': i++; outfile = argv[i]; break; case 'n': i++; max_iter = atoi(argv[i]); printf("number of iterations: %d\n",max_iter); break; default: printf("unknown option %s\n",argv[i]); options(argv[0]); } } else { printf("unknown option %s\n",argv[i]); options(argv[0]); } } if (outfile == NULL || edge_file == NULL) options(argv[0]);#if (ALGORITHM == CHAMFER34) printf("performing chamfer3-4\n");#elif (ALGORITHM == CHAMFER5711) printf("performing chamfer5-7-11\n");#endif read_pgm(image_mag,edge_file,&width,&height,&depth); if (binary_file != NULL) { read_pgm(tmp,binary_file,&width,&height,&depth); /* copy into integer array */ for (y = 0; y < height; y++) for (x = 0; x < width; x++) image_dist[x][y] = tmp[x][y]; } else { /* threshold magnitude image */ for (y = 0; y < height; y++) for (x = 0; x < width; x++) if ((unsigned int)image_mag[x][y] > 0) image_dist[x][y] = 0; else image_dist[x][y] = 255; } /* propagate distance etc */ j = 0; do { j++; printf("iteration %d\n",j); change = FALSE; /* forward pass */ for (y = 1; y < height-1; y++) { for (x = 1; x < width-1; x++) { prev_measure = (double) (image_dist[x][y]+K) / (double) ((unsigned int)image_mag[x][y]+K); for (i = 0; i < MASK_SIZE; i++) { xn = x + x_offset[i]; yn = y + y_offset[i]; d[i] = image_dist[xn][yn] + i_offset[i]; m[i] = (unsigned int)image_mag[xn][yn]; } min_dist = d[0]; min_mag = m[0]; min_measure = (double) (d[0]+K) / (double) (m[0]+K); for (i = 1; i < MASK_SIZE; i++) { measure = (double) (d[i]+K) / (double) (m[i]+K); if (measure < min_measure) { min_measure = measure; min_dist = d[i]; min_mag = m[i]; } } image_dist[x][y] = min_dist; image_mag[x][y] = min_mag; if (prev_measure != min_measure) change = TRUE; } } /* backward pass */ for (y = height-2; y >= 1; y--) { for (x = width-2; x >= 1; x--) { prev_measure = (double) (image_dist[x][y]+K) / (double) ((unsigned int)image_mag[x][y]+K); for (i = 0; i < MASK_SIZE; i++) { xn = x - x_offset[i]; yn = y - y_offset[i]; d[i] = image_dist[xn][yn] + i_offset[i]; m[i] = (unsigned int)image_mag[xn][yn]; } min_dist = d[0]; min_mag = m[0]; min_measure = (double) (d[0]+K) / (double) (m[0]+K); for (i = 1; i < MASK_SIZE; i++) { measure = (double) (d[i]+K) / (double) (m[i]+K); if (measure < min_measure) { min_measure = measure; min_dist = d[i]; min_mag = m[i]; } } image_dist[x][y] = min_dist; image_mag[x][y] = min_mag; if (prev_measure != min_measure) change = TRUE; } } } while (change && j < max_iter); printf("final iteration: %d\n",j); /* calculate measure values */ for (y = 1; y < height-1; y++) { for (x = 1; x < width-1; x++) { image_measure[x][y] = (double) (image_dist[x][y]+K) / (double) ((unsigned int)image_mag[x][y]+K); } } /* rescale */ max_val = image_measure[1][1]; for (y = 1; y < height-1; y++) for (x = 1; x < width-1; x++) if (image_measure[x][y] > max_val) max_val = image_measure[x][y]; for (y = 1; y < height-1; y++) for (x = 1; x < width-1; x++) tmp[x][y] = (unsigned char)(image_measure[x][y] * 255 / max_val); /* reset borders */ for (y = 0; y < height; y++) tmp[0][y] = tmp[width-1][y] = 255; for (x = 0; x < width; x++) tmp[x][0] = tmp[x][height-1] = 255; write_pgm(tmp,outfile,width,height);}options(progname)char *progname;{ printf("usage: %s [options]\n",progname); printf(" -b file binary edge map (optional)\n"); printf(" -e file edge magnitude map\n"); printf(" -o file output distance map\n"); printf(" -n int maximum number of iterations (default: %d)\n",max_iter); exit(-1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -