Sunday, March 10, 2013

Precision / Recall

With the previous technical solution, I propose to verify the quality of this approach.

This approach is simple, efficient and low cost in term of coding.

I will add some Tree algorithm to enhance the search approach technic.

But What is the result of this approach on a big image database based on 10000 images.
The approach to take some measures is to verify the precision and the recall of each image and to extract some result and comparison.
The precision an recall are clearly explain on wikipedia : http://en.wikipedia.org/wiki/Precision_and_recall
The result in different grey level and colors.


The best result is given by the color 4x4x4 (4 red,blue and green).

The code:
public static void main(String[] args) {
        String veriterTerrainfiles = args[0];
        String fichierDescription = args[2];
        int max = 10000;
        String classe = "";
        boolean indexe = false;
        if (args.length > 4) {
            indexe = true;
            classe = args[4];
            //index = getStringIndex(args[4], args[1]);
        }
        File databaseFile = new File(fichierDescription);

        FileReader datareader = null;
        try {
            datareader = new FileReader(databaseFile);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(PrecisionRappel.class.getName()).log(Level.SEVERE, null, ex);
        }

        String completeFile = loadFile(databaseFile);

        BufferedReader databuffer = new BufferedReader(datareader);
        StringReader reader = new StringReader(completeFile);
        String s;
        Map<String, List<Float>> listFileFloat = new HashMap();
        try {
            while ((s = databuffer.readLine()) != null) {
                String valuesStrList[] = s.split(";");

                List<Float> values = new LinkedList<Float>();
                for (int i = 1; i < valuesStrList.length; i++) {
                    values.add(Float.parseFloat(valuesStrList[i]));
                }

                String filename = valuesStrList[0];
                listFileFloat.put(filename, values);

            }
        } catch (IOException ex) {
            Logger.getLogger(PrecisionRappel.class.getName()).log(Level.SEVERE, null, ex);
        }


        FileReader descreader = null;
        try {
            descreader = new FileReader(args[1]);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(PrecisionRappel.class.getName()).log(Level.SEVERE, null, ex);

        }
        //listefichiers=new File(imagePath).list();
        BufferedReader descbuffer = new BufferedReader(descreader);

        int ii = 0;
        Map<Float, List<Float>> precisionRappelListGlobal = new HashMap();

        try {
            //for(i=0;i<listefichiers.length;i++){
            while ((s = descbuffer.readLine()) != null) {
                if (!indexe || classe.equals(s)) {
                    System.out.println("Work on class :" + s);

                    Set<String> set = getListIndex(veriterTerrainfiles, ii);
                    Map<Float, List<Float>> precisionRappelList = new HashMap();
                    for (String name : set) {
                        float[] image = QBE.chargeImageRequete(databaseFile, name);
                        List<QBE.ResultUnit> res2 = QBE.calculUnitDistanceEtTrie(listFileFloat, image);
                        int nbDansClasse = 0;
                        for (int i = 0; i < res2.size(); i++) {
                            //QBE.Result res = QBE.calculDistanceEtTrie(i, listFileFloat, image);
                            try {
                                reader.reset();
                            } catch (IOException ex) {
                                Logger.getLogger(PrecisionRappel.class.getName()).log(Level.SEVERE, null, ex);
                            }

                            if (set.contains(res2.get(i).resultImage)) {
                                nbDansClasse++;
                            }


                            Float rappel = (float) nbDansClasse / (float) set.size();
                            Float precision = (float) nbDansClasse / ((float) i + 1);
                            if (!precisionRappelList.containsKey(rappel)) {
                                precisionRappelList.put(rappel, new ArrayList());
                            }
                            precisionRappelList.get(rappel).add(precision);

                            //   System.out.println("in:" + i + "," + name + ",precision=" + precision + ",rappel=" + rappel);


                        }
                        Iterator<Float> rappelKeys = precisionRappelList.keySet().iterator();
                        while (rappelKeys.hasNext()) {
                            Float rappel = rappelKeys.next();
                            Float cumul = 0.0f;
                            for (Float prec : precisionRappelList.get(rappel)) {
                                cumul += prec;
                            }
                            if (!precisionRappelListGlobal.containsKey(rappel)) {
                                precisionRappelListGlobal.put(rappel, new ArrayList());
                            }
                            precisionRappelListGlobal.get(rappel).add((cumul / ((float) precisionRappelList.get(rappel).size())));

                        }
                        //System.out.println(name);

                    }



                }
                ii++;
            }
        } catch (IOException ex) {
            Logger.getLogger(PrecisionRappel.class.getName()).log(Level.SEVERE, null, ex);

        }
        System.out.println("Generate result");
        StringBuffer buff = new StringBuffer();
        Iterator<Float> rappelKeys = precisionRappelListGlobal.keySet().iterator();
        while (rappelKeys.hasNext()) {
            Float rappel = rappelKeys.next();
            Float cumul = 0.0f;
            for (Float prec : precisionRappelListGlobal.get(rappel)) {
                cumul += prec;
            }

            buff.append(rappel + " " + (cumul / ((float) precisionRappelListGlobal.get(rappel).size())) + "\n");
        }
        System.out.println("Wriet result");
        try {
            FileWriter indexedDB = new FileWriter(args[3], false);
            indexedDB.write(buff.toString());
            indexedDB.close();
        } catch (IOException ex) {
            Logger.getLogger(QBE.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private static Set<String> getListIndex(String veriterTerrainfiles, int index) {
        FileReader descreader;
        try {
            descreader = new FileReader(veriterTerrainfiles);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(PrecisionRappel.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
        //listefichiers=new File(imagePath).list();
        BufferedReader descbuffer = new BufferedReader(descreader);
        String s;
        int i = 0;
        try {
            //for(i=0;i<listefichiers.length;i++){
            while ((s = descbuffer.readLine()) != null) {
                if (index == i) {
                    Set list = new HashSet();
                    String ret[] = s.split(" ");
                    for (String un : ret) {
                        list.add(un);
                    }
                    return list;
                }
                i++;
            }
        } catch (IOException ex) {
            Logger.getLogger(PrecisionRappel.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
        return null;
    }

    private static int getStringqIndex(String classeName, String descFilename) {
        FileReader descreader;
        try {
            descreader = new FileReader(descFilename);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(PrecisionRappel.class.getName()).log(Level.SEVERE, null, ex);
            return -1;
        }
        //listefichiers=new File(imagePath).list();
        BufferedReader descbuffer = new BufferedReader(descreader);
        String s;
        int i = 0;
        try {
            //for(i=0;i<listefichiers.length;i++){
            while ((s = descbuffer.readLine()) != null) {
                if (classeName.equals(s)) {
                    return i;
                }
                i++;
            }
        } catch (IOException ex) {
            Logger.getLogger(PrecisionRappel.class.getName()).log(Level.SEVERE, null, ex);
            return -1;
        }
        return i;
    }

    public static String loadFile(File f) {
        try {
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
            StringWriter out = null;
            out = new StringWriter();
            int b;
            while ((b = in.read()) != -1) {
                out.write(b);
            }
            out.flush();
            out.close();
            in.close();
            return out.toString();
        } catch (IOException ie) {
            ie.printStackTrace();
        }
        return null;
    }

The new method calculUnitDistanceEtTrie

public static List<ResultUnit> calculUnitDistanceEtTrie( Map<String, List<Float>> databuffer, float[] imageRequete) {

        //Search best results
        //saved result

        List<ResultUnit> result = new ArrayList();
        int maxIndex = 0;
        //Iterator it = savedImgList.keySet().iterator();
        Iterator<String> itFileName = databuffer.keySet().iterator();
     


        while (itFileName.hasNext()) {
            String filename = itFileName.next();
            List<Float> floats = databuffer.get(filename);
            float[] values = new float[floats.size()];
            for (int i = 0; i < values.length; i++) {
                values[i] = floats.get(i);
            }


            float imgvalues[] = values;
            float distance = distanceL2(imageRequete, imgvalues);
            result.add(new ResultUnit(filename, distance));


        }
        Collections.sort(result );
        return result;
    }

with new class result:

public static class ResultUnit implements Comparable<ResultUnit>{

        public String resultImage = "";

        @Override
        public String toString() {
            return "ResultUnit{" + "resultImage=" + resultImage + ", resultDistance=" + resultDistance + '}';
        }
        public float resultDistance = 0.0f;

        private ResultUnit(String filename, float distance) {
            resultImage = filename;
            resultDistance = distance;
        }

        @Override
        public int compareTo(ResultUnit t) {
            float result=(t.resultDistance-resultDistance);
            if (result>0) return -1;
            if (result<0) return 1;
            return 0;
           
        }
       
    }