HamoudaOthman / javacv

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

Memory leaks/slow down when using cvHoughLines2 #43

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Running the code sample provided

public class ExampleDifference {

    public static void main(String[] args) {

        new JavaCvErrorCallback().redirectError();

        // memoryLeakExample();
        slowDownExample();
    }

    // In this example we are reusing the CvMemStorage object (but NOT calling
    // cvClearMemStorage).
    //
    // In this case after 20,000 iterations the time per iteration has doubled
    // from 6ms to 11ms however the memory usage has remained stable throughout
    // at only around 20MB
    //
    private static void slowDownExample() {

        String imageFile = "test.png";
        IplImage image = cvLoadImage(imageFile, CV_LOAD_IMAGE_GRAYSCALE);
        IplImage edge = IplImage.create(image.width, image.height, image.depth,
                image.nChannels);
        cvCanny(image, edge, 1000, 1200, 3);
        CvMemStorage mem = CvMemStorage.create();
        long totalTime = 0;
        int iteration = 0;

        while (true) {
            iteration++;
            long start = System.currentTimeMillis();
            CvSeq hough = cvHoughLines2(edge, mem.getPointer(),
                    CV_HOUGH_STANDARD, 1, Math.PI
                            / TuningParameter.houghAnalysisResolution, 1000, 0,
                    0);
            long end = System.currentTimeMillis();
            long time = end - start;
            totalTime += time;

            if (iteration % 100 == 0) {
                System.out.println("Iteration - " + iteration
                        + " average time per iteration " + (totalTime / 100));
                totalTime = 0;
            }

        }

    }

    // In this case, after 20,000 iterations the time per iteration remains
    // stable (at 7ms on my box), but the memory usages has increased
    // continuously to 180MB
    //
    private static void memoryLeakExample() {
        String imageFile = "test.png";
        IplImage image = cvLoadImage(imageFile, CV_LOAD_IMAGE_GRAYSCALE);
        IplImage edge = IplImage.create(image.width, image.height, image.depth,
                image.nChannels);
        cvCanny(image, edge, 1000, 1200, 3);
        long totalTime = 0;
        int iteration = 0;

        while (true) {
            iteration++;
            long start = System.currentTimeMillis();
            CvMemStorage mem = CvMemStorage.create();
            CvSeq hough = cvHoughLines2(edge, mem.getPointer(),
                    CV_HOUGH_STANDARD, 1, Math.PI
                            / TuningParameter.houghAnalysisResolution, 1000, 0,
                    0);
            cvClearMemStorage(mem);
            mem.release();
            cvReleaseMemStorage(mem.pointerByReference());

            long end = System.currentTimeMillis();
            long time = end - start;
            totalTime += time;

            if (iteration % 100 == 0) {
                System.out.println("Iteration - " + iteration
                        + " average time per iteration " + (totalTime / 100));
                totalTime = 0;
            }

        }

    }
}

What is the expected output? What do you see instead?

See comments for detail. In the first case I see a slow down over time, in the 
second case I see a memory leak

What version of the product are you using? On what operating system?

- Lastest precompiled dlls for OpenCV 2.1.0 
- Window 7 64bit

Please provide any additional information below.

Original issue reported on code.google.com by tim.di...@gmail.com on 14 Jan 2011 at 3:55

GoogleCodeExporter commented 8 years ago
You don't need to release it, just clear it with cvClearMemStorage() on every 
iteration 

Can you try to use it in the same way as in the Test2 sample provided in the 
README.txt file?

Original comment by samuel.a...@gmail.com on 15 Jan 2011 at 1:39

GoogleCodeExporter commented 8 years ago
Thanks for your reply. I already tried creating the memory store only once at 
the start of the program and then calling cvClearMemStorage after each 
iteration (as shown in Test2 from the README.txt file). The behaviour that I 
see is the same as in my memoryLeakExample above. i.e. The time per iteration 
remains constant but the memory taken by the process gradually increases...

I have created a stand alone test that doesn't rely on any external images to 
illustrate this. I would be grateful if you could have a look.

I have also tried checking running it against the latest JavaCV code from the 
SVN and I see the same behaviour. I am using the recommended version of JNA 
(3.2.7). 

Any help would be gratefully received.

import static com.googlecode.javacv.jna.cv.CV_HOUGH_STANDARD;
import static com.googlecode.javacv.jna.cv.cvCanny;
import static com.googlecode.javacv.jna.cv.cvHoughLines2;
import static com.googlecode.javacv.jna.cxcore.cvClearMemStorage;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;

import com.googlecode.javacv.JavaCvErrorCallback;
import com.googlecode.javacv.jna.cxcore.CvMemStorage;
import com.googlecode.javacv.jna.cxcore.CvSeq;
import com.googlecode.javacv.jna.cxcore.IplImage;

public class MemoryTest {

    // class to test creating and releasing images from JavaCV
    public static void main(String[] args) throws IOException,
            InterruptedException {

        new JavaCvErrorCallback().redirectError();

        // create a random image
        IplImage image = createRandomImage();
        IplImage edge = IplImage.create(image.width, image.height, image.depth,
                image.nChannels);
        cvCanny(image, edge, 1000, 1200, 3);
        CvMemStorage storage = CvMemStorage.create();

        long totalTime = 0;

        int iteration = 0;
        while (true) {
            iteration++;

            // carry out the hough lines and store the time taken
            long start = System.currentTimeMillis();
            CvSeq hough = cvHoughLines2(edge, storage.getPointer(),
                    CV_HOUGH_STANDARD, 1, Math.PI / 360, 1000, 20, 40);
            long end = System.currentTimeMillis();
            long time = end - start;
            totalTime += time;
            cvClearMemStorage(storage);

            if (iteration % 1000 == 0) {
                System.out.println(iteration + " mean time per iteration "
                        + (totalTime / 1000));
                System.gc();
                Thread.sleep(500);
                totalTime = 0;
            }

        }

    }

    public static IplImage createRandomImage() {
        int width = 100;
        int height = 100;
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_BYTE_GRAY);
        Graphics g = image.getGraphics();
        for (int i = 0; i < 50; i++) {
            int x = (int) (width * Math.random());
            int y = (int) (height * Math.random());
            int x2 = (int) (width * Math.random());
            int y2 = (int) (height * Math.random());
            g.drawLine(x, y, x2, y2);
        }
        return IplImage.createFrom(image);
    }

}

Original comment by tim.di...@gmail.com on 15 Jan 2011 at 4:33

GoogleCodeExporter commented 8 years ago
There is a possibility that OpenCV itself is leaking memory.. Have you tried 
something similar in C/C++ to make sure? I get lots of hit on Google search 
about cvHoughLines2 and memory leaks..

Original comment by samuel.a...@gmail.com on 16 Jan 2011 at 1:54

GoogleCodeExporter commented 8 years ago
I managed to fix the code. I am not sure why this work, but if I called 
cvClearMemStorage on the storage attribute *within* the CvSeq rather than the 
CvMemStorage itself there is no slowdown and no memory leak. To illustrate 
this, in the above example, I simply replaced:

cvClearMemStorage(storage);

with 

cvClearMemStorage(hough.storage);

to solve the problem....

Original comment by tim.di...@gmail.com on 16 Jan 2011 at 1:30

GoogleCodeExporter commented 8 years ago
Ah, looks like there is a bug in OpenCV. cvHoughLines2() must ignore the 
storage given as argument and always creates its own. Good to know, thanks for 
reporting

Original comment by samuel.a...@gmail.com on 16 Jan 2011 at 1:42