From b8f1837335638b5c5abcae46691c8164e4c5c000 Mon Sep 17 00:00:00 2001 From: goodspb Date: Thu, 24 May 2018 00:56:50 +0800 Subject: [PATCH] feat: add face_landmark_detection --- config.m4 | 3 +- pdlib.cc | 2 ++ src/face_landmark_detection.cc | 63 ++++++++++++++++++++++++++++++++++ src/face_landmark_detection.h | 14 ++++++++ 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/face_landmark_detection.cc create mode 100644 src/face_landmark_detection.h diff --git a/config.m4 b/config.m4 index b238017..a4e692e 100644 --- a/config.m4 +++ b/config.m4 @@ -25,7 +25,8 @@ if test "$PHP_PDLIB" != "no"; then PHP_SUBST(PDLIB_SHARED_LIBADD) pdlib_src_files="pdlib.cc \ - src/face_detection.cc" + src/face_detection.cc \ + src/face_landmark_detection.cc" AC_MSG_CHECKING(for pkg-config) if test ! -f "$PKG_CONFIG"; then diff --git a/pdlib.cc b/pdlib.cc index 6166542..b923421 100644 --- a/pdlib.cc +++ b/pdlib.cc @@ -29,6 +29,7 @@ extern "C" { } #include "php_pdlib.h" #include "src/face_detection.h" +#include "src/face_landmark_detection.h" /* If you declare any globals in php_pdlib.h uncomment this: ZEND_DECLARE_MODULE_GLOBALS(pdlib) @@ -151,6 +152,7 @@ PHP_MINFO_FUNCTION(pdlib) const zend_function_entry pdlib_functions[] = { PHP_FE(confirm_pdlib_compiled, NULL) PHP_FE(dlib_face_detection, dlib_face_detection_arginfo) + PHP_FE(dlib_face_landmark_detection, dlib_face_landmark_detection_arginfo) PHP_FE_END /* Must be the last line in pdlib_functions[] */ }; /* }}} */ diff --git a/src/face_landmark_detection.cc b/src/face_landmark_detection.cc new file mode 100644 index 0000000..25e85fe --- /dev/null +++ b/src/face_landmark_detection.cc @@ -0,0 +1,63 @@ + +#include "../php_pdlib.h" +#include "face_landmark_detection.h" + +#include +#include +#include +#include +#include + +#define ARRAY_NAME_WITH_INDEX(name, index) name##index + +using namespace dlib; +using namespace std; + +PHP_FUNCTION(dlib_face_landmark_detection) +{ + char *shape_predictor_file_path; + char *img_path; + size_t shape_predictor_file_path_len, img_path_len; + + if(zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &shape_predictor_file_path, &shape_predictor_file_path_len, + &img_path, &img_path_len) == FAILURE){ + RETURN_FALSE; + } + zval return_val; + array_init(&return_val); + + try { + frontal_face_detector detector = get_frontal_face_detector(); + shape_predictor sp; + deserialize(shape_predictor_file_path) >> sp; + + array2d img; + load_image(img, img_path); + pyramid_up(img); + + std::vector dets = detector(img); + + std::vector shapes; + for (unsigned long j = 0; j < dets.size(); ++j) + { + full_object_detection shape = sp(img, dets[j]); + + zval ARRAY_NAME_WITH_INDEX(face, j); + array_init(&ARRAY_NAME_WITH_INDEX(face, j)); + for (int k = 0; k < shape.num_parts(); k++) { + zval ARRAY_NAME_WITH_INDEX(part, k); + array_init(&ARRAY_NAME_WITH_INDEX(part, k)); + dlib::point p = shape.part(k); + add_next_index_long(&ARRAY_NAME_WITH_INDEX(part, k),p.x()); + add_next_index_long(&ARRAY_NAME_WITH_INDEX(part, k),p.y()); + add_next_index_zval(&ARRAY_NAME_WITH_INDEX(face, j), &ARRAY_NAME_WITH_INDEX(part, k)); + } + add_next_index_zval(&return_val, &ARRAY_NAME_WITH_INDEX(face, j)); + } + RETURN_ZVAL(&return_val, 0, 0); + } + catch (exception& e) + { + RETURN_FALSE; + } +} \ No newline at end of file diff --git a/src/face_landmark_detection.h b/src/face_landmark_detection.h new file mode 100644 index 0000000..caff095 --- /dev/null +++ b/src/face_landmark_detection.h @@ -0,0 +1,14 @@ +// +// Created by goodspb on 2018/5/23. +// + +#ifndef PDLIB_FACE_LANDMARK_DETECTION_H +#define PDLIB_FACE_LANDMARK_DETECTION_H + +ZEND_BEGIN_ARG_INFO_EX(dlib_face_landmark_detection_arginfo, 0, 0, 1) +ZEND_ARG_INFO(0, shape_predictor_file_path) +ZEND_ARG_INFO(0, img_path) +ZEND_END_ARG_INFO() +PHP_FUNCTION(dlib_face_landmark_detection); + +#endif //PDLIB_FACE_LANDMARK_DETECTION_H