【问题标题】:OpenCV Error: Assertion failed (!empty()) in java and opencv 3.0 and what does it mean?OpenCV 错误:Java 和 opencv 3.0 中的断言失败 (!empty()),这是什么意思?
【发布时间】:2018-04-10 23:35:58
【问题描述】:

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

请告诉我我的错误是什么。我无法解决这个问题。我还尝试了代码的许多变体,但它不起作用。

【问题讨论】:

标签: java opencv image-processing


【解决方案1】:

似乎没有从文件中正确加载分类器。

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

【讨论】:

  • 那么请通过回答如何“确保 faceDetector.load() 返回 true”让你的答案足够清楚
【解决方案2】:

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

例如: /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) 是去掉路径中最初的"/"。如果您不需要该调用,可以将其删除。

【讨论】:

    【解决方案3】:

    我也在努力解决同样的问题。指示 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);
        }
    }
    

    【讨论】:

      【解决方案4】:
      "C:\\opencv2.4.9\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml"
      

      在窗口中给出路径时使用双斜杠。

      【讨论】:

      • 您也可以使用单个“普通”斜杠,即使在 Windows 上也是如此。
      【解决方案5】:

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

      【讨论】:

      • 其实我还没有做函数writeframe,请看上面的代码;0 对不起
      【解决方案6】:

      Java 不适用于 getResoure("...").getPath() 因此,将所有具有该功能的行更改为绝对路径,例如:"C:/Users/USER/workspace/SmallTest/bin/face.jpg" 我刚刚解决了。 对不起英语不好

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          猜你喜欢
          • 2015-06-04
          • 2021-09-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-20
          • 1970-01-01
          • 2017-07-14
          • 1970-01-01
          相关资源
          最近更新 更多