libvips/libsrc/other/glds_funcs.c
2007-08-29 16:23:50 +00:00

249 lines
6.2 KiB
C

/* @(#) Calculates the spatial grey level differnce
* @(#) matrix of an image and some of its
* @(#) features. The 256x1 difference matrix of im is held by m
* @(#) There should be enough margin around the box so the (dx,dy) can
* @(#) access neighbouring pixels outside the box
* @(#)
* @(#) Usage:
* @(#) int im_glds_matrix(im, m, xpos, ypos, xsize, ysize, dx, dy)
* @(#) IMAGE *im, *m;
* @(#) int xpos, ypos, xsize, ysize; location of the box within im
* @(#) int dx, dy; displacements
* @(#)
* @(#) int im_glds_asm(m, asmoment)
* @(#) IMAGE *m;
* @(#) double *asmoment;
* @(#)
* @(#) int im_glds_contrast(m, contrast)
* @(#) IMAGE *m;
* @(#) double *contrast;
* @(#)
* @(#) int im_glds_entropy(m, entropy)
* @(#) IMAGE *m;
* @(#) double *entropy;
* @(#)
* @(#) int im_glds_mean(m, mean)
* @(#) IMAGE *m;
* @(#) double *mean;
* @(#)
* @(#) All functions return 0 on success and -1 on error
*
* Copyright: N. Dessipris, 1991
* Written on: 2/12/1991
* Modified on:
* 22/7/93 JC
* - im_incheck() added
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <vips/vips.h>
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
/* Keep the greylevel difference matrix as a 256x1 double image */
int
im_glds_matrix( IMAGE *im, IMAGE *m,
int xpos, int ypos, int xsize, int ysize, int dx, int dy )
{
PEL *in, *cpin;
int *b, *pb;
double *l, *pl;
int x, y;
int ofs;
int tmp;
int norm;
if (im_iocheck(im, m) == -1)
{ im_errormsg("im_glds_matrix: im_iocheck failed"); return(-1);}
if ((im->Bands != 1)||(im->Bbits != IM_BBITS_BYTE)||(im->BandFmt != IM_BANDFMT_UCHAR))
{ im_errormsg("im_glds_matrix: Wrong input"); return(-1); }
if ( (xpos + xsize + dx > im->Xsize)|| (ypos + ysize + dy > im->Ysize) )
{ im_errormsg("im_glds_matrix: wrong args"); return(-1); }
if (im_cp_desc(m, im) == -1)
{ im_errormsg("im_glds_matrix: im_cp_desc failed"); return(-1);}
m->Xsize = 256; m->Ysize = 1;
m->Bbits = IM_BBITS_DOUBLE; m->BandFmt = IM_BANDFMT_DOUBLE;
m->Type = IM_TYPE_B_W;
if (im_setupout(m) == -1)
{ im_errormsg("im_glds_matrix: im_setupout failed");return(-1);}
b = (int *)calloc( (unsigned)m->Xsize, sizeof(int) );
l = (double *)calloc( (unsigned)m->Xsize, sizeof(double));
if ( (b == NULL) || (l == NULL) )
{ im_errormsg("im_glds_matrix: calloc failed"); return(-1); }
in = (PEL*)im->data;
in += ( ypos * im->Xsize + xpos );
ofs = dy * im->Xsize + dx;
for ( y=0; y<ysize; y++ )
{
cpin = in;
in += im->Xsize;
for ( x=0; x<xsize; x++ )
{
tmp = abs((int)*cpin - (int)(*(cpin+ofs)));
pb = (b + tmp);
(*pb)++;
cpin++;
}
}
norm = xsize * ysize;
pb = b;
pl = l;
for (x=0; x<m->Xsize; x++)
*pl++ = ((double)(*pb++))/(double)norm;
if (im_writeline( 0, m, (PEL *) l ) == -1)
{im_errormsg("im_glds_matrix: im_writeline failed");return(-1);}
free((char*)b); free((char*)l);
return(0);
}
/* @(#) Calculates the asmoment of the sglds matrix held by m
*/
int
im_glds_asm( IMAGE *m, double *asmoment )
{
double temp, tmpasm, *in;
int i;
if( im_incheck( m ) )
return( -1 );
if (m->Xsize != 256 || m->Ysize != 1 ||
m->Bands != 1 || m->BandFmt != IM_BANDFMT_DOUBLE)
{im_errormsg("im_glds_asm: unable to accept input");return(-1);}
tmpasm = 0.0;
in = (double*)m->data;
for(i=0; i<m->Xsize; i++)
{
temp = *in++;
tmpasm += (temp*temp);
}
*asmoment = tmpasm;
return(0);
}
/* @(#) Calculates the contrast of the coocurence matrix passed in buffer
*/
int
im_glds_contrast( IMAGE *m, double *contrast )
{
double tmpcon, *in;
int i;
if( im_incheck( m ) )
return( -1 );
if (m->Xsize != 256 || m->Ysize != 1 ||
m->Bands != 1 || m->BandFmt != IM_BANDFMT_DOUBLE)
{ im_errormsg("im_glds_contrast: wrong input"); return(-1); }
tmpcon = 0.0;
in = (double*)m->data;
for(i=0; i<m->Xsize; i++)
{
tmpcon += ( ((double)i)*((double)i)*(*in) );
in++;
}
*contrast = tmpcon;
return(0);
}
/* @(#) Calculates the entropy of the glds vector passed in buffer
* @(#) Function returns the entropy based on log base 2.
*/
int
im_glds_entropy( IMAGE *m, double *entropy )
{
double tmpent, dtemp, *in;
int i;
if( im_incheck( m ) )
return( -1 );
if (m->Xsize != 256 || m->Ysize != 1 ||
m->Bands != 1 || m->BandFmt != IM_BANDFMT_DOUBLE)
{ im_errormsg("im_glds_entropy: wrong input"); return(-1); }
tmpent = 0.0;
in = (double*)m->data;
for(i=0; i<m->Xsize; i++)
{
if(*in != 0)
{
dtemp = *in;
tmpent += (dtemp*log10(dtemp));
}
in++;
}
*entropy = ((-1)*tmpent/log10(2.0));
return(0);
}
/* @(#) Calculates the mean of the sglds matrix passed in m
*/
int
im_glds_mean( IMAGE *m, double *mean )
{
double tmpmean, *in;
int i;
if( im_incheck( m ) )
return( -1 );
if (m->Xsize != 256 || m->Ysize != 1 ||
m->Bands != 1 || m->BandFmt != IM_BANDFMT_DOUBLE)
{ im_errormsg("im_glds_mean: wrong input"); return(-1); }
tmpmean = 0.0;
in = (double*)m->data;
for(i=0; i<m->Xsize; i++)
{
tmpmean += ( ((double)i)*(*in) );
in++;
}
tmpmean = tmpmean/((double)m->Xsize);
*mean = tmpmean;
return(0);
}