Reputation: 11
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.
Upvotes: 1
Views: 10150
Reputation: 71
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.
Upvotes: 0
Reputation: 4127
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);
}
}
Upvotes: 1
Reputation: 31
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.
Upvotes: 3
Reputation: 1
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
Upvotes: 0
Reputation: 21
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();
}
}
}
Upvotes: 0
Reputation: 55
"C:\\opencv2.4.9\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml"
Use double slash when you give path in windows.
Upvotes: 0
Reputation: 507
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.
Upvotes: 4