2017-10-18 10 views
1

모양 예측자를 훈련하려고하는데 add_overlay 함수가 필요하다는 문제에 직면했습니다. 68 점 중 5 점입니다. 그렇다면 46 점의 오버레이를 어떻게 추가 할 수 있습니까? 여기 코드입니다. 문서의 example과 거의 같습니다.원하는 수의 오버레이를 추가하는 방법은 무엇입니까?

#!/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() 

출력 로그 : 귀하의 경우 중 5 또는 68

될 감지 점의 수에 대한 검사가 있습니다 dlib 창을 사용하는

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

해결 방법은 cv2를 사용하여 점 좌표에 원을 배치하는 것입니다. – kozlone

답변

2

당신이 46 포인트를 가지고있다. 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 

이제 주석 기능을 사용하여 결과를 표시하십시오.

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() 

참고 : 이제이 기능이 요구 사항에 직접 연결될 수 있습니다. shape의 유형을 확인하십시오. annotate_landmarks 함수

+0

예, 있습니다. 방금 dlib로 포인트를 표시하는 방법이 있다고 생각했습니다. 나는 cv2로 이것을 성공적으로 해결했다. 감사. – kozlone