import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_contrib.createLBPHFaceRecognizer;
import static com.googlecode.javacv.cpp.opencv_objdetect.cvHaarDetectObjects;
import java.io.File;
import java.io.FileInputStream;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import com.googlecode.javacpp.Loader;
import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.FrameGrabber;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.cpp.opencv_contrib.FaceRecognizer;
import com.googlecode.javacv.cpp.opencv_core.CvMat;
import com.googlecode.javacv.cpp.opencv_core.CvMemStorage;
import com.googlecode.javacv.cpp.opencv_core.CvRect;
import com.googlecode.javacv.cpp.opencv_core.CvSeq;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.googlecode.javacv.cpp.opencv_core.MatVector;
import static com.googlecode.javacv.cpp.opencv_highgui.cvLoadImage;
import com.googlecode.javacv.cpp.opencv_objdetect;
import static com.googlecode.javacv.cpp.opencv_objdetect.CV_HAAR_DO_CANNY_PRUNING;
import com.googlecode.javacv.cpp.opencv_objdetect.CvHaarClassifierCascade;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
public class LBPFaceRecognizer {
private static String faceDataFolder = "F:\\FaceID\\ID\\";
public static String imageDataFolder = faceDataFolder + "images\\";
private static final String CASCADE_FILE = "C:\\Users\\chatur\\Documents\\NetBeansProjects\\NetbeansWorkspace\\DemoFaceRecognize-master\\haarcascade_frontalface_default.xml";
public static final String personNameMappingFileName = faceDataFolder + "personNumberMap.properties";
static final CvHaarClassifierCascade cascade = new CvHaarClassifierCascade(cvLoad(CASCADE_FILE));
private static LBPFaceRecognizer instance = new LBPFaceRecognizer();
Properties dataMap = new Properties();
private static final int NUM_IMAGES_PER_PERSON =10;
double binaryTreshold = 100;
int highConfidenceLevel = 70;
private FaceRecognizer fr_binary = null;
private LBPFaceRecognizer() {
if(cascade!=null)
{System.out.println(cascade+"\t"+CASCADE_FILE);}
createModels();
loadTrainingData();
}
public static LBPFaceRecognizer getInstance() {
return instance;
}
private void createModels() {
fr_binary = createLBPHFaceRecognizer(1, 8, 8, 8, binaryTreshold);
}
protected CvSeq detectFace(IplImage originalImage) {
System.out.println("in detection");
CvSeq faces = null;
Loader.load(opencv_objdetect.class);
try {
IplImage grayImage = IplImage.create(originalImage.width(), originalImage.height(), IPL_DEPTH_8U, 1);
cvCvtColor(originalImage, grayImage, CV_BGR2GRAY);
CvMemStorage storage = CvMemStorage.create();
faces = cvHaarDetectObjects(grayImage, cascade, storage, 1.1,3,CV_HAAR_DO_CANNY_PRUNING);
for(int i=0;i<faces.total();i++){
CvRect r=new CvRect(cvGetSeqElem(faces,i));
cvRectangle(originalImage, cvPoint(r.x(),r.y()),cvPoint(r.x()+r.width(),r.y()+r.height()),CvScalar.YELLOW,1,CV_AA,0);;
}
} catch (Exception e) {
e.printStackTrace();
}
return faces;
}
public String identifyFace(IplImage image) {
System.err.println("==========================================================");
String personName = "";
Set keys = dataMap.keySet();
if (keys.size() > 0) {
int[] ids = new int[1];
double[] distance = new double[1];
int result = -1;
fr_binary.predict(image, ids, distance);
//just deriving a confidence number against treshold
result = ids[0];
if (result > -1 && distance[0]<highConfidenceLevel) {
personName = (String) dataMap.get("" + result);
}
}
return personName;
}
public boolean learnNewFace(String personName, IplImage[] images) throws Exception
{
System.out.println("in learn new face");
int memberCounter = dataMap.size();
System.out.println(memberCounter);
if(dataMap.containsValue(personName)){
Set keys = dataMap.keySet();
Iterator ite = keys.iterator();
while (ite.hasNext()) {
String personKeyForTraining = (String) ite.next();
String personNameForTraining = (String) dataMap.getProperty(personKeyForTraining);
if(personNameForTraining.equals(personName)){
memberCounter = Integer.parseInt(personKeyForTraining);
System.out.println(memberCounter);
System.err.println("Person already exist.. re-learning..");
}
}
}
dataMap.put("" + memberCounter, personName);
storeTrainingImages(personName, images);
retrainAll();
return true;
}
public IplImage preprocessImage(IplImage image, CvRect r){
IplImage gray = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
IplImage roi = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
System.out.println("in preprocessing");
CvRect r1 = new CvRect(r.x()-10, r.y()-10, r.width()+10, r.height()+10);
cvCvtColor(image, gray, CV_BGR2GRAY);
cvSetImageROI(gray, r1);
cvResize(gray, roi, CV_INTER_LINEAR);
cvEqualizeHist(roi, roi);
return roi;
}
private void retrainAll() throws Exception {
System.out.println("in retrainAll");
Set keys = dataMap.keySet();
if (keys.size() > 0) {
MatVector trainImages = new MatVector(keys.size() * NUM_IMAGES_PER_PERSON);
CvMat trainLabels = CvMat.create(keys.size() * NUM_IMAGES_PER_PERSON, 1, CV_32SC1);
Iterator ite = keys.iterator();
int count = 0;
System.err.print("Loading images for training...");
while (ite.hasNext()) {
String personKeyForTraining = (String) ite.next();
String personNameForTraining = (String) dataMap.getProperty(personKeyForTraining);
IplImage imagesForTraining[]=new IplImage[NUM_IMAGES_PER_PERSON];
imagesForTraining = readImages(personNameForTraining);
System.out.println("length\t"+imagesForTraining.length+"\t"+personNameForTraining);
IplImage grayImage[]=new IplImage[NUM_IMAGES_PER_PERSON];
for(int j=0;j<imagesForTraining.length;j++){
grayImage[j] = IplImage.create(imagesForTraining[j].width(), imagesForTraining[j].height(), IPL_DEPTH_8U, 1);
}
for (int i = 0; i < imagesForTraining.length; i++) {
trainLabels.put(count, 0, Integer.parseInt(personKeyForTraining));
cvCvtColor(imagesForTraining[i], grayImage[i], CV_BGR2GRAY);
trainImages.put(count,grayImage[i]);
count++;
}
}
System.err.println("done.");
fr_binary.train(trainImages, trainLabels);
System.err.println("done.");
storeTrainingData();
}
}
private void loadTrainingData() {
try {
File personNameMapFile = new File(personNameMappingFileName);
if (personNameMapFile.exists()) {
System.out.print("in if ");
FileInputStream fis = new FileInputStream(personNameMapFile);
dataMap.load(fis);
System.out.println("datdataMap"+dataMap);
fis.close();
dataMap.list(System.out);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void storeTrainingData() throws Exception {
System.err.print("Storing training models ....");
File personNameMapFile = new File("personNameMappingFileName");
if (personNameMapFile.exists()) {
personNameMapFile.delete();
}
FileOutputStream fos = new FileOutputStream(personNameMapFile, false);
dataMap.store(fos, "");
fos.close();
System.err.println("done.");
}
public void storeTrainingImages(String personName, IplImage[] images) {
System.out.println("in store");
for (int i = 0; i < images.length; i++) {
String imageFileName = imageDataFolder + "training\\" + personName + "_" + i + ".bmp";
File imgFile = new File(imageFileName);
if (imgFile.exists()) {
imgFile.delete();
}
cvSaveImage(imageFileName, images[i]);
}
System.out.println("exit store");
}
private IplImage[] readImages(String personName) {
File imgFolder = new File(imageDataFolder);
IplImage[] images = null;
if (imgFolder.isDirectory() && imgFolder.exists()) {
images = new IplImage[NUM_IMAGES_PER_PERSON];
for (int i = 0; i < NUM_IMAGES_PER_PERSON; i++) {
String imageFileName = imageDataFolder + "training\\" + personName + "_" + i + ".bmp";
IplImage img = cvLoadImage(imageFileName);
images[i] = img;
}
}
return images;
}
public static void main(String ar[]) throws FrameGrabber.Exception, Exception{
try{
//LBPFaceRecognizer fr=new LBPFaceRecognizer();
//fr.getInstance();
LBPFaceRecognizer fr = LBPFaceRecognizer.getInstance();
FrameGrabber grabber = new OpenCVFrameGrabber(0);
grabber.start();
IplImage img=null;
CvSeq faces=null;
CvRect r=null;
CanvasFrame canvas=new CanvasFrame("webcam");
canvas.setDefaultCloseOperation(EXIT_ON_CLOSE);
canvas.setSize(750,750);
boolean flag=true;
while(flag){
img = grabber.grab();
IplImage snapshot = cvCreateImage(cvGetSize(img), img.depth(), img.nChannels());
cvFlip(img, snapshot, 1);
faces = fr.detectFace(img);
if(img!=null){
canvas.showImage(img);
}
r=new CvRect(cvGetSeqElem(faces,0));
int imageCounter = 0;
IplImage trainImages[]= new IplImage[1];
trainImages[0]= fr.preprocessImage(img, r);
fr.learnNewFace("p", trainImages);
fr.identifyFace(fr.preprocessImage(img, r));
}
}
catch(ExceptionInInitializerError e)
{
System.out.println(e);
}
}
}
以上代码用于人脸识别。它会检测面部,但在训练时它会抛出异常。问题是它在retrainAll()方法中抛出了一个名为“java.lang.NullPointerException”的异常。 在声明中
grayImage[j] = IplImage.create(imagesForTraining[j].width(), imagesForTraining[j].height(), IPL_DEPTH_8U, 1);
请帮助解决这个问题。
答案 0 :(得分:0)
IplImage img = cvLoadImage(imageFileName);
该东西可以返回null。所以你的imagesForTraining[j]
之一是空的。
这导致了问题。
如果您将代码更改为:
int width = imagesForTraining[j].width();
int height = imagesForTraining[j].height();
grayImage[j] = IplImage.create(width, height, IPL_DEPTH_8U, 1);
将在这3行中的第一行抛出异常。 您应该考虑场景以及未加载图像的位置并实现它。简单的实现类似于:
if(imagesForTraining[j] == null)continue;//or do something, try to load again
int width = imagesForTraining[j].width();
int height = imagesForTraining[j].height();
grayImage[j] = IplImage.create(width, height, IPL_DEPTH_8U, 1);