|
Packit |
78deda |
/* pgmminkowsky.c - read a portable graymap and calculate the Minkowski
|
|
Packit |
78deda |
** Integrals as a function of the threshold.
|
|
Packit |
78deda |
**
|
|
Packit |
78deda |
** Copyright (C) 2000 by Luuk van Dijk/Mind over Matter
|
|
Packit |
78deda |
**
|
|
Packit |
78deda |
** Based on pgmhist.c,
|
|
Packit |
78deda |
** Copyright (C) 1989 by Jef Poskanzer.
|
|
Packit |
78deda |
**
|
|
Packit |
78deda |
** Permission to use, copy, modify, and distribute this software and its
|
|
Packit |
78deda |
** documentation for any purpose and without fee is hereby granted, provided
|
|
Packit |
78deda |
** that the above copyright notice appear in all copies and that both that
|
|
Packit |
78deda |
** copyright notice and this permission notice appear in supporting
|
|
Packit |
78deda |
** documentation. This software is provided "as is" without express or
|
|
Packit |
78deda |
** implied warranty.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#include "pgm.h"
|
|
Packit |
78deda |
#include "mallocvar.h"
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#define MAX2(a,b) ( ( (a)>(b) ) ? (a) : (b) )
|
|
Packit |
78deda |
#define MAX4(a,b,c,d) MAX2( MAX2((a),(b)), MAX2((c),(d)) )
|
|
Packit |
78deda |
|
|
Packit |
78deda |
int main( int argc, char** argv ){
|
|
Packit |
78deda |
|
|
Packit |
78deda |
FILE *ifp;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
gray maxval;
|
|
Packit |
78deda |
int cols, rows, format;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
gray* prevrow;
|
|
Packit |
78deda |
gray* thisrow;
|
|
Packit |
78deda |
gray* tmprow;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
int* countTile;
|
|
Packit |
78deda |
int* countEdgeX;
|
|
Packit |
78deda |
int* countEdgeY;
|
|
Packit |
78deda |
int* countVertex;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
int i, col, row;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
int maxtiles, maxedgex, maxedgey, maxvertex;
|
|
Packit |
78deda |
int area, perimeter, eulerchi;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
double l2inv, linv;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* parse arg and initialize
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
pgm_init( &argc, argv );
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if ( argc > 2 ) pm_usage( "[pgmfile]" );
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if ( argc == 2 )
|
|
Packit |
78deda |
ifp = pm_openr( argv[1] );
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
ifp = stdin;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/*
|
|
Packit |
78deda |
* initialize
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
pgm_readpgminit( ifp, &cols, &rows, &maxval, &format );
|
|
Packit |
78deda |
|
|
Packit |
78deda |
prevrow = pgm_allocrow( cols );
|
|
Packit |
78deda |
thisrow = pgm_allocrow( cols );
|
|
Packit |
78deda |
|
|
Packit |
78deda |
MALLOCARRAY(countTile , maxval + 1 );
|
|
Packit |
78deda |
MALLOCARRAY(countEdgeX , maxval + 1 );
|
|
Packit |
78deda |
MALLOCARRAY(countEdgeY , maxval + 1 );
|
|
Packit |
78deda |
MALLOCARRAY(countVertex , maxval + 1 );
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (countTile == NULL || countEdgeX == NULL || countEdgeY == NULL ||
|
|
Packit |
78deda |
countVertex == NULL)
|
|
Packit |
78deda |
pm_error( "out of memory" );
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for ( i = 0; i <= maxval; i++ ) countTile[i] = 0;
|
|
Packit |
78deda |
for ( i = 0; i <= maxval; i++ ) countEdgeX[i] = 0;
|
|
Packit |
78deda |
for ( i = 0; i <= maxval; i++ ) countEdgeY[i] = 0;
|
|
Packit |
78deda |
for ( i = 0; i <= maxval; i++ ) countVertex[i] = 0;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* first row */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
pgm_readpgmrow( ifp, thisrow, cols, maxval, format );
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* tiles */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for ( col = 0; col < cols; ++col ) ++countTile[thisrow[col]];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* y-edges */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for ( col = 0; col < cols; ++col ) ++countEdgeY[thisrow[col]];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* x-edges */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
++countEdgeX[thisrow[0]];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for ( col = 0; col < cols-1; ++col )
|
|
Packit |
78deda |
++countEdgeX[ MAX2(thisrow[col], thisrow[col+1]) ];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
++countEdgeX[thisrow[cols-1]];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* shortcut: for the first row, countVertex == countEdgeX */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
++countVertex[thisrow[0]];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for ( col = 0; col < cols-1; ++col )
|
|
Packit |
78deda |
++countVertex[ MAX2(thisrow[col], thisrow[col+1]) ];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
++countVertex[thisrow[cols-1]];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for ( row = 1; row < rows; ++row ){
|
|
Packit |
78deda |
|
|
Packit |
78deda |
tmprow = prevrow;
|
|
Packit |
78deda |
prevrow = thisrow;
|
|
Packit |
78deda |
thisrow = tmprow;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
pgm_readpgmrow( ifp, thisrow, cols, maxval, format );
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* tiles */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for ( col = 0; col < cols; ++col ) ++countTile[thisrow[col]];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* y-edges */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for ( col = 0; col < cols; ++col )
|
|
Packit |
78deda |
++countEdgeY[ MAX2(thisrow[col], prevrow[col]) ];
|
|
Packit |
78deda |
/* x-edges */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
++countEdgeX[thisrow[0]];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for ( col = 0; col < cols-1; ++col )
|
|
Packit |
78deda |
++countEdgeX[ MAX2(thisrow[col], thisrow[col+1]) ];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
++countEdgeX[thisrow[cols-1]];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* vertices */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
++countVertex[ MAX2(thisrow[0],prevrow[0]) ];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for ( col = 0; col < cols-1; ++col )
|
|
Packit |
78deda |
++countVertex[
|
|
Packit |
78deda |
MAX4(thisrow[col], thisrow[col+1], prevrow[col], prevrow[col+1])
|
|
Packit |
78deda |
];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
++countVertex[ MAX2(thisrow[cols-1],prevrow[cols-1]) ];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
} /* for row */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* now thisrow contains the top row*/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* tiles and x-edges have been counted, now upper
|
|
Packit |
78deda |
y-edges and top vertices remain */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* y-edges */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for ( col = 0; col < cols; ++col ) ++countEdgeY[ thisrow[col] ];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* vertices */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
++countVertex[thisrow[0]];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for ( col = 0; col < cols-1; ++col )
|
|
Packit |
78deda |
++countVertex[ MAX2(thisrow[col],thisrow[col+1]) ];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
++countVertex[ thisrow[cols-1] ];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* cleanup */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
maxtiles = rows * cols;
|
|
Packit |
78deda |
maxedgex = rows * (cols+1);
|
|
Packit |
78deda |
maxedgey = (rows+1) * cols;
|
|
Packit |
78deda |
maxvertex= (rows+1) * (cols+1);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
l2inv = 1.0/maxtiles;
|
|
Packit |
78deda |
linv = 0.5/(rows+cols);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* And print it. */
|
|
Packit |
78deda |
printf( "#threshold\t tiles\tx-edges\ty-edges\tvertices\n" );
|
|
Packit |
78deda |
printf( "#---------\t -----\t-------\t-------\t--------\n" );
|
|
Packit |
78deda |
for ( i = 0; i <= maxval; i++ ){
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if( !(countTile[i] || countEdgeX[i] || countEdgeY[i] || countVertex[i] ) )
|
|
Packit |
78deda |
continue; /* skip empty slots */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
area = maxtiles;
|
|
Packit |
78deda |
perimeter = 2*maxedgex + 2*maxedgey - 4*maxtiles;
|
|
Packit |
78deda |
eulerchi = maxtiles - maxedgex - maxedgey + maxvertex;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
printf( "%f\t%6d\t%7d\t%7d\t%8d\t%g\t%g\t%6d\n", (float) i/(1.0*maxval),
|
|
Packit |
78deda |
maxtiles, maxedgex, maxedgey, maxvertex,
|
|
Packit |
78deda |
area*l2inv, perimeter*linv, eulerchi
|
|
Packit |
78deda |
);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
maxtiles -= countTile[i];
|
|
Packit |
78deda |
maxedgex -= countEdgeX[i];
|
|
Packit |
78deda |
maxedgey -= countEdgeY[i];
|
|
Packit |
78deda |
maxvertex-= countVertex[i];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* i, countTile[i], countEdgeX[i], countEdgeY[i], countVertex[i] */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* these should be zero: */
|
|
Packit |
78deda |
printf( "# check:\t%6d\t%7d\t%7d\t%8d\n",
|
|
Packit |
78deda |
maxtiles, maxedgex, maxedgey, maxvertex );
|
|
Packit |
78deda |
|
|
Packit |
78deda |
pm_close( ifp );
|
|
Packit |
78deda |
|
|
Packit |
78deda |
exit( 0 );
|
|
Packit |
78deda |
|
|
Packit |
78deda |
} /*main*/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|