繁体   English   中英

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

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

我正在尝试在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)

我的源代码如下:

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

请告诉我我的错误是什么。 我无法解决此问题。 我还尝试了代码中的许多变体,但没有用。

看来分类器没有从文件中正确加载。

请确保faceDetector.load()返回true,否则不会读取文件。

这是5个月前发布的,但为了在尝试所有建议的解决方案后仍将面临这一挑战的人们,在遇到相同挑战后我发现了另一种可能性。 如果getPath()返回的URL中存在空格,则空格将作为"%20"返回。

例如:/ /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
您需要将"%20"回空格。

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

注意: substring(1)用于删除路径中的初始"/" 如果不需要该呼叫,可以将其删除。

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

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

我也在同一个问题上挣扎。 指示haarcascade_frontalface_alt.xml文件的目录对我来说很好用。 您也可以尝试。

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

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

首先,在这种情况下,您应该检查CascadeClassifier是否已正确加载指定的XML资源。 有两种方法:检查load()方法是否返回true。 另一种方法(例如,如果您不使用此方法,而只是在构造函数中指定必需的资源)是使用empty()方法,以确保正确加载分类器。

暂无
暂无

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

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