rindarith / javacv

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

cvFindContours & cvApproxPoly Performance Problem? #10

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

Hello Samuel,

I have been experimenting with cvFindContours & cvApproxPoly.
I have noticed when the polygon count is greater than 18(ish) it  will take > 
10 seconds to process.  I don't seem to get the same behavior in a similar .c 
program.  I was guessing this had to do with the amount of data transported 
through the jna call. 6 Polygons require ~1 second. This makes "real time" 
processing a bit of a challenge.

I was initially hoping to filter some of the polygons out based on area, but 
noticed cvContourArea is commented out.  Was this intentional?

I suspect that this is not a problem with the your great code, but just an area 
where OpenCV has a significant amount of data being processed as return values 
or passed with pointers, and the JNA wrapper incurs a significant performance 
loss.  

With that in mind I was wondering what you might recommend as a strategy? The 
amount of data when you isolate the polygons you are interested in is 
surprisingly sparse. For example, I am only interested resulting bounding 
perimeter and centroid which consists of a few points.  The problem is, to get 
there, a large amount of data needs to be passed back and forth.

I could write my own blob function in c and jna wrap that with minimal data 
exchange.  I believe they have done that at OPENCV 
(http://ubaa.net/shared/processing/opencv/). This works, but seems rather 
fragile in the long run.  It would need to be maintained, remain compatible 
with Linux, Windows, Mac, remain compatible with opencv releases.. etc... etc...

I wish opencv had a blob function with a variety of parameters and a simple  
(lean) data structure passed back.  Alas, there seems to be a considerable 
amount of disparity in the subject. The blobslib must be separately downloaded 
from opencv and other have similar projects have sprung up (e.g. 
http://code.google.com/p/cvblob/)

I guess after rambling on for a while, the best long term solution would be to 
extend your JNA code to wrap the blobslib from opencv.  Is this of interest to 
you?

I will start looking into the details.

Best Regards,

Greg.

Original issue reported on code.google.com by supert...@gmail.com on 11 Jul 2010 at 2:46

GoogleCodeExporter commented 9 years ago
This is most likely caused by the "auto-synch" feature in JNA, details here 
under "Large Structure": 
https://jna.dev.java.net/javadoc/overview-summary.html#performance

Unfortunately, functions like cvFindContours() and cvApproxPoly() create CvSeq 
objects and the programmer does not get a chance to setAutoSynch(false) before 
they get read... I'll think about what could be done to keep things clean. You 
may however modify the source code of cxcore.java, as a quick fix, by adding 
setAutoSynch(false) to constructors of the CvSeq class.

Samuel

Original comment by samuel.a...@gmail.com on 16 Jul 2010 at 3:01

GoogleCodeExporter commented 9 years ago
To answer some of the other questions, the number of parameters to the 
cvContourArea() method changes with the version of OpenCV, so you need to 
import one of the subclasses based on the version of OpenCV you wish to use.

The problem with blobslib is that it's written in C++.. It's quite hard to use 
C++ interfaces from other languages. Someone would need to produce an interface 
in C first.

Original comment by samuel.a...@gmail.com on 16 Jul 2010 at 3:10

GoogleCodeExporter commented 9 years ago
Great,
Thanks, I will try your suggestion.

Additionally, I was wondering why cvContourArea was commented out?

Original comment by supert...@gmail.com on 16 Jul 2010 at 3:18

GoogleCodeExporter commented 9 years ago
Sorry, did not see your last reply before I posted my last comment.
Makes sense regarding parameter numbers changing.

I'll experiment with the setAutoSynch too. I'd assume that all the fields would 
be null until forcefully read into - not sure how to do that, but I'll look.
Thanks for pointing me in the right direction.

Greg.

Original comment by supert...@gmail.com on 16 Jul 2010 at 8:29

GoogleCodeExporter commented 9 years ago
I modified CvSeq slightly in this test package to include a static autoSynch 
flag:
    http://www.ok.ctrl.titech.ac.jp/~saudet/javacv.jar
With that, something like the following should disable the default auto-synch 
behavior of any newly constructed CvSeq objects:
    CvSeq.autoSynch = false;
Once "auto-synch" is disabled, you need to call the readField() method to read 
the native values of the fields in the Structure. The values of the Java fields 
will not be correct.. 

If that works, I plan to add the flag to all Structures in the next release... 
Please let me know if it works, thanks

Original comment by samuel.a...@gmail.com on 12 Aug 2010 at 3:06

GoogleCodeExporter commented 9 years ago
I am having the same problem. Blob detection is a pain using javaCV. I have 
turned to opencv for processing and it works quite good, but it would be nice 
to see a fix or improvement on the javaCV side.

that jar file did not work for me. Did not notice a difference.

Original comment by victamin...@gmail.com on 25 Oct 2010 at 12:07

GoogleCodeExporter commented 9 years ago
You have to put this line somewhere before your blob detection:
    CvSeq.autoSynch = false;
If you did put this line and it did not improve the performance, then please 
let me know. Otherwise, I am considering this problem fixed, thank you.

Original comment by samuel.a...@gmail.com on 25 Oct 2010 at 2:03