package fr.unistra.pelican.algorithms.descriptors.texture; import fr.unistra.pelican.AlgorithmException; import fr.unistra.pelican.Image; import fr.unistra.pelican.Descriptor; import fr.unistra.pelican.util.data.DoubleArrayData; /** * Variogram on 4 directions * * @author Erchan Aptoula * @author Régis Witz (recovery, mask support and framework adaptation, normalization) */ public class Variogram extends Descriptor { public static final int HOR = 0; public static final int LDG = 1; public static final int VER = 2; public static final int RDG = 3; /** Length of the granulometric curve */ public int length = 25; /** First input parameter. */ public Image input; /** Output parameter. */ public DoubleArrayData output; /** Constructor */ public Variogram() { super(); super.inputs = "input"; super.options = "length"; super.outputs = "output"; } public static DoubleArrayData exec( Image input ) { return ( DoubleArrayData ) new Variogram().process( input ); } public static DoubleArrayData exec( Image input, int length ) { return ( DoubleArrayData ) new Variogram().process( input,length ); } /** @see fr.unistra.pelican.Algorithm#launch() */ @SuppressWarnings("unchecked") public void launch() throws AlgorithmException { int size = this.length * 4; Double[] values = new Double[ size ]; for ( int i = 0 ; i < size ; i++ ) values[i] = new Double(0); // every size for ( int i = 1; i <= this.length; i++ ) { // vertical_____________________________ double d = variogramOperator( this.input,i,Variogram.VER ); values[ i-1 ] = d; // left diagonal line________________________ d = variogramOperator( this.input,i,Variogram.LDG ); values[ this.length+i-1 ] = d; // horizontal line___________________________ d = variogramOperator( this.input,i,Variogram.HOR ); values[ 2*this.length+i-1 ] = d; // right diagonal line_______________________ d = variogramOperator( this.input,i,Variogram.RDG ); values[ 3*this.length+i-1 ] = d; } // don't forget to normalize.. values = fr.unistra.pelican.util.Tools.vectorNormalize( values ); this.output = new DoubleArrayData(); this.output.setDescriptor( ( Class ) this.getClass() ); this.output.setValues( values ); } private double variogramOperator( Image img, int l, int direction ) { double res = 0.0; double syc = 0.0; int tmpx = 0; int tmpy = 0; // M00 in alpha kuvvetini al..tum goruntu icin kesisim icn degil.. // zira islemde tum pikselleri modulo biciminde kullaniyoruz... switch ( direction ) { case HOR: for ( int x = 0 ; x < img.getXDim() ; x++ ) { for ( int y = 0 ; y < img.getYDim() ; y++ ) { if ( !img.isPresentXY( x,y ) ) continue; tmpx = x + l; if ( !img.isPresentXY( tmpx,y ) ) continue; double diff = diff( img, x,y, tmpx,y ); res += diff * diff; syc++; } } break; case VER: for ( int x = 0 ; x < img.getXDim() ; x++ ) { for ( int y = 0 ; y < img.getYDim() ; y++ ) { if ( !img.isPresentXY( x,y ) ) continue; tmpy = y + l; if ( !img.isPresentXY( x,tmpy ) ) continue; double diff = diff( img, x,y, x,tmpy ); res += diff * diff; syc++; } } break; case LDG: for ( int x = 0 ; x < img.getXDim() ; x++ ) { for ( int y = 0 ; y < img.getYDim() ; y++ ) { if ( !img.isPresentXY( x,y ) ) continue; tmpx = x - l; tmpy = y + l; if ( !img.isPresentXY( tmpx,tmpy ) ) continue; double diff = diff( img, x,y, tmpx,tmpy ); res += diff * diff; syc++; } } break; case RDG: for ( int x = 0 ; x < img.getXDim() ; x++ ) { for ( int y = 0 ; y < img.getYDim() ; y++ ) { if ( !img.isPresentXY( x,y ) ) continue; tmpx = x + l; tmpy = y + l; if ( !img.isPresentXY( tmpx,tmpy ) ) continue; double diff = diff( img, x,y, tmpx,tmpy ); res += diff * diff; syc++; } } break; default: throw new AlgorithmException( "Unsupported direction" ); } return res / ( 2*syc ); } private double diff( Image img, int x, int y, int x2, int y2 ) { if ( img.getBDim() == 1 ) { double d = img.getPixelXYDouble( x,y ); double d2 = img.getPixelXYDouble( x2,y2 ); double sonuc = ( d-d2 ); return sonuc; } else { double tmp = 0.0; for ( int b = 0; b < img.getBDim(); b++ ) { double diff = img.getPixelXYBDouble( x,y,b ) - img.getPixelXYBDouble( x2,y2,b ); tmp += diff*diff; } return Math.sqrt(tmp); } } /* * (non-Javadoc) * * @see fr.unistra.pelican.Algorithm#help() */ public String help() { return "4 directional normalized covariance.\n" + "fr.unistra.pelican.Image inputImage\n" + "Integer size for each side\n" + "\n" + "double array output curve\n" + "\n"; } }