keke77 / javacv

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

Why objectfinder perform different result with same image? #287

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
My program(objectfinder) is developed in SOAP web server of eclipse.
When the server is started, client can send image to server using iphone.
But when I use the same iphone and send the same image to objectfinder to 
process , the result is different(e.g. the double[] returned by find())
I am not sure but I guess there is some memory not clear after the find() is 
finished. 
I use 3 objects to detect 1 target when find() process once.
I assured that the image sent from client is completely the same with the one 
web server received.(e.g. I compared their byte array and they are same)

RecognizeForm.java  : for javacv
WeatherService.java : for web service

What is the expected output? What do you see instead?
I expect that the program will generate the same result every time I use the 
same image as input(e.g. lena.jpg).
But now the result is different even if the same image is inputted.

What version of the product are you using? On what operating system?
I forgot the version of Javacv I use but I download it since 4, Nov 2012 and 
its the latest version at that time. 
Window 7 
Eclipse Indigo Service Release 2

Please provide any additional information below.

2 weeks ago ,I tried to build another program using javacv objectfinder without 
web server. It works perfectly when I just process one image with run the 
program once. 

However ,when I modified the program as it can process multiple images(e.g. 10) 
at the same time(use "for loop" to loop the find() function and process one 
image per find())
the same problem is ocurred.

Original issue reported on code.google.com by rjisgr...@msn.com on 4 Mar 2013 at 9:55

Attachments:

GoogleCodeExporter commented 9 years ago
Looks like there is a change that is caused by this bug:
    http://code.opencv.org/issues/2219
Please let me know if this is related. You could try an older version of OpenCV 
to verify that for example.

Original comment by samuel.a...@gmail.com on 4 Mar 2013 at 10:07

GoogleCodeExporter commented 9 years ago
Additional information of previous program :
OpenCV 2.4.0 
JavaCV 0.3

I have tried OpenCV 2.4.0 and JavaCV 0.2 
also OpenCV 2.4.4 and JavaCV 0.4 
unfortunately the problem is still here.

There is the main part of my testing program which I made a little change from 
ObjectFinder.

public static RecognitionResult Detection(){
...
javaCV.Settings settings_text = new javaCV.Settings();
settings_text.objectImage = object_text;
settings_text.useFLANN = true;
settings_text.ransacReprojThreshold = 5;
javaCV finder_text = new javaCV(settings_text);
...
double[] dst_corners_text = finder_text.find(image);

if (dst_corners_text != null) {
  for (int i = 0; i < 4; i++) {
    int j = (i + 1) % 4;
    int x1 = (int) Math.round(dst_corners_text[2 * i]);
    int y1 = (int) Math.round(dst_corners_text[2 * i + 1]);
    int x2 = (int) Math.round(dst_corners_text[2 * j]);
    int y2 = (int) Math.round(dst_corners_text[2 * j + 1]);
    System.out.println("x1:"+x1+" y1:"+y1);
...
  }
...
}

public static void main(String[] args) throws Exception {
    for (int a = 0 ; a < 2 ; a++){
        Detection();
    }
}

When a == 0 ,  output = 
x1:720 y1:86
x1:726 y1:922
x1:137 y1:924
x1:163 y1:56

When a ==1 , output 
x1:720 y1:86
x1:726 y1:919
x1:136 y1:925
x1:162 y1:55

The results are different. 

Sorry that I tried to use (OpenCV 2.3.1 and JavaCV 0.1) and (OpenCV 2.3.1 and 
JavaCV 0.2) as your suggestion but some errors are occurred in both cases.

Exception in thread "main" java.lang.UnsatisfiedLinkError: 
C:\DOCUME~1\JACKY_~1\LOCALS~1\Temp\javacpp6981140360017\jniopencv_core.dll 
(JVMPORT015E 无法解析共享库引用 - 可能缺少必备共享库)
    at java.lang.ClassLoader.loadLibraryWithPath(ClassLoader.java:1011)
    at java.lang.System.load(System.java:457)
    at com.googlecode.javacpp.Loader.loadLibrary(Loader.java:418)
    at com.googlecode.javacpp.Loader.load(Loader.java:368)
    at com.googlecode.javacpp.Loader.load(Loader.java:315)
    at com.googlecode.javacv.cpp.opencv_core.<clinit>(opencv_core.java:131)
    at java.lang.J9VMInternals.initializeImpl(Native Method)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
    at java.lang.Class.forNameImpl(Native Method)
    at java.lang.Class.forName(Class.java:172)
    at com.googlecode.javacpp.Loader.load(Loader.java:334)
    at com.googlecode.javacv.cpp.opencv_imgproc.<clinit>(opencv_imgproc.java:96)
    at java.lang.J9VMInternals.initializeImpl(Native Method)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
    at java.lang.Class.forNameImpl(Native Method)
    at java.lang.Class.forName(Class.java:172)
    at com.googlecode.javacpp.Loader.load(Loader.java:334)
    at com.googlecode.javacv.cpp.opencv_highgui.<clinit>(opencv_highgui.java:91)
    at java.lang.J9VMInternals.initializeImpl(Native Method)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
    at javaCV.Detection(javaCV.java:459) 
    at javaCV.Detection(javaCV.java:417)
    at javaCV.main(javaCV.java:999)

where javaCV.java:459 refer to 
IplImage object_text = cvLoadImage(objectFilename_text,CV_LOAD_IMAGE_GRAYSCALE);

I guess it is due to some mistakes in environment variable setting.
I use the following as User variable setting.

CLASSPATH
C:\opencv\build\x86\vc10\lib;C:\opencv\build\x86\vc10\staticlib;
PATH
C:\opencv\build\common\tbb\ia32\vc10;C:\opencv\build\common\tbb\ia32\vc10\irml_c
;
C:\opencv\build\common\tbb\ia32\vc10\irml;C:\opencv\build\x86\vc10\bin;

Please let me know if there is any obvious mistakes.
Thank you.

Original comment by rjisgr...@msn.com on 5 Mar 2013 at 10:54

GoogleCodeExporter commented 9 years ago
Does the problem occur with the /original/ ObjectFinder.java as well? Or only 
with your /modified/ version?

Original comment by samuel.a...@gmail.com on 5 Mar 2013 at 10:59

GoogleCodeExporter commented 9 years ago
If I simply add a for loop in the main() of the /original/ ObjectFinder.java 
and use my own object and scene image, the problem is occurred.

If box.png and box_in_scene.png are used instead, the problem is still here.

Original comment by rjisgr...@msn.com on 6 Mar 2013 at 2:11

GoogleCodeExporter commented 9 years ago
Here is the main() of my testing program.
1.For loop is added.
2.String objectFilename and sceneFilename are hard-coded instead of args[] 
parameter.
3.System.out.println("x1 :" + x1 + " y1 :" + y1) is added to show the 
coordinate of 4 corners of generated frame.

public static void main(String[] args) throws Exception {
        // Logger.getLogger("com.googlecode.javacv").setLevel(Level.OFF);

        for (int a = 0; a < 3; a++) {

            String objectFilename = "image/box.png";
            String sceneFilename = "image/box_in_scene.png";

            IplImage object = cvLoadImage(objectFilename,
                    CV_LOAD_IMAGE_GRAYSCALE);
            IplImage image = cvLoadImage(sceneFilename, CV_LOAD_IMAGE_GRAYSCALE);
            if (object == null || image == null) {
                System.err.println("Can not load " + objectFilename
                        + " and/or " + sceneFilename);
                System.exit(-1);
            }

            IplImage objectColor = IplImage.create(object.width(),object.height(), 8, 3);
            cvCvtColor(object, objectColor, CV_GRAY2BGR);
            IplImage correspond = IplImage.create(image.width(),object.height() + image.height(), 8, 1);
            cvSetImageROI(correspond,cvRect(0, 0, object.width(), object.height()));

            cvCopy(object, correspond);
            cvSetImageROI(correspond,cvRect(0, object.height(), correspond.width(), correspond.height()));
            cvCopy(image, correspond);
            cvResetImageROI(correspond);
            ObjectFinder.Settings settings = new ObjectFinder.Settings();
            settings.objectImage = object;
            settings.useFLANN = true;
            settings.ransacReprojThreshold = 5;
            ObjectFinder finder = new ObjectFinder(settings);

            long start = System.currentTimeMillis();
            double[] dst_corners = finder.find(image);
            System.out.println("Finding time = "
                    + (System.currentTimeMillis() - start) + " ms");

            if (dst_corners != null) {
                for (int i = 0; i < 4; i++) {
                    int j = (i + 1) % 4;
                    int x1 = (int) Math.round(dst_corners[2 * i]);
                    int y1 = (int) Math.round(dst_corners[2 * i + 1]);
                    int x2 = (int) Math.round(dst_corners[2 * j]);
                    int y2 = (int) Math.round(dst_corners[2 * j + 1]);
                    cvLine(correspond, cvPoint(x1, y1 + object.height()),
                            cvPoint(x2, y2 + object.height()), CvScalar.WHITE,
                            1, 8, 0);
                    System.out.println("x1 :" + x1 + " y1 :" + y1);
                }
            }

            for (int i = 0; i < finder.ptpairs.size(); i += 2) {
                CvPoint2D32f pt1 = finder.objectKeypoints[finder.ptpairs.get(i)]
                        .pt();
                CvPoint2D32f pt2 = finder.imageKeypoints[finder.ptpairs
                        .get(i + 1)].pt();
                cvLine(correspond,
                        cvPointFrom32f(pt1),
                        cvPoint(Math.round(pt2.x()),
                                Math.round(pt2.y() + object.height())),
                        CvScalar.WHITE, 1, 8, 0);
            }

            CanvasFrame objectFrame = new CanvasFrame("Object");
            CanvasFrame correspondFrame = new CanvasFrame("Object Correspond");

            correspondFrame.showImage(correspond);
            for (int i = 0; i < finder.objectKeypoints.length; i++) {
                CvSURFPoint r = finder.objectKeypoints[i];
                CvPoint center = cvPointFrom32f(r.pt());
                int radius = Math.round(r.size() * 1.2f / 9 * 2);
                cvCircle(objectColor, center, radius, CvScalar.RED, 1, 8, 0);
            }
            objectFrame.showImage(objectColor);

            objectFrame.waitKey();

            objectFrame.dispose();
            correspondFrame.dispose();
        }
    }

Following is the output :

2013年3月6日 上午11:23:39 ObjectFinder setSettings
INFO: 593 object descriptors
2013年3月6日 上午11:23:39 ObjectFinder find
INFO: 782 image descriptors
2013年3月6日 上午11:23:39 ObjectFinder locatePlanarObject
INFO: 37 matching pairs found
Finding time = 172 ms
x1 :118 y1 :161
x1 :283 y1 :175
x1 :269 y1 :299
x1 :89 y1 :273
2013年3月6日 上午11:23:40 ObjectFinder setSettings
INFO: 593 object descriptors
2013年3月6日 上午11:23:40 ObjectFinder find
INFO: 782 image descriptors
2013年3月6日 上午11:23:40 ObjectFinder locatePlanarObject
INFO: 40 matching pairs found
Finding time = 156 ms
x1 :118 y1 :161
x1 :283 y1 :175
x1 :269 y1 :298
x1 :89 y1 :273
2013年3月6日 上午11:23:41 ObjectFinder setSettings
INFO: 593 object descriptors
2013年3月6日 上午11:23:41 ObjectFinder find
INFO: 782 image descriptors
2013年3月6日 上午11:23:41 ObjectFinder locatePlanarObject
INFO: 42 matching pairs found
Finding time = 156 ms
x1 :118 y1 :161
x1 :284 y1 :175
x1 :269 y1 :299
x1 :90 y1 :273

These 3 sets of result are different.
However, I found that every time I run this program, the output is the same, 
which means the 3 sets of result are same as previous 3 sets.

Original comment by rjisgr...@msn.com on 6 Mar 2013 at 3:35

GoogleCodeExporter commented 9 years ago
If you want /exactly/ the same results down to the nearest pixel, then you 
shouldn't use FLANN. Do not set the `useFLANN` setting to `true`: Leave to 
`false`.

And please ask your questions on the mailing list next time if possible, thank 
you.

Original comment by samuel.a...@gmail.com on 9 Mar 2013 at 3:42