2016-06-20 47 views
14

Oggi inizio a testare il progetto che rileva un sorriso in Java e OpenCv. Per il riconoscimento del progetto volto e bocca usato haarcascade_frontalface_alt e haarcascade_mcs_mouth Ma non capisco perché in alcune ragioni il progetto rileva il naso come una bocca. Ho due metodi:Rilevamento di viso e bocca Java e haarcascade - bocca come il naso

private ArrayList<Mat> detectMouth(String filename) { 
    int i = 0; 
    ArrayList<Mat> mouths = new ArrayList<Mat>(); 
    // reading image in grayscale from the given path 
    image = Highgui.imread(filename, Highgui.CV_LOAD_IMAGE_GRAYSCALE); 
    MatOfRect faceDetections = new MatOfRect(); 
    // detecting face(s) on given image and saving them to MatofRect object 
    faceDetector.detectMultiScale(image, faceDetections); 
    System.out.println(String.format("Detected %s faces", faceDetections.toArray().length)); 
    MatOfRect mouthDetections = new MatOfRect(); 
    // detecting mouth(s) on given image and saving them to MatOfRect object 
    mouthDetector.detectMultiScale(image, mouthDetections); 
    System.out.println(String.format("Detected %s mouths", mouthDetections.toArray().length)); 
    for (Rect face : faceDetections.toArray()) { 
     Mat outFace = image.submat(face); 
     // saving cropped face to picture 
     Highgui.imwrite("face" + i + ".png", outFace); 
     for (Rect mouth : mouthDetections.toArray()) { 
      // trying to find right mouth 
      // if the mouth is in the lower 2/5 of the face 
      // and the lower edge of mouth is above of the face 
      // and the horizontal center of the mouth is the enter of the face 
      if (mouth.y > face.y + face.height * 3/5 && mouth.y + mouth.height < face.y + face.height 
        && Math.abs((mouth.x + mouth.width/2)) - (face.x + face.width/2) < face.width/10) { 
       Mat outMouth = image.submat(mouth); 
       // resizing mouth to the unified size of trainSize 
       Imgproc.resize(outMouth, outMouth, trainSize); 
       mouths.add(outMouth); 
       // saving mouth to picture 
       Highgui.imwrite("mouth" + i + ".png", outMouth); 
       i++; 
      } 
     } 
    } 
    return mouths; 
} 

e rilevare sorriso

private void detectSmile(ArrayList<Mat> mouths) { 
     trainSVM(); 
     CvSVMParams params = new CvSVMParams(); 
     // set linear kernel (no mapping, regression is done in the original feature space) 
     params.set_kernel_type(CvSVM.LINEAR); 
    // train SVM with images in trainingImages, labels in trainingLabels, given params with empty samples 
     clasificador = new CvSVM(trainingImages, trainingLabels, new Mat(), new Mat(), params); 
     // save generated SVM to file, so we can see what it generated 
     clasificador.save("svm.xml"); 
     // loading previously saved file 
     clasificador.load("svm.xml"); 
     // returnin, if there aren't any samples 
     if (mouths.isEmpty()) { 
      System.out.println("No mouth detected"); 
      return; 
     } 
     for (Mat mouth : mouths) { 
      Mat out = new Mat(); 
      // converting to 32 bit floating point in gray scale 
      mouth.convertTo(out, CvType.CV_32FC1); 
      if (clasificador.predict(out.reshape(1, 1)) == 1.0) { 
       System.out.println("Detected happy face"); 
      } else { 
       System.out.println("Detected not a happy face"); 
      } 
     } 
    } 

Esempi:

Per quella foto

enter image description here

rileva correttamente questa mounth:

enter image description here

ma in altra immagine viene rilevato

enter image description here

naso enter image description here

Qual è il problema secondo te?

risposta

10

Molto probabilmente rileva che l'immagine è sbagliata a causa della proporzione del viso (distanza troppo lunga da occhi a bocca rispetto alla distanza tra gli occhi). Il rilevamento della bocca e del naso mediante rilevatore haar non è molto stabile, quindi gli algoritmi di solito usano il modello geometrico del viso, per scegliere la migliore combinazione di caratteristiche per ogni caratteristica facciale. Alcune implementazioni possono anche provare a predire la posizione della bocca in base agli occhi, se non sono stati trovati candidati alla bocca.

Il rilevatore haar non è il più recente e più conosciuto in questo momento per il rilevamento delle funzioni. Prova ad usare le implementazioni del modello di parti deformabili. Prova questo, hanno codice matlab con efficienti funzioni ottimizzate in C++: https://www.ics.uci.edu/~xzhu/face/