简体   繁体   English

OpenCV错误:在Java和OpenCV 3.0中断言失败(!empty()),这是什么意思?

[英]OpenCV Error: Assertion failed (!empty()) in java and opencv 3.0 and what does it mean?

I am trying to run a code in java and when I run this code, it throws the following error: 我正在尝试在Java中运行代码,当我运行此代码时,它将引发以下错误:

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. 我还尝试了代码中的许多变体,但没有用。

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. 请确保faceDetector.load()返回true,否则不会读取文件。

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. 这是5个月前发布的,但为了在尝试所有建议的解决方案后仍将面临这一挑战的人们,在遇到相同挑战后我发现了另一种可能性。 If there are spaces in the URL returned by getPath() , the spaces are returned as "%20" . 如果getPath()返回的URL中存在空格,则空格将作为"%20"返回。

For example: /C:/Users/Ayomide.Johnson/Documents/NetBeansProjects/OpenCV%20Test%20Project/build/classes/haarcascade_frontalface_alt.xml 例如:/ /C:/Users/Ayomide.Johnson/Documents/NetBeansProjects/OpenCV%20Test%20Project/build/classes/haarcascade_frontalface_alt.xml : /C:/Users/Ayomide.Johnson/Documents/NetBeansProjects/OpenCV%20Test%20Project/build/classes/haarcascade_frontalface_alt.xml
You need to change the "%20" back to spaces. 您需要将"%20"回空格。

My tweek was: FaceDetector.class.getResource("x.JPG").getPath().substring(1).replace("%20", " ") and it worked! 我的第一个星期是: FaceDetector.class.getResource("x.JPG").getPath().substring(1).replace("%20", " ") ,它起作用了!

Note: The substring(1) is to remove the initial "/" in the path. 注意: substring(1)用于删除路径中的初始"/" If you do not need that call, you can remove it. 如果不需要该呼叫,可以将其删除。

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

在Windows中提供路径时,请使用双斜杠。

I was also struggling with the same problem. 我也在同一个问题上挣扎。 Indicating the directory of the haarcascade_frontalface_alt.xml file worked fine for me. 指示haarcascade_frontalface_alt.xml文件的目录对我来说很好用。 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);
    }
}

Adding convert-buffered-image to mat type variable fixes the problem. 将convert-buffered-image添加到mat类型变量可解决此问题。

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

    }


} 

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. Java无法与getResoure("...").getPath()因此将所有具有该功能的行更改为绝对路径,例如: "C:/Users/USER/workspace/SmallTest/bin/face.jpg"刚刚解决了。 Sorry for bad English 对不起英语不好

First of all in this case you should check if CascadeClassifier has properly loaded the specified XML resource. 首先,在这种情况下,您应该检查CascadeClassifier是否已正确加载指定的XML资源。 There are 2 ways of doing this: either check if the load() method returns true. 有两种方法:检查load()方法是否返回true。 Another way (eg 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. 另一种方法(例如,如果您不使用此方法,而只是在构造函数中指定必需的资源)是使用empty()方法,以确保正确加载分类器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM