2016-06-20 21 views
14

Dzisiaj zaczynam testować projekt, który wykrywa uśmiech w Javie i OpenCv. Do rozpoznania projektu twarzy i ust używałem haarascade_frontalface_alt i haarcascade_mcs_mouth Ale nie rozumiem, dlaczego z jakichś powodów projekt wykrywa nos jako usta. Mam dwie metody:Wykrywanie twarzy i jamy Javy i haaraskady - usta jak nos

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; 
} 

i wykrywania uśmiechu

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"); 
      } 
     } 
    } 

Przykłady:

dla tego obrazu

enter image description here

poprawnie wykrywa ten mounth:

enter image description here

ale w innym obrazie

enter image description here

nos jest wykrywany enter image description here

czym problem w swojej opinii?

Odpowiedz

10

Najprawdopodobniej wykryje błąd na zdjęciu z powodu proporcji twarzy (zbyt duża odległość między oczami a ustami w porównaniu do odległości między oczami). Wykrywanie jamy ustnej i nosa za pomocą detektora haar nie jest bardzo stabilne, więc algorytmy zwykle używają modelu geometrii twarzy, aby wybrać najlepszą kombinację kandydatów na cechy dla każdej cechy twarzy. Niektóre implementacje mogą nawet próbować przewidzieć pozycję w jamie ustnej na podstawie oczu, jeśli nie znaleziono kandydatów do jamy ustnej.

Detektor Haar nie jest najnowszy i najbardziej znany w tym momencie do wykrywania cech. Spróbuj użyć odkształcalnych modeli części. Wypróbuj to, mają kod Matlab z wydajnymi funkcjami C++ zoptymalizowanymi: https://www.ics.uci.edu/~xzhu/face/