| /* @(#) 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) |
| return( -1 ); |
| |
| if ((im->Bands != 1)||(im->BandFmt != IM_BANDFMT_UCHAR)) { |
| im_error( "im_glds_matrix", "%s", _( "Wrong input") ); |
| return(-1); } |
| |
| if ( (xpos + xsize + dx > im->Xsize)|| (ypos + ysize + dy > im->Ysize) ) { |
| im_error( "im_glds_matrix", "%s", _( "wrong args") ); |
| return(-1); } |
| |
| if (im_cp_desc(m, im) == -1) |
| return( -1 ); |
| m->Xsize = 256; |
| m->Ysize = 1; |
| m->BandFmt = IM_BANDFMT_DOUBLE; |
| m->Type = IM_TYPE_B_W; |
| |
| if (im_setupout(m) == -1) |
| return( -1 ); |
| |
| b = (int *)calloc( (unsigned)m->Xsize, sizeof(int) ); |
| l = (double *)calloc( (unsigned)m->Xsize, sizeof(double)); |
| if ( (b == NULL) || (l == NULL) ) { |
| im_error( "im_glds_matrix", "%s", _( "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) |
| 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_error( "im_glds_asm", "%s", _( "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_error( "im_glds_contrast", "%s", _( "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_error( "im_glds_entropy", "%s", _( "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_error( "im_glds_mean", "%s", _( "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); |
| } |