package fr.unistra.pelican.util.vectorial.orders; import java.awt.Point; import java.util.Arrays; import java.util.Comparator; import fr.unistra.pelican.ByteImage; import fr.unistra.pelican.Image; import fr.unistra.pelican.util.vectorial.VectorPixel; /** * This class represents an alpha-lexicographical ordering scheme for double valued arrays and derivatives. * ...very experimental... * * @author E.A. * */ public class AlphaLexicographicalOrdering implements VectorialOrdering,Comparator { private double alpha = 0.0; private Image cimg; public AlphaLexicographicalOrdering(double alpha) { this.alpha = alpha; } /** * Produces a marginally clustered image * such as every cluster is comprised of pixels * within an interval of length alpha... * HIGHLY NOT OPTIMIZED..in fact the only way to write it * worse is to use bubble sort.. * @param img the image to cluster * @param flag whether to start clustering from maximal (true) or minima (false) values * @return clustered image */ public Image preprocess(Image img,boolean flag) { cimg = new ByteImage(img); int bdim = img.getBDim(); int ydim = img.getXDim(); int xdim = img.getYDim(); int size = xdim * ydim; for(int b = 0; b < bdim - 1; b++){ // get the channel.. IndexedPixels[] pixels = new IndexedPixels[size]; // fill the array...so that we can sort it.. for(int x = 0; x < xdim; x++) for(int y = 0; y < ydim; y++) pixels[y * xdim + x] = new IndexedPixels(img.getPixelXYBDouble(x,y,b),x,y); Arrays.sort(pixels); // it's in ascending order... // now the clustering direction depends on the flag // for now..only min..meaning we start from the bottom..the smallest.. // so as the smallest value has a nice group int label = 0; // for every pixel.. for(int i = 0; i < size; i++){ // set the current label.. cimg.setPixelByte(pixels[i].x,pixels[i].y,0,0,b,label); // get all pixels within the alpha interval int j = i+1; if(i < size - 1){ while(j < size && Math.abs(pixels[j].d - pixels[i].d) <= alpha){ cimg.setPixelByte(pixels[j].x,pixels[j].y,0,0,b,label); j++; } } i = j - 1; label++; } System.err.println(label); } cimg.setImage4D(img.getImage4D(bdim - 1,Image.B),bdim - 1,Image.B); return cimg; } private class IndexedPixels implements Comparable { double d; int x; int y; IndexedPixels(double d,int x,int y) { this.d = d; this.x = x; this.y = y; } public int compareTo(Object o){ IndexedPixels d = (IndexedPixels)o; if(this.d < d.d) return -1; else if(this.d > d.d) return 1; else return 0; } } /* * (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; } public Point max(Point[] p) { Point 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]; } /* * (non-Javadoc) * @see fr.unistra.pelican.util.vectorial.orders.VectorialOrdering#order(fr.unistra.pelican.util.vectorial.VectorPixel[]) */ public VectorPixel[] order(VectorPixel[] v) { Arrays.sort(v,this); return v; } /** * 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; Point r1 = null,r2 = null; try{ if(o1.getClass().getName().equals("[D")){ p1 = (double[])o1; p2 = (double[])o2; }else if(o1.getClass().getName().equals("fr.unistra.pelican.util.vectorial.VectorPixel")){ p1 = ((VectorPixel)o1).getVector(); p2 = ((VectorPixel)o2).getVector(); }else if(o1.getClass().getName().equals("java.awt.Point")){ r1 = (Point)o1; r2 = (Point)o2; }else throw new ClassCastException(); }catch(ClassCastException ex){ ex.printStackTrace(); } if(r1 != null && r2 != null){ p1 = cimg.getVectorPixelXYZTDouble(r1.x,r1.y,0,0); p2 = cimg.getVectorPixelXYZTDouble(r2.x,r2.y,0,0); } for(int i = 0; i < p1.length; i++){ if(p1[i] < p2[i]) return -1; else if(p1[i] > p2[i]) 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; } }