package fr.unistra.pelican.algorithms.statistics;
import fr.unistra.pelican.*;
import fr.unistra.pelican.util.Pixel;
/**
* Computes the co-occurrence matrix of an image.
* Currently only work for images whose pixels are only positive integers.
*
* @author Régis Witz
* @date 07.04.2009
*/
public class Cooccurence extends Algorithm {
////////////
// FIELDS //
////////////
/** Input image. */
public ByteImage input;
/** Deviation vector. */
public Pixel t = new Pixel();
/** Side of {@link #output} matrix.
* <br>
* If not given by the user, it will be computed automatically,
* but this will cost additionnal time ( <i>ie.</i> one pass ).
* <br>
* No verification is done on an user-given value.
*/
public int side = -1;
/** Should {@link #output} be normalized ? */
public boolean normalize = true;
/** Output co-occurence matrix. It's a {@link #side}x{@link #side} square matrix. */
public IntegerImage output;
/////////////
// PROFILE //
/////////////
/** Algorithm specifications. */
public Cooccurence() {
super();
super.inputs = "input";
super.options = "t,normalize,side";
super.outputs = "output";
}
///////////////////
// LAUNCH METHOD //
///////////////////
@Override
/** @see Algorithm */
public void launch() throws AlgorithmException {
// // {@link #input} must be an instance of one of these class. for example,
// // there is no sense to compute a co-occurence matrix on a DoubleImage ...
// if ( !( this.input instanceof BooleanImage
// || this.input instanceof ByteImage
// || this.input instanceof IntegerImage ) )
// throw new PelicanException( "Cannot compute co-occurence matrix " +
// "on a " + this.input.getClass().getName() + " image." );
//
if ( side < 0 ) {
// if ( this.input instanceof BooleanImage ) this.side = 2;
if ( this.input instanceof ByteImage ) this.side = 256;
// if ( this.input instanceof IntegerImage ) this.side = Integer.MAX_VALUE-Integer.MIN_VALUE+1;
}
// create the co-occurence matrix
this.output = new IntegerImage( this.side,this.side,1,1,1 );
for ( Pixel p : this.output ) this.output.setPixelInt( p,0 );
// compute the co-occurence matrix
int p1,p2, sum = 0;
Pixel pt = null;
for ( Pixel p : this.input ) {
pt = new Pixel( p.x + this.t.x,
p.y + this.t.y,
p.z + this.t.z,
p.t + this.t.t,
p.b + this.t.b );
try { p2 = this.input.getPixelByte( pt ); }
catch ( ArrayIndexOutOfBoundsException ex ) { continue; }
p1 = this.input.getPixelByte( p );
// if ( p1 != 0 ) System.out.println( p1 );
// if ( p2 != 0 ) System.out.println( p2 );
this.output.setPixelXYInt( p1,p2, this.output.getPixelXYInt( p1,p2 )+1 );
sum++;
}
pt = null;
System.out.println( "/cooc: " + sum / 4. );
// normalize the co-occurence matrix
if ( sum > 0 )
for ( Pixel p : this.output )
this.output.setPixelInt( p, this.output.getPixelInt( p ) / sum );
} // endfunc
//////////////////
// EXEC METHODS //
//////////////////
public static IntegerImage exec( Image input ) {
return ( IntegerImage ) new Cooccurence().process( input );
}
public static IntegerImage exec( Image input, boolean normalize ) {
return ( IntegerImage ) new Cooccurence().process( input,normalize );
}
public static IntegerImage exec( Image input, int size ) {
return ( IntegerImage ) new Cooccurence().process( input,size );
}
public static IntegerImage exec( Image input, boolean normalize, int size ) {
return ( IntegerImage ) new Cooccurence().process( input,normalize,size );
}
public static IntegerImage exec( Image input, Pixel t ) {
return ( IntegerImage ) new Cooccurence().process( input,t );
}
public static IntegerImage exec( Image input, Pixel t, boolean normalize ) {
return ( IntegerImage ) new Cooccurence().process( input,t,normalize );
}
public static IntegerImage exec( Image input, Pixel t, int size ) {
return ( IntegerImage ) new Cooccurence().process( input,t,size );
}
public static IntegerImage exec( Image input, Pixel t, boolean normalize, int size ) {
return ( IntegerImage ) new Cooccurence().process( input,t,normalize,size );
}
}