package fr.unistra.pelican.util.vectorial.orders; import java.util.Arrays; import java.util.Comparator; import fr.unistra.pelican.ByteImage; import fr.unistra.pelican.util.Tools; /** * This class represents a lexicographical ordering scheme for double valued pixels. * The input pixels are considered in the HSL order.. * * The priority of the first component is modified using a subquantization of the first (luminance) dimension * followed by saturation during comparison. Hue is not take into account. * * Specifically created for the comparison of lexicographical orderings. * * * @author E.A. * */ public class QuantizationBasedLexicographicalOrdering implements BinaryVectorialOrdering,Comparator { private double alpha; private double[] transformed; public static int syc = 0; /** * Alpha is to be chosen as if the pixels values were in [0,255] * * @param alpha the rounding parameter */ public QuantizationBasedLexicographicalOrdering(double alpha) { if(alpha > 1.0) this.alpha = alpha; else this.alpha = 1.0; // integer value alpha = Math.round(alpha); transformed = new double[256]; double value = 0; for(int z = 0; z < 256;){ int k = (int)Math.ceil(alpha * sigma(z) + Tools.epsilon); for(int i = z; i < z + k; i++) transformed[i] = value; value++; z += k; } } double sigma(int z) { double x = z / 255.0; if(x <= 0.5) return (1 / (1 + Math.exp(-10 * (x - 0.25))) - 0.0758)/0.84834; else return (1 / (1 + Math.exp(10 * (x - 0.75))) - 0.0758)/0.84834; } /* * (non-Javadoc) * @see fr.unistra.pelican.util.vectorial.orders.VectorialOrdering#max(double[][]) */ public double[] max(double[][] p) { double[] max = p[0]; for(int i = 1; i < p.length; i++){ if(this.compare(max,p[i]) < 0) max = p[i]; } return max; } /* * (non-Javadoc) * @see fr.unistra.pelican.util.vectorial.orders.VectorialOrdering#min(double[][]) */ public double[] min(double[][] p) { double[] min = p[0]; for(int i = 1; i < p.length; i++){ if(this.compare(min,p[i]) > 0) min = p[i]; } return min; } /* * (non-Javadoc) * @see fr.unistra.pelican.util.vectorial.orders.VectorialOrdering#rank(double[][], int) */ public double[] rank(double[][] p,int r) { Arrays.sort(p,this); return p[r]; } /** * Compares the given arguments according to this ordering * * @param o1 first double valued array or vector pixel * @param o2 second double valued array or vector pixel * @return 1,-1 or 0 if o1 is respectively superior, inferior or equal to o2 */ public int compare(Object o1,Object o2) { double[] p1 = null,p2 = null; try{ if(o1.getClass().getName().equals("[D")){ p1 = (double[])o1; p2 = (double[])o2; }else throw new ClassCastException(); }catch(ClassCastException ex){ ex.printStackTrace(); } int tmp1,tmp2; double dtmp1,dtmp2; // L rounded.. if(alpha > 1.0){ dtmp1 = Math.round(ByteImage.doubleToByte * p1[2]); dtmp1 = transformed[(int)dtmp1]; dtmp2 = Math.round(ByteImage.doubleToByte * p2[2]); dtmp2 = transformed[(int)dtmp2]; if(Tools.doubleCompare(dtmp1,dtmp2) < 0) return -1; else if(Tools.doubleCompare(dtmp1,dtmp2) > 0) return 1; }else{ if(Tools.doubleCompare(p1[2],p2[2]) < 0) return -1; else if(Tools.doubleCompare(p1[2],p2[2]) > 0) return 1; } // saturation if(Tools.doubleCompare(p1[1],p2[1]) < 0) return -1; else if(Tools.doubleCompare(p1[1],p2[1]) > 0) return 1; return 0; } /* * (non-Javadoc) * @see fr.unistra.pelican.util.vectorial.orders.VectorialOrdering#max(double[], double[]) */ public double[] max(double[] p,double[] r) { if(compare(p,r) == 1) return p; else return r; } /* * (non-Javadoc) * @see fr.unistra.pelican.util.vectorial.orders.VectorialOrdering#min(double[], double[]) */ public double[] min(double[] p,double[] r) { if(compare(p,r) == 1) return r; else return p; } }