249 lines
6.2 KiB
C
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);
|
|
}
|