⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chamfer_sdt1.c

📁 The salience distance transform incorporates edge strength information into the distance transform.
💻 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 + -