rindarith / javacv

Automatically exported from code.google.com/p/javacv
GNU General Public License v2.0
0 stars 0 forks source link

Flann radiusSearch, knnSearch #129

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
So I'm trying to use flann to speed up matching, but I keep getting random 
indices after performing radiusSearch and knnSearch as well. I'm using the 
newest javacv (yesterday's version)

Here's the simplified version of the code, where I put some made up descriptors 
and it still throw random indices on every run.

public static void main(String[] args) throws IOException,
            InterruptedException {

        int numNeighbors = 10; 
        CvMat imageMat = CvMat.create(10, 2, CV_32F);

        LinearIndexParams kdParams = new LinearIndexParams();
        SearchParams searchParams = new SearchParams(2, 0.05f, true);
        for (int i = 0; i < 10; i++) 
        { 
            for (int j = 0; j < 2; j++) 
            { 
                imageMat.put(i, j, 1- i*1.0/(j+1) ); 
            } 
        } 

        Index flannIndex = new Index(imageMat, kdParams, 1);

        for (int c = 0; c < 10; c++)
        {
            CvMat queryMat = CvMat.create(1, 2, CV_32F);

            CvMat indicesMat = new CvMat(null);
            CvMat distancesMat = new CvMat(null);
            //CvMat distancesMat = CvMat.create(1, numNeighbors, CV_32F);

            for (int i = 0; i < 2; i++) 
            { 
                queryMat.put(0, i, c*1.0/(i+1));
            } 

            //flannIndex.knnSearch(queryMat, indicesMat, distancesMat, numNeighbors, searchParams);
            flannIndex.radiusSearch(queryMat, indicesMat, distancesMat, 0.05f, numNeighbors, searchParams);

            System.out.println("Index " + indicesMat.get(0,0) + " Distance " + distancesMat.get(0,0));  
        } 
    }

Original issue reported on code.google.com by mastera...@gmail.com on 4 Nov 2011 at 8:56

GoogleCodeExporter commented 9 years ago
I do get random numbers the radiusSearch(), but not for knnSearch(). The 
results are the same, always... Can you double check? If it still does not 
work, please provide more info about your platform, etc. thanks

Original comment by samuel.a...@gmail.com on 9 Nov 2011 at 1:55

GoogleCodeExporter commented 9 years ago
yes, indeed knn is not generating random numbers.
Though it works extremely inefficient, instead of working faster it works 
slower.
Perhaps you could take a look:
private Integer[] findPairs(CvSURFPoint[] objectKeypoints,
            FloatBuffer[] objectDescriptors, CvSURFPoint[] imageKeypoints,
            FloatBuffer[] imageDescriptors) {

        boolean[] lessRidiculous = new boolean[imageDescriptors.length];
        Integer[] toReturn = new Integer[objectDescriptors.length*2];
        int numNeighbors = 100; 
        int matchCounter = 0;

        LinearIndexParams kdParams = new LinearIndexParams();
        SearchParams searchParams = new SearchParams(descriptorLength, 0.5f, true);

        // Populate imageMat
        CvMat imageMat = CvMat.create(imageDescriptors.length, descriptorLength, CV_32F);
        for (int i = 0; i < imageDescriptors.length; i++) 
        { 
            for (int j = 0; j < descriptorLength; j++) 
            { 
                imageMat.put(i, j, imageDescriptors[i].get(j) ); 
            } 
        } 

        Index flannIndex = new Index(imageMat, kdParams, 1);

        for (int c = 0; c < objectDescriptors.length; c++)
        {
            CvMat queryMat = CvMat.create(1, descriptorLength, CV_32F);

            CvMat indicesMat = CvMat.create(1, numNeighbors, CV_32S);
            CvMat indicesMat = CvMat.create(1, numNeighbors, CV_32S);
            CvMat distancesMat = CvMat.create(1, numNeighbors, CV_32F);
            // Populate queryMat 
            for (int i = 0; i < descriptorLength; i++) 
            { 
                queryMat.put(0, i, (double) objectDescriptors[c].get(i));
            } 
            flannIndex.knnSearch(queryMat, indicesMat, distancesMat, numNeighbors, searchParams);

            //System.out.println("Index " + indicesMat.get(0,0) + " Distance " + distancesMat.get(0,0) + "Index " + indicesMat.get(0,1) + " Distance " + distancesMat.get(0,1));
            int nearestNeighbor = (int)indicesMat.get(0,0);  
            if (indicesMat !=null && nearestNeighbor >0 && nearestNeighbor < imageDescriptors.length && !lessRidiculous[nearestNeighbor])
            {
                lessRidiculous[nearestNeighbor] = true;
                //System.out.println("M " + c + " " + nearestNeighbor  + " d " + distancesMat.get(0,0));
                toReturn[matchCounter++]  = c;
                toReturn[matchCounter++]  = nearestNeighbor ;
            }
        }
        System.out.println("Matches count " + matchCounter);
        return Arrays.copyOf(toReturn, matchCounter); 
        }

Original comment by mastera...@gmail.com on 10 Nov 2011 at 9:23

GoogleCodeExporter commented 9 years ago
Well, CvMat.create() is a pretty heavy operation. You should move those calls 
outside the loop. 

BTW, check out the NetBeans profiler: http://profiler.netbeans.org/ . With that 
tool we can easily find which calls use most of the CPU time.

Original comment by samuel.a...@gmail.com on 26 Nov 2011 at 7:04