I'm trying to use FaceRecognition with javacv. But when I have more than 5 train images I get this error:
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6a30b400, pid=4856, tid=32
#
# JRE version: Java(TM) SE Runtime Environment (7.0_51-b13) (build 1.7.0_51-b13)
# Java VM: Java HotSpot(TM) Client VM (24.51-b03 mixed mode, sharing windows-x86 )
# Problematic frame:
# C [opencv_core246.dll+0x4b400]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\reco\workspace\hellow\hs_err_pid4856.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
This is my code:
import com.googlecode.javacv.cpp.opencv_core;
import static com.googlecode.javacv.cpp.opencv_highgui.*;
import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_contrib.*;
import java.io.File;
import java.io.FilenameFilter;
public class OpenCVFaceRecognizer {
public static void main(String[] args) {
String trainingDir = "C:/Users/reco/workspace/hellow";
IplImage testImage = cvLoadImage("C:/Users/reco/workspace/0.png");
File root = new File(trainingDir);
FilenameFilter pngFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".png");
}
};
File[] imageFiles = root.listFiles(pngFilter);
MatVector images = new MatVector(imageFiles.length);
int[] labels = new int[imageFiles.length];
int counter = 0;
int label;
IplImage img;
IplImage grayImg;
for (File image : imageFiles) {
img = cvLoadImage(image.getAbsolutePath());
String temp= image.getName();
label = Integer.parseInt(temp.charAt(0)+"");
grayImg = IplImage.create(img.width(), img.height(), IPL_DEPTH_8U, 1);
cvCvtColor(img, grayImg, CV_BGR2GRAY);
images.put(counter, grayImg);
labels[counter] = label;
counter++;
}
IplImage greyTestImage = IplImage.create(testImage.width(), testImage.height(), IPL_DEPTH_8U, 1);
//FaceRecognizer faceRecognizer = createFisherFaceRecognizer();
FaceRecognizer faceRecognizer = createEigenFaceRecognizer();
// FaceRecognizer faceRecognizer = createLBPHFaceRecognizer()
faceRecognizer.train(images, labels);
cvCvtColor(testImage, greyTestImage, CV_BGR2GRAY);
int predictedLabel = faceRecognizer.predict(greyTestImage);
System.out.println("Predicted label: " + predictedLabel);
}
}
edit::i just removed
grayImg = IplImage.create(img.width(), img.height(), IPL_DEPTH_8U, 1);
cvCvtColor(img, grayImg, CV_BGR2GRAY);
and it worked :)
IplImage img;
IplImage grayImg=null;
for (File image : imageFiles) {
img = cvLoadImage(image.getAbsolutePath(),CV_BGR2GRAY);
int yer = image.getName().indexOf(".");
String isim=image.getName().substring(0,yer);
label = Integer.parseInt(isim);
images.put(counter, img);
labels[counter] = label;
counter++;
}
it is the final of my code and it works like a charm :)
Related
I am using opencv 3.2 for Java (build source with contrib modules), and trying to use SURF + BOWKMeansTrainer for detect, but it throws an error when I run it.
My code:
//read jpg to variable trainMats
//...
//train
Mat allDesc = new Mat();
int clusterCount = 30;
FeatureDetector detector = FeatureDetector.create(FeatureDetector.SURF);
DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.SURF);
BOWTrainer bowTrainer = new BOWKMeansTrainer(clusterCount);
for(int i = 0; i < trainMats.size(); i++) {
Mat trainMat = trainMats.get(i);
MatOfKeyPoint matOfKeyPoint = new MatOfKeyPoint();
Mat desc = new Mat();
detector.detect(trainMat, matOfKeyPoint);
extractor.compute(trainMat, matOfKeyPoint, desc);
allDesc.push_back(desc);
}
Mat dictionary = bowTrainer.cluster(allDesc);
//...
throw error:
Exception in thread "main" java.lang.Exception: unknown exception
at org.opencv.features2d.BOWKMeansTrainer.cluster_1(Native Method)
at org.opencv.features2d.BOWKMeansTrainer.cluster(BOWKMeansTrainer.java:62)
Is by the OpenCV version.
Try using 2.4.11
Is any one know how i can convert Mat to IplImage ?
to achieve this i have converted Mat to BufferedImage but again not able to find conversion in BufferedImage to IplImage.
is there any way where i can convert Mat to IplImage?
Thanks
I believe you can convert BufferedImage to IplImage as follows.
public static IplImage toIplImage(BufferedImage src) {
Java2DFrameConverter bimConverter = new Java2DFrameConverter();
OpenCVFrameConverter.ToIplImage iplConverter = new OpenCVFrameConverter.ToIplImage();
Frame frame = bimConverter.convert(src);
IplImage img = iplConverter.convert(frame);
IplImage result = img.clone();
img.release();
return result;
}
I got this from this question. Try this for now. I'll check if direct conversion is possible.
UPDATE:
Please have a look at this api docs. I haven't tested the following. Wrote it just now. Please do try and let me know.
public static IplImage toIplImage(Mat src) {
OpenCVFrameConverter.ToIplImage iplConverter = new OpenCVFrameConverter.ToIplImage();
OpenCVFrameConverter.ToMat matConverter = new OpenCVFrameConverter.ToMat();
Frame frame = matConverter.convert(src);
IplImage img = iplConverter.convert(frame);
IplImage result = img.clone();
img.release();
return result;
}
Trying to figure out a way to gather the confidence level when it actually does the face recognizing on the target image. I have searched through a few examples but haven't found anything I can see how to implement. All help appreciated, thanks guys.
public static void facecompare() {
String trainingDir = "C:/TrainingDirectory"; //training directory
IplImage testImage = cvLoadImage("C:/TargetImages/boland_straight_happy_open_4.pgm"); //the target image
File root = new File(trainingDir);
FilenameFilter pngFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".pgm");
}
};
File[] imageFiles = root.listFiles(pngFilter);
MatVector images = new MatVector(imageFiles.length);
int[] labels = new int[imageFiles.length];
int counter = 0;
int label;
IplImage img;
IplImage grayImg;
for (File image : imageFiles) {
img = cvLoadImage(image.getAbsolutePath());
label = Integer.parseInt(image.getName().split("\\-")[0]);
grayImg = IplImage.create(img.width(), img.height(), IPL_DEPTH_8U, 1);
cvCvtColor(img, grayImg, CV_BGR2GRAY);
images.put(counter, grayImg);
labels[counter] = label;
counter++;
}
IplImage greyTestImage = IplImage.create(testImage.width(), testImage.height(), IPL_DEPTH_8U, 1);
// FaceRecognizer faceRecognizer = createFisherFaceRecognizer();
// FaceRecognizer faceRecognizer = createEigenFaceRecognizer();
FaceRecognizer faceRecognizer = createLBPHFaceRecognizer();
faceRecognizer.train(images, labels);
cvCvtColor(testImage, greyTestImage, CV_BGR2GRAY);
int predictedLabel = faceRecognizer.predict(greyTestImage);
System.out.println("Predicted label: " + predictedLabel);
}
There is another predict method that returns the confidence:
// pointer-like output parameters
// only the first element of these arrays will be changed
int[] plabel = new int[1];
double[] pconfidence = new double[1];
faceRecognizer.predict(greyTestImage, plabel, pconfidence);
int predictedLabel = plabel[0];
double confidence = pconfidence[0];
I have the following code:
IplImage* f( IplImage* src )
{
// Must have dimensions of output image
IplImage* cropped = cvCreateImage( cvSize(1280,500), src->depth, src->nChannels );
// Say what the source region is
cvSetImageROI( src, cvRect( 0,0, 1280,500 ) );
// Do the copy
cvCopy( src, cropped );
cvResetImageROI( src );
return cropped;
}
void testApp::setup(){
img.loadImage("test.jpg");
finder.setup("haarcascade_frontalface_default.xml");
finder.findHaarObjects(img);
}
//--------------------------------------------------------------
void testApp::update(){
}
//--------------------------------------------------------------
ofRectangle cur;
void testApp::draw(){
img = f(img);
img.draw(0, 0);
ofNoFill();
for(int i = 0; i < finder.blobs.size(); i++) {
cur = finder.blobs[i].boundingRect;
ofRect(cur.x-20, cur.y-20, cur.width+50, cur.height+50);
}
}
It produces an error. I think it's because I don't convert IplImage to ofImage. Can someone please tell me how to do it?
I would imagine that your instance of img, that your passing to f(), is an instance of ofxCVImage or similar. As far as I know ofx store a protected variable of iplimage, as such you can't cast ofxCVImage to an iplimage.
You might try
img = f(img.getCvImage()) // ofxCvImage::getCvImage() returns IplImage
I'm been trying to capture video from a cam and write it into an AVI file. I'm using Qt 4.8.2 with MSVC 2010 (x86) on Windows 7. I have 2 versions of the code: one using cv::Mat and the other using IplImage*. However, only the IplImage* version is working. Here's my code using cv::Mat:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main() {
VideoCapture* capture2 = new VideoCapture( CV_CAP_DSHOW );
Size size2 = Size(640,480);
int codec = CV_FOURCC('M', 'J', 'P', 'G');
VideoWriter* writer2 = new VideoWriter("video.avi",codec,15,size2);
int a = 100;
Mat frame2;
while ( a > 0 ) {
capture2->read(frame2);
writer2->write(frame2);
a--;
}
writer2->release();
capture2->release();
return 0;
}
And here's the code using IplImage*:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
int main() {
CvCapture* capture = cvCaptureFromCAM( CV_CAP_DSHOW );
CvSize size = cvSize(640,480);
int codec = CV_FOURCC('M', 'J', 'P', 'G');
CvVideoWriter* writer = cvCreateVideoWriter("video.avi",codec,15,size);
int a = 100;
while ( a > 0 ) {
IplImage* frame = cvQueryFrame( capture );
cvWriteToAVI(writer,frame);
a--;
}
cvReleaseVideoWriter(&writer);
cvReleaseCapture( &capture );
return 0;
}
It's basically the same, or at least it looks like the same thing to me. It reads 100 frames and should write them into "video.avi". It compiles and runs without errors, but the cv::Mat version doesn't write anything, and the IplImage* version works perfectly.
Does someone have any idea on what's going on?
The syntax in Opencv C++ reference is bit different, and here is a working code in C++.
I Just added imshow and waitkey, for checking you can remove them if you want.
int main()
{
VideoCapture* capture2 = new VideoCapture(CV_CAP_DSHOW);
Size size2 = Size(640, 480);
int codec = CV_FOURCC('M', 'J', 'P', 'G');
// Unlike in C, here we use an object of the class VideoWriter//
VideoWriter writer2("video_.avi", codec, 15.0, size2, true);
writer2.open("video_.avi", codec, 15.0, size2, true);
if (writer2.isOpened())
{
int a = 100;
Mat frame2;
while (a > 0)
{
capture2->read(frame2);
imshow("live", frame2);
waitKey(100);
writer2.write(frame2);
a--;
}
}
else
{
cout << "ERROR while opening" << endl;
}
// No Need to release the Writer as the distructor will called automatically
capture2->release();
return 0;
}
I had the same problem over and over again, and none of the solutions I found online helped.
Strange enough, the problem (identified purely with a trial and error method) was with the write permission. Everything worked after I sudo chmod u+rwx the python script.
I have the same problem and after a few time i realize that the input video isn't the same size with the output. Resize the input video may help u.
capture2->read(frame2);
cv::resize(frame2,frame2,cv::Size(640,480);
writer2->write(frame2);