package fr.unistra.pelican.util.data;
import java.util.ArrayList;
import fr.unistra.pelican.util.Keypoint;
import fr.unistra.pelican.util.Offset;
import fr.unistra.pelican.util.data.distances.KeypointArrayEuclideanDistance;
/**
* Represents the "array of keypoints" datatype.
* Useful for SIFT-like descriptors.
*
* @see Keypoint
*
* @author Régis Witz
* @date 27.01.09
*/
public class KeypointArrayData extends Data {
/** The effective data stored in the object. */
ArrayList<Keypoint> values = new ArrayList<Keypoint>();
/** This is a SURF comparison.
* Note that only the laplacian and descriptor[i] values are used for matching.
* x,y,scale and orientation where put in output for exhaustivity and coherence, but
* they can be thrown away of class Keypoint if one day memory cost is a problem.
*
* @param data A <tt>KeypointArrayData</tt> with wich <tt>this</tt> must be compared.
* @return Distance in ]0;1] ( ->0:near,1:far ) between the two keypoints arrays.
*/
@Override
public double distance( Data data ) {
return new KeypointArrayEuclideanDistance().distance( this, data );
}
@Override
public boolean equals( Data data ) {
ArrayList<Keypoint> values2 = ( ( KeypointArrayData ) data).values;
int size = this.values.size();
if ( size != values2.size() ) return false;
Keypoint k1,k2;
for ( int index = 0 ; index < size ; index++ ) {
k1 = this.values.get( index );
k2 = this.values.get( index );
if ( !k1.equals( k2 ) ) return false;
}
return true;
}
@Override
public Object getValues() {
return this.values;
}
@SuppressWarnings("unchecked")
@Override
public void setValues(Object values) {
this.values = ( ArrayList<Keypoint> ) values;
}
@Override
public Data clone() {
DoubleArrayData data = new DoubleArrayData();
data.setDescriptor( this.getDescriptor() );
data.setValues( this.values.clone() );
return data;
}
@Override
public String toString() {
String s = "<DATA="+this.getClass().getName()+">";
if ( this.getDescriptor() != null ) s += "," + this.getDescriptor().getName();
s += "," + this.values.size();
for ( Keypoint point : this.values ) s += "," + point.toString();
s += ",</DATA>";
return s;
}
@SuppressWarnings( "unchecked" )
public static KeypointArrayData getParsedInstance( String [] words, Offset c ) {
KeypointArrayData data = null;
ArrayList<Keypoint> values = new ArrayList<Keypoint>();
int size;
assert words[c.offset].startsWith(
"<DATA="+new KeypointArrayData().getClass().getName() ) :
"Wrong position of offset " + c.offset + ": \"" + words[c.offset] + "\".";
c.offset++; // pass <Data=...>
if ( c.offset < words.length ) {
data = new KeypointArrayData();
try {
Class desc = Class.forName( words[c.offset++] );
data.setDescriptor( desc );
} catch( ClassNotFoundException ex ) { ex.printStackTrace(); }
size = new Integer( words[c.offset++] );
for ( int i = 0 ; i < size ; i++ ) {
Keypoint point = Keypoint.getParsedInstance( words,c );
values.add( point );
}
c.offset++; // pass </DATA>
data.setValues( values );
}
return data;
}
}