2017-10-18 9 views
1

J'essaie de former prédicteur de forme et face à un problème que la fonction add_overlay est nécessaire 5 sur 68 points. Alors, comment puis-je ajouter une superposition avec 46 points? Voici le code, il est presque le même que le example dans les docs.Comment ajouter une superposition avec un nombre de points désiré?

#!/usr/bin/python 
import os 
import sys 
import glob 

import dlib 
from skimage import io 



if len(sys.argv) != 2: 
    print(
     "Give the path to the examples/faces directory as the argument to this " 
     "program. For example, if you are in the python_examples folder then " 
     "execute this program by running:\n" 
     " ./train_shape_predictor.py ../examples/faces") 
    exit() 
faces_folder = sys.argv[1] 

options = dlib.shape_predictor_training_options() 

options.oversampling_amount = 500 

options.tree_depth = 2 
options.be_verbose = True 

training_xml_path = os.path.join(faces_folder, "women_test.xml") 
dlib.train_shape_predictor(training_xml_path, "predictor.dat", options) 

print("\nTraining accuracy: {}".format(
    dlib.test_shape_predictor(training_xml_path, "predictor.dat"))) 

predictor = dlib.shape_predictor("predictor.dat") 
detector = dlib.simple_object_detector("detector.svm") 


print("Showing detections and predictions on the images in the objects folder...") 
win = dlib.image_window() 
for f in glob.glob(os.path.join(faces_folder, "*.jpg")): 
    print("Processing file: {}".format(f)) 
    img = io.imread(f) 

    win.clear_overlay() 
    win.set_image(img) 

    dets = detector(img, 1) 
    print("Number of faces detected: {}".format(len(dets))) 
    for k, d in enumerate(dets): 
     print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(
      k, d.left(), d.top(), d.right(), d.bottom())) 
     shape = predictor(img, d) 
     print("Part 0: {}, Part 1: {} ...".format(shape.part(0), 
                shape.part(1))) 
     win.add_overlay(shape) 

    win.add_overlay(dets) 
    dlib.hit_enter_to_continue() 

journal de sortie:

Training with cascade depth: 10 
Training with tree depth: 2 
Training with 500 trees per cascade level. 
Training with nu: 0.05 
Training with random seed: 
Training with oversampling amount: 500 
Training with feature pool size: 400 
Training with feature pool region padding: 0 
Training with lambda_param: 0.1 
Training with 20 split tests. 
Fitting trees... 
Training complete       
Training complete, saved predictor to file predictor.dat 

Training accuracy: 0.0 
Showing detections and predictions on the images in the faces folder... 
Processing file: img/women/women5.jpg 
Number of faces detected: 1 
Detection 0: Left: 290 Top: 498 Right: 646 Bottom: 676 
Part 0: (317, 564), Part 1: (319, 582) ... 
Traceback (most recent call last): 
    File "train_shape_detector.py", line 131, in <module> 
    win.add_overlay(shape) 
RuntimeError: 

Error detected at line 25. 
Error detected in file /tmp/pip-build-867r6kjx/dlib/dlib/../dlib/image_processing/render_face_detections.h. 
Error detected in function std::vector<dlib::image_display::overlay_line> dlib::render_face_detections(const std::vector<dlib::full_object_detection>&, dlib::rgb_pixel). 

Failing expression was dets[i].num_parts() == 68 || dets[i].num_parts() == 5. 
    std::vector<image_window::overlay_line> render_face_detections() 
    You have to give either a 5 point or 68 point face landmarking output to this function. 
    dets[0].num_parts(): 46 
+0

Pour contourner ce problème, j'utilise cv2 pour placer les cercles sur les coordonnées des points. – kozlone

Répondre

2

Vous utilisez la fenêtre de Dlib qui a un chèque pour le nombre de points détectés être 5 ou 68.

Dans votre cas, vous avez 46 points. Vous auriez besoin d'afficher l'image sur la fenêtre cv2.

def annotate_landmarks(image, landmarks): 
""" 
Given image and a set of landmark points, annotates the points for viewing 
:param image: Input image 
:type image: np.array 
:param landmarks: set of facial landmark points 
:type landmarks: [(float, float)] 
:return: Resulting annotated image 
:rtype: np.array 
""" 
image = image.copy() 
for idx, point in enumerate(landmarks): 
    pos = (point[0, 0], point[0, 1]) 
    cv2.putText(image, str(idx), pos, 
       fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, 
       fontScale=0.4, 
       color=(0, 0, 255)) 
    cv2.circle(image, pos, 3, color=(0, 255, 255)) 
return image 

Utilisez maintenant la fonction annoter pour afficher les résultats.

new_img = img 
for k, d in enumerate(dets): 
    shape = predictor(new_img, d) 
    new_img = annotate_landmarks(new_img, shape) 

cv2.imshow(new_image) 
cv2.waitkey() 

Remarque: Cette fonction peut maintenant être directement connectée à vos besoins. Vérifiez le type de shape passant dans annotate_landmarks fonction

+0

Oui, je l'ai. Je pensais juste qu'il y a un moyen d'afficher les points avec dlib. J'ai résolu avec succès avec cv2, déjà. Merci. – kozlone