1

I am trying to run a code in java and when I run this code, it throws the following error:

OpenCV Error: Assertion failed (!empty()) in cv::CascadeClassifier::detectMultiScale, file C:\builds\master_PackSlaveAddon-win64-vc12-static\opencv\modules\objdetect\src\cascadedetect.cpp, line 1634
Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: C:\builds\master_PackSlaveAddon-win64-vc12-static\opencv\modules\objdetect\src\cascadedetect.cpp:1634: error: (-215) !empty() in function cv::CascadeClassifier::detectMultiScale
]
    at org.opencv.objdetect.CascadeClassifier.detectMultiScale_1(Native Method)
    at org.opencv.objdetect.CascadeClassifier.detectMultiScale(CascadeClassifier.java:103)
    at FaceDetector.main(FaceDetector.java:30)

My source code is the following:

import org.opencv.core.Core;
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.objdetect.CascadeClassifier;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

public class FaceDetector {

    public static void main(String[] args) {

        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        System.out.println("\nRunning FaceDetector");

       CascadeClassifier faceDetector = new CascadeClassifier(FaceDetector.class.getResource("haarcascade_frontalface_alt.xml").getPath());
        //CascadeClassifier cascade1 = new CascadeClassifier("C:/OpenCV/opencv/sources/data/haarcascades/haarcascade_frontalface_alt.xml");
        //CascadeClassifier cascade1 = new CascadeClassifier("C:/OpenCV/opencv/sources/data/lbpcascade/lbpcascade_frontalface.xml");
        //CascadeClassifier cascade1=new CascadeClassifier();
        //cascade1.load("C:/opencv2.4.9/sources/data/haarcascades/haarcascade_frontalface_alt.xml");
       faceDetector.load("C:/opencv2.4.9/sources/data/haarcascades/haarcascade_frontalface_alt.xml");
        System.out.println("step1");
        Mat image = Imgcodecs.imread(FaceDetector.class.getResource("anuj.jpg").getPath());
        System.out.println("step2");
        MatOfRect faceDetections = new MatOfRect();
        System.out.println("step3");
        faceDetector.detectMultiScale(image, faceDetections);
        System.out.println("step4");
        try {
            System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            System.err.println("ERROR IS HERE");
            //e.printStackTrace();
        }

        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));
        }

        String filename = "ouput.png";
        System.out.println(String.format("Writing %s", filename));
        Imgcodecs.imwrite(filename, image);
    }
}

Please tell me what is my mistake. I am not able to solve this. I also tried many variations in the code but it does not work.

1

7 Answers 7

4

It seems that the classifier is not being loaded properly from file.

Please ensure that faceDetector.load() returns true, otherwise the file is not being read.

Sign up to request clarification or add additional context in comments.

1 Comment

so then please make your answer clear enough by answer too how to "ensure that faceDetector.load() returns true"
3

This was posted 5 months ago, but for the sake of people who are still going to be faced with this challenge after trying all proposed solutions, there is another possibility which I found out after facing same challenge. If there are spaces in the URL returned by getPath(), the spaces are returned as "%20".

For example: /C:/Users/Ayomide.Johnson/Documents/NetBeansProjects/OpenCV%20Test%20Project/build/classes/haarcascade_frontalface_alt.xml
You need to change the "%20" back to spaces.

My tweek was: FaceDetector.class.getResource("x.JPG").getPath().substring(1).replace("%20", " ") and it worked!

Note: The substring(1) is to remove the initial "/" in the path. If you do not need that call, you can remove it.

Comments

1

I was also struggling with the same problem. Indicating the directory of the haarcascade_frontalface_alt.xml file worked fine for me. You may try it too.

package faceDetection;

import org.opencv.core.Core;
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 FaceDetection
{

    public static void main(String[] args)
    {

        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);


        CascadeClassifier faceDetector = new CascadeClassifier();
        faceDetector.load("D:\\OpenCv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
        System.out.println ( "Working" );
        // Input image
        Mat image = Imgcodecs.imread("E:\\input.jpg");

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

        // Creating a rectangular box showing faces detected
        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));
        }

        // Saving the output image
        String filename = "Ouput.jpg";
        Imgcodecs.imwrite("E:\\"+filename, image);
    }
}

Comments

0
"C:\\opencv2.4.9\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml"

Use double slash when you give path in windows.

1 Comment

You can also use a single "normal" slash, even on Windows.
0

Adding convert-buffered-image to mat type variable fixes the problem.

package facedetect;

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

import javax.imageio.ImageIO;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.objdetect.CascadeClassifier;

public class FaceDetector {
    // https://blog.openshift.com/day-12-opencv-face-detection-for-java-developers/
    // make user library and add it to project

    public static void main(String[] args) throws IOException {
        BufferedImage image = ImageIO.read(new File("/hayanchoi/scene1.png"));
        detectFace(image);
    }

    private static Mat convertBufImg2Mat(BufferedImage image) {
        DataBufferByte s;
        byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
        Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3);
        mat.put(0, 0, data);
        return mat;
    }

    private static int detectFace(BufferedImage image) {

        System.out.println("step0: Running FaceDetector");
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        CascadeClassifier faceDetector = new CascadeClassifier(
                FaceDetector.class.getResource("haarcascade_frontalface_alt.xml").getPath());
        if (!faceDetector.load("E:/hayanchoi/FaceDetectionTest/bin/facedetect/haarcascade_frontalface_alt.xml")) {
            return -1;
        }

        System.out.println("step1: convert bufferedimage to mat type");
        Mat matImage = convertBufImg2Mat(image);


        System.out.print("step2: detect face- ");
        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale(matImage, faceDetections);
        System.out.println(String.format(" %s faces", faceDetections.toArray().length));

        System.out.println("step3: write faces");
        String filename = "/0_research/" + "ouput.png";
        for (Rect rect : faceDetections.toArray()) {
            writeFrame(filename, matImage, rect);
        }
        return faceDetections.toArray().length;
    }

    private static BufferedImage cropImage(BufferedImage src, Rect rect) {
        BufferedImage dest = src.getSubimage(rect.x, rect.y, rect.width, rect.height);
        return dest;
    }

    public static void writeFrame(String filename, Mat mat, Rect rect) {

        byte[] data = new byte[mat.rows() * mat.cols() * (int) (mat.elemSize())];
        mat.get(0, 0, data);
        if (mat.channels() == 3) {
            for (int i = 0; i < data.length; i += 3) {
                byte temp = data[i];
                data[i] = data[i + 2];
                data[i + 2] = temp;
            }
        }
        BufferedImage image = new BufferedImage(mat.cols(), mat.rows(), BufferedImage.TYPE_3BYTE_BGR);
        image.getRaster().setDataElements(0, 0, mat.cols(), mat.rows(), data);
        BufferedImage frame = cropImage(image, rect);
        try {
            ImageIO.write(frame, "png", new File(filename + ".png"));

        } catch (IOException e) {
            e.printStackTrace();
        } 

    }


} 

1 Comment

Actually i didn't make the function writeframe yet, please see the upper side of the code;0 sorry
0

Java didn't work with getResoure("...").getPath() So change all lines have that function to absolute path , example :"C:/Users/USER/workspace/SmallTest/bin/face.jpg" I just have resolved it. Sorry for bad English

Comments

0

First of all in this case you should check if CascadeClassifier has properly loaded the specified XML resource. There are 2 ways of doing this: either check if the load() method returns true. Another way (e.g. if you didn't use this method just specifying the necessary resource in the constructor) is to use empty() method to ensure classifier has been loaded properly.

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.