View Single Post
  #1   Spotlight this post!  
Unread 09-02-2012, 16:32
violinuxer violinuxer is offline
Registered User
FRC #2523
 
Join Date: Jan 2012
Location: Vermont
Posts: 13
violinuxer is an unknown quantity at this point
Massive memory leaks in smartdashboard image processing library.

Hi all!

Our team is using the libraries in SmartDashboard (WPIJavaCV) to do our image processing. We are planning to do image processing on a driverstation computer and then send motor values on the robot. We are up to the point where we can detect rectangles (ie the backboard) but we have been noticing huge memory leaks- SmartDashboard will take more than a gigabyte of memory after only a couple minutes. I have managed to narrow the problem down to the highligted line below. It leaks only when that line is in the code regardless of whether this line assigns its result to a variable. I have been monitoring the code with JVisualVM, which shows a memory usage of under 10MB in java, while the task manager reads usages in the hundreds of MB. Is this a bug in OpenCV? It could make sense due to the fact that JavaCV is just a wrapper of the c version...

Code:
    public WPIImage processImage(WPIColorImage rawImage) {
        int cameraCenterX = rawImage.getWidth() - (rawImage.getWidth() / 2);
        int cameraCenterY = rawImage.getHeight() - (rawImage.getHeight() / 2);
        threshold = thresholdDialog.getThreshold();
        WPIBinaryImage redChannel;
        WPIBinaryImage greenChannel;
        WPIBinaryImage blueChannel;
        WPIBinaryImage finalImage;
        if (thresholdDialog.isInverted()) {
            redChannel = rawImage.getRedChannel().getThreshold(threshold);
            greenChannel = rawImage.getGreenChannel().getThreshold(threshold);
            blueChannel = rawImage.getBlueChannel().getThreshold(threshold);
        } else {
            redChannel = rawImage.getGreenChannel().getThresholdInverted(threshold);
            greenChannel = rawImage.getGreenChannel().getThresholdInverted(threshold);
            blueChannel = rawImage.getGreenChannel().getThresholdInverted(threshold);
        }
        finalImage = redChannel.getAnd(greenChannel.getAnd(blueChannel));

        finalImage.erode(thresholdDialog.getErodeLevel());
        finalImage.dilate(thresholdDialog.getDilateLevel());
        WPIContour[] contours = finalImage.findContours(); // This line causes the memory leak even without assigning to a variable.
        minSize = thresholdDialog.getMinSize();
        maxSize = thresholdDialog.getMaxSize();
        int rectCenterX = 0;
        int rectCenterY = 0;
        int aspectRatio = 0;
        int polyAccuracy = thresholdDialog.getPolyAccuracy();
        
        for (int i = 0; i < contours.length; i++) {
            aspectRatio = contours[i].getWidth() / contours[i].getHeight();
            if (contours[i].getHeight() > minSize && contours[i].getWidth() > minSize && 
                   contours[i].getHeight() < maxSize && contours[i].getWidth() < maxSize) {
                if (aspectRatio < 1.5 && aspectRatio > .75) {
                    WPIPolygon currPolygon = contours[i].approxPolygon(polyAccuracy);
                    if (currPolygon.isConvex() && currPolygon.getNumVertices() == 4) {
                        rectCenterX = currPolygon.getX() + currPolygon.getWidth() / 2;
                        rectCenterY = currPolygon.getY() + currPolygon.getHeight()/ 2;

                        rawImage.drawPolygon(currPolygon, WPIColor.RED, 2);
                        rawImage.drawPoint(new WPIPoint(rectCenterX, rectCenterY), WPIColor.GREEN, 5);
                        rawImage.drawPoint(new WPIPoint(cameraCenterX, cameraCenterY), WPIColor.BLUE, 5);
                    }
                }
            }
        }
        return rawImage; 
    }
}
If anybody has used the same methods successfully, please do post! The knowledge would be greatly appreciated!

Thanks!

violinuxer
Reply With Quote