2015-05-27 7 views
-2
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? Я попробовал его с другим дедектором, и там он работает ?! Я также рассмотрел некоторые другие вопросы для ответа, и я нашел одно решение, и я с ним работал, но он тоже не работал. Это мой первый опыт работы с Openimaj.OutOfMemoryError после Facededetion

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) 
+0

Возможный дубликат [Как обрабатывать OutOfMemoryError в Java?] (Http://stackoverflow.com/questions/511013/how-to-handle-outofmemoryerror-in-java) – mhlz

ответ

1

Причина, по которой вы получили отказ, связана с использованием алгоритма обработки изображений. Я не уверен, что openimaj использует, но есть две обходные возможности для этого:

  1. Увеличить размер кучи, так что ваше приложение имеет больше памяти для обработки изображений. См. How can I increase the JVM memory?

  2. Уменьшите размер изображения, чтобы ваше приложение использовало меньше памяти для обработки.

Основываясь на собственном опыте, с функцией распознавания лица на мобильных устройствах (ограниченный объем памяти, а), 940x720, кажется, более чем достаточно для обнаружения лица. Не изменяйте размер на 640x480 (или аналогичный), результаты не должны быть затронуты.

Помните, что вы можете скопировать исходное изображение, изменить его размер с любым соотношением сторон (например, 1.5), определить лицо на новом измененном изображении и вернуть исходное изображение с обнаруженными координатами лица, умноженными на ваше соотношение сторон.

+0

Большое спасибо, я использовал оба решения и он решил проблему. Но теперь я получаю исключение IndexOutOfBounds -1 в той же строке. – Simon

 Смежные вопросы

  • Нет связанных вопросов^_^