0

I am working in java on a program that uses the opencv library to take a folder of images and crop just the faces. It uses face recognition from opencv. I got it to work, but when I try it with a larger folder of images it stops with these errors:

OpenCV Error: Insufficient memory (Failed to allocate 411068928 bytes) in cv::OutOfMemoryError, file C:\builds\master_PackSlaveAddon-win32-vc12-static\opencv\modules\core\src\alloc.cpp, line 52 OpenCV Error: Assertion failed (u != 0) in cv::Mat::create, file C:\builds\master_PackSlaveAddon-win32-vc12-static\opencv\modules\core\src\matrix.cpp, line 411 Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: C:\builds\master_PackSlaveAddon-win32-vc12-static\opencv\modules\core\src\matrix.cpp:411: error: (-215) u != 0 in function cv::Mat::create ] at org.opencv.objdetect.CascadeClassifier.detectMultiScale_1(Native Method) at org.opencv.objdetect.CascadeClassifier.detectMultiScale(CascadeClassifier.java:103) at FaceDetector.main(FaceDetector.java:42)

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.plaf.synth.SynthSeparatorUI;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;

public class FaceDetector {
    public static void main(String[] args) throws IOException {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    System.out.println("\nRunning FaceDetector");

    CascadeClassifier faceDetector = new CascadeClassifier("C:/Users/Family/workspace/detect face/haarcascade_frontalface_alt.xml");

    File folder = new File("C:\\Users\\Family\\Downloads\\Photos (4)");
    File[] listOfFiles = folder.listFiles();

    for (int j = 0; j < listOfFiles.length; j++) {
        System.out.println(listOfFiles[j]);
    }

    for (int i = 0; i < listOfFiles.length-1; i++){
        String picname = listOfFiles[i].toString();

        System.out.println("reading: " + listOfFiles[i]);

        Mat image = Imgcodecs.imread(picname);

        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale(image, faceDetections);

        System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));


        for (Rect rect : faceDetections.toArray()) {
            Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar (0, 255, 0));
        }

        Rect recta = new Rect();

        for (Rect rect : faceDetections.toArray()) {
            recta.x = rect.x;
            recta.y = rect.y;
            recta.width = rect.width;
            recta.height = rect.height;
        }


        if (faceDetections.toArray().length == 1) {
            BufferedImage picture = ImageIO.read(new File(picname));
            BufferedImage croppedImage = picture.getSubimage(recta.x, recta.y, recta.width, recta.height);

//              File finalCropped = new     File(listOfFiles[i].toString()+"cropped.jpg");
            File finalCropped = new File("C:/Users/Family/Downloads/CroppedImages/" + "cropped" + (i + 140) + ".jpg");

            ImageIO.write(croppedImage, "jpg", finalCropped);

            System.out.println("Cropping " + i + "/" + listOfFiles.length);

        }

        faceDetections.release();
    }
    System.out.println("Process complete.");

}
}

2 Answers 2

2

You should release image object too. I would like to suggest to use a try catch finally for proper release.

image.release();
Sign up to request clarification or add additional context in comments.

3 Comments

I did this and the program got further than last time, but it stopped at the same error. I'm just going to try with a shorter amount of images.
well that did nothing
You might want to call System.gc() if the loop count is divisible by some number like 5 or 10. You also need to release the Mat objects loaded by Imgcodecs.imread too.
0

Have you tried to increase the Heap Space ? Have a look here.

The java.lang.OutOfMemoryError: Java heap space error will be triggered when the application attempts to add more data into the heap space area, but there is not enough room for it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.