Facededetion后OutOfMemoryError
OutOfMemoryError after Facededetion
package facerec;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.openimaj.feature.DoubleFVComparison;
import org.openimaj.image.FImage;
import org.openimaj.image.MBFImage;
import org.openimaj.image.colour.RGBColour;
import org.openimaj.image.processing.face.alignment.RotateScaleAligner;
import org.openimaj.image.processing.face.detection.HaarCascadeDetector;
import org.openimaj.image.processing.face.detection.keypoints.FKEFaceDetector;
import org.openimaj.image.processing.face.detection.keypoints.KEDetectedFace;
import org.openimaj.image.processing.face.recognition.EigenFaceRecogniser;
import org.openimaj.image.processing.face.recognition.FaceRecognitionEngine;
import org.openimaj.image.typography.hershey.HersheyFont;
import org.openimaj.math.geometry.point.Point2d;
import org.openimaj.ml.annotation.Annotated;
import org.openimaj.ml.annotation.AnnotatedObject;
import org.openimaj.ml.annotation.ScoredAnnotation;
import org.openimaj.util.pair.IndependentPair;
import org.openimaj.video.VideoDisplay;
import org.openimaj.video.VideoDisplayListener;
import org.openimaj.video.capture.VideoCapture;
public class NewFaceRegister extends KeyAdapter implements VideoDisplayListener<MBFImage> {
private VideoCapture capture;
private VideoDisplay<MBFImage> videoFrame;
FKEFaceDetector faceDetector = new FKEFaceDetector(new HaarCascadeDetector());
private EigenFaceRecogniser<KEDetectedFace, String> recogniser = EigenFaceRecogniser.create(20, new RotateScaleAligner(), 1, DoubleFVComparison.CORRELATION, 0.9f);
FaceRecognitionEngine<KEDetectedFace, String> engine = FaceRecognitionEngine.create(faceDetector, recogniser);
Annotated<KEDetectedFace, String> faceobj;
private FImage currentFrame;
public NewFaceRegister() throws Exception {
capture = new VideoCapture(940, 720);
//engine = new CLMFaceTracker();
//engine.fpd = 120;
videoFrame = VideoDisplay.createVideoDisplay(capture);
videoFrame.addVideoListener(this);
SwingUtilities.getRoot(videoFrame.getScreen()).addKeyListener(this);
}
@Override
public synchronized void keyPressed(KeyEvent key) {
if (key.getKeyCode() == KeyEvent.VK_SPACE) {
this.videoFrame.togglePause();
} else if (key.getKeyChar() == 'c') {
// if (!this.videoFrame.isPaused())
// this.videoFrame.togglePause();
final String person = JOptionPane.showInputDialog(this.videoFrame.getScreen(), "Name der Person eingeben", "",
JOptionPane.QUESTION_MESSAGE);
final List<KEDetectedFace> faces = detectFaces();
if (faces.size() == 1) {
engine.train(faces.get(0), person);
//TODO Datenbankmethode aufrufen, welches das AnnotatedObject (faceObj) speichert.
} else {
System.out.println("Zu viele/wenige Gesichter im Bild");
}
//this.videoFrame.close();
} else
System.out.println("Wrong key");
}
private List<KEDetectedFace> detectFaces() {
return engine.getDetector().detectFaces(currentFrame);
}
@Override
public void afterUpdate(VideoDisplay<MBFImage> display) {
// do nothing
}
@Override
public synchronized void beforeUpdate(MBFImage frame) {
this.currentFrame = frame.flatten();
/*engine.track(frame);
engine.drawModel(frame, true, true, true, true, true);*/
final List<KEDetectedFace> faces = detectFaces();
for (KEDetectedFace face : faces) {
frame.drawShape(face.getBounds(), RGBColour.RED);
}
if (recogniser != null && recogniser.listPeople().size() >= 1) {
for (KEDetectedFace face : faces) {
List<IndependentPair<KEDetectedFace, ScoredAnnotation<String>>> name = engine.recogniseBest(face.getFacePatch());
if (name.size() > 0) {
final Point2d r = face.getBounds().getTopLeft();
frame.drawText(name.get(0).getSecondObject().toString(), r, HersheyFont.ROMAN_SIMPLEX, 15, RGBColour.GREEN);
}
}
}
}
public static void main(String[] args) throws Exception {
new NewFaceRegister();
}
}
为什么我会收到 OutOfMemoryError?我用另一个 Dedector 试过它,它有效吗?!我还查看了其他一些问题的答案,我找到了一个解决方案,我完全使用它,但它也没有用。
这是我第一次使用 Openimaj。
Exception in thread "Thread-4" java.lang.OutOfMemoryError: Java heap space
at no.uib.cipr.matrix.AbstractDenseMatrix.<init>(AbstractDenseMatrix.java:47)
at no.uib.cipr.matrix.DenseMatrix.<init>(DenseMatrix.java:167)
at no.uib.cipr.matrix.SVD.<init>(SVD.java:98)
at no.uib.cipr.matrix.SVD.<init>(SVD.java:75)
at no.uib.cipr.matrix.SVD.factorize(SVD.java:146)
at org.openimaj.math.matrix.ThinSingularValueDecomposition.<init>(ThinSingularValueDecomposition.java:84)
at org.openimaj.math.matrix.ThinSingularValueDecomposition.<init>(ThinSingularValueDecomposition.java:69)
at org.openimaj.math.matrix.algorithm.pca.ThinSvdPrincipalComponentAnalysis.learnBasisNorm(ThinSvdPrincipalComponentAnalysis.java:56)
at org.openimaj.math.matrix.algorithm.pca.PrincipalComponentAnalysis.learnBasis(PrincipalComponentAnalysis.java:183)
at org.openimaj.math.matrix.algorithm.pca.PrincipalComponentAnalysis.learnBasis(PrincipalComponentAnalysis.java:170)
at org.openimaj.ml.pca.FeatureVectorPCA.learnBasis(FeatureVectorPCA.java:113)
at org.openimaj.image.model.EigenImages.train(EigenImages.java:125)
at org.openimaj.image.processing.face.feature.EigenFaceFeature$Extractor.train(EigenFaceFeature.java:167)
at org.openimaj.image.processing.face.recognition.EigenFaceRecogniser.beforeBatchTrain(EigenFaceRecogniser.java:159)
at org.openimaj.image.processing.face.recognition.LazyFaceRecogniser.retrain(LazyFaceRecogniser.java:139)
at org.openimaj.image.processing.face.recognition.LazyFaceRecogniser.annotate(LazyFaceRecogniser.java:153)
at org.openimaj.image.processing.face.recognition.EigenFaceRecogniser.annotate(EigenFaceRecogniser.java:55)
at org.openimaj.image.processing.face.recognition.FaceRecogniser.annotateBest(FaceRecogniser.java:115)
at org.openimaj.image.processing.face.recognition.FaceRecognitionEngine.recogniseBest(FaceRecognitionEngine.java:260)
at facerec.NewFaceRegister.beforeUpdate(NewFaceRegister.java:97)
at facerec.NewFaceRegister.beforeUpdate(NewFaceRegister.java:1)
at org.openimaj.video.VideoDisplay.fireBeforeUpdate(VideoDisplay.java:785)
at org.openimaj.video.VideoDisplay.run(VideoDisplay.java:522)
at java.lang.Thread.run(Unknown Source)
你失败的原因是因为使用了图像处理算法。我不确定 openimaj
使用什么,但有两种解决方法:
增加堆大小,以便您的应用程序有更多内存可用于图像处理。参见 How can I increase the JVM memory?
减小图像大小,以便您的应用程序使用更少的内存进行处理。
根据我自己在移动设备上进行人脸检测的经验(内存有限),940x720 似乎对人脸检测来说绰绰有余。随意调整为 640x480(或类似),结果应该不会受到影响。
请记住,您可以复制初始图像,以任意纵横比 (i.g.1.5) 调整大小,在新调整大小的图像上检测人脸,return 初始图像检测到的人脸坐标乘以你的纵横比。
package facerec;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.openimaj.feature.DoubleFVComparison;
import org.openimaj.image.FImage;
import org.openimaj.image.MBFImage;
import org.openimaj.image.colour.RGBColour;
import org.openimaj.image.processing.face.alignment.RotateScaleAligner;
import org.openimaj.image.processing.face.detection.HaarCascadeDetector;
import org.openimaj.image.processing.face.detection.keypoints.FKEFaceDetector;
import org.openimaj.image.processing.face.detection.keypoints.KEDetectedFace;
import org.openimaj.image.processing.face.recognition.EigenFaceRecogniser;
import org.openimaj.image.processing.face.recognition.FaceRecognitionEngine;
import org.openimaj.image.typography.hershey.HersheyFont;
import org.openimaj.math.geometry.point.Point2d;
import org.openimaj.ml.annotation.Annotated;
import org.openimaj.ml.annotation.AnnotatedObject;
import org.openimaj.ml.annotation.ScoredAnnotation;
import org.openimaj.util.pair.IndependentPair;
import org.openimaj.video.VideoDisplay;
import org.openimaj.video.VideoDisplayListener;
import org.openimaj.video.capture.VideoCapture;
public class NewFaceRegister extends KeyAdapter implements VideoDisplayListener<MBFImage> {
private VideoCapture capture;
private VideoDisplay<MBFImage> videoFrame;
FKEFaceDetector faceDetector = new FKEFaceDetector(new HaarCascadeDetector());
private EigenFaceRecogniser<KEDetectedFace, String> recogniser = EigenFaceRecogniser.create(20, new RotateScaleAligner(), 1, DoubleFVComparison.CORRELATION, 0.9f);
FaceRecognitionEngine<KEDetectedFace, String> engine = FaceRecognitionEngine.create(faceDetector, recogniser);
Annotated<KEDetectedFace, String> faceobj;
private FImage currentFrame;
public NewFaceRegister() throws Exception {
capture = new VideoCapture(940, 720);
//engine = new CLMFaceTracker();
//engine.fpd = 120;
videoFrame = VideoDisplay.createVideoDisplay(capture);
videoFrame.addVideoListener(this);
SwingUtilities.getRoot(videoFrame.getScreen()).addKeyListener(this);
}
@Override
public synchronized void keyPressed(KeyEvent key) {
if (key.getKeyCode() == KeyEvent.VK_SPACE) {
this.videoFrame.togglePause();
} else if (key.getKeyChar() == 'c') {
// if (!this.videoFrame.isPaused())
// this.videoFrame.togglePause();
final String person = JOptionPane.showInputDialog(this.videoFrame.getScreen(), "Name der Person eingeben", "",
JOptionPane.QUESTION_MESSAGE);
final List<KEDetectedFace> faces = detectFaces();
if (faces.size() == 1) {
engine.train(faces.get(0), person);
//TODO Datenbankmethode aufrufen, welches das AnnotatedObject (faceObj) speichert.
} else {
System.out.println("Zu viele/wenige Gesichter im Bild");
}
//this.videoFrame.close();
} else
System.out.println("Wrong key");
}
private List<KEDetectedFace> detectFaces() {
return engine.getDetector().detectFaces(currentFrame);
}
@Override
public void afterUpdate(VideoDisplay<MBFImage> display) {
// do nothing
}
@Override
public synchronized void beforeUpdate(MBFImage frame) {
this.currentFrame = frame.flatten();
/*engine.track(frame);
engine.drawModel(frame, true, true, true, true, true);*/
final List<KEDetectedFace> faces = detectFaces();
for (KEDetectedFace face : faces) {
frame.drawShape(face.getBounds(), RGBColour.RED);
}
if (recogniser != null && recogniser.listPeople().size() >= 1) {
for (KEDetectedFace face : faces) {
List<IndependentPair<KEDetectedFace, ScoredAnnotation<String>>> name = engine.recogniseBest(face.getFacePatch());
if (name.size() > 0) {
final Point2d r = face.getBounds().getTopLeft();
frame.drawText(name.get(0).getSecondObject().toString(), r, HersheyFont.ROMAN_SIMPLEX, 15, RGBColour.GREEN);
}
}
}
}
public static void main(String[] args) throws Exception {
new NewFaceRegister();
}
}
为什么我会收到 OutOfMemoryError?我用另一个 Dedector 试过它,它有效吗?!我还查看了其他一些问题的答案,我找到了一个解决方案,我完全使用它,但它也没有用。 这是我第一次使用 Openimaj。
Exception in thread "Thread-4" java.lang.OutOfMemoryError: Java heap space
at no.uib.cipr.matrix.AbstractDenseMatrix.<init>(AbstractDenseMatrix.java:47)
at no.uib.cipr.matrix.DenseMatrix.<init>(DenseMatrix.java:167)
at no.uib.cipr.matrix.SVD.<init>(SVD.java:98)
at no.uib.cipr.matrix.SVD.<init>(SVD.java:75)
at no.uib.cipr.matrix.SVD.factorize(SVD.java:146)
at org.openimaj.math.matrix.ThinSingularValueDecomposition.<init>(ThinSingularValueDecomposition.java:84)
at org.openimaj.math.matrix.ThinSingularValueDecomposition.<init>(ThinSingularValueDecomposition.java:69)
at org.openimaj.math.matrix.algorithm.pca.ThinSvdPrincipalComponentAnalysis.learnBasisNorm(ThinSvdPrincipalComponentAnalysis.java:56)
at org.openimaj.math.matrix.algorithm.pca.PrincipalComponentAnalysis.learnBasis(PrincipalComponentAnalysis.java:183)
at org.openimaj.math.matrix.algorithm.pca.PrincipalComponentAnalysis.learnBasis(PrincipalComponentAnalysis.java:170)
at org.openimaj.ml.pca.FeatureVectorPCA.learnBasis(FeatureVectorPCA.java:113)
at org.openimaj.image.model.EigenImages.train(EigenImages.java:125)
at org.openimaj.image.processing.face.feature.EigenFaceFeature$Extractor.train(EigenFaceFeature.java:167)
at org.openimaj.image.processing.face.recognition.EigenFaceRecogniser.beforeBatchTrain(EigenFaceRecogniser.java:159)
at org.openimaj.image.processing.face.recognition.LazyFaceRecogniser.retrain(LazyFaceRecogniser.java:139)
at org.openimaj.image.processing.face.recognition.LazyFaceRecogniser.annotate(LazyFaceRecogniser.java:153)
at org.openimaj.image.processing.face.recognition.EigenFaceRecogniser.annotate(EigenFaceRecogniser.java:55)
at org.openimaj.image.processing.face.recognition.FaceRecogniser.annotateBest(FaceRecogniser.java:115)
at org.openimaj.image.processing.face.recognition.FaceRecognitionEngine.recogniseBest(FaceRecognitionEngine.java:260)
at facerec.NewFaceRegister.beforeUpdate(NewFaceRegister.java:97)
at facerec.NewFaceRegister.beforeUpdate(NewFaceRegister.java:1)
at org.openimaj.video.VideoDisplay.fireBeforeUpdate(VideoDisplay.java:785)
at org.openimaj.video.VideoDisplay.run(VideoDisplay.java:522)
at java.lang.Thread.run(Unknown Source)
你失败的原因是因为使用了图像处理算法。我不确定 openimaj
使用什么,但有两种解决方法:
增加堆大小,以便您的应用程序有更多内存可用于图像处理。参见 How can I increase the JVM memory?
减小图像大小,以便您的应用程序使用更少的内存进行处理。
根据我自己在移动设备上进行人脸检测的经验(内存有限),940x720 似乎对人脸检测来说绰绰有余。随意调整为 640x480(或类似),结果应该不会受到影响。
请记住,您可以复制初始图像,以任意纵横比 (i.g.1.5) 调整大小,在新调整大小的图像上检测人脸,return 初始图像检测到的人脸坐标乘以你的纵横比。