開源人臉識別seetaface入門教程(一)
簡述
seetaface由中科院計算所山世光研究員帶領(lǐng)的人臉識別研究組研發(fā)。代碼基于C++實現(xiàn),不依賴第三方庫。然而,目前開源的代碼,是在windows vs上編譯的,對于我們這幫mac/linux用戶來說,用起來還是挺麻煩的。經(jīng)過這幾天的學習,對seetaface總算有了全面的了解。下面,聽我娓娓道來。
注意:本文章不涉及代碼邏輯和原理,只是教大家如何使用seetaface做人臉識別。
引擎
FaceDetection
- 人臉識別模塊,用于識別出照片中的人臉,染回每個人臉的坐標和人臉總數(shù)。
FaceAlignment
- 特征點識別模塊,主要識別兩個嘴角、鼻子、兩個眼睛五個點的坐標。測試下來,發(fā)現(xiàn)圖片模糊時,識別不準。
FaceIdentification
- 人臉比較模塊,根據(jù)官方的說法,先提取特征值,然后比較。給出的測試程序是seetaface提取人臉的特征值和caffe訓練庫里的人臉做對比。
以下教程都是在MacOSX編譯運行通過。使用cmake和make編譯
以下的編譯方法是把FaceDetect測試程序也編譯了,而測試程序是依賴opencv的,所以,在這之前,確認opencv是否安裝
人臉識別教程
編譯
由于代碼是在windows平臺編譯的,所以,這地方要做些修改。
- 進入FaceDetection目錄
- 修改include/common.h,修改38行
- #ifdef SEETA_EXPORTS
- #define SEETA_API __declspec(dllexport)
- #else
- #define SEETA_API __declspec(dllimport)
- #endif
為
- #if defined _WIN32
- #ifdef SEETA_EXPORTS
- #define SEETA_API __declspec(dllexport)
- #else
- #define SEETA_API __declspec(dllimport)
- #endif
- #else
- #define SEETA_API
- #endif
- 修改include/feat/surf_feature_map.h文件,在前面加上#include <cstring>
- 修改include/util/image_pyramid.h文件,在前面加上#include <cstring>
- 修改src/feat/surf_feature_map.cpp文件,在前面加上#include <cmath>
- 增加CMakeLists.txt,內(nèi)容如下:
- cmake_minimum_required(VERSION 3.3)
- project(seeta_facedet_lib)
- option(BUILD_EXAMPLES "Set to ON to build examples" ON)
- option(USE_OPENMP "Set to ON to build use openmp" ON)
- set(CMAKE_CXX_STANDARD 11)
- set(CMAKE_CXX_STANDARD_REQUIRED ON)
- message(STATUS "C++11 support has been enabled by default.")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
- if (USE_OPENMP)
- find_package(OpenMP QUIET)
- if (OpenMP_FOUND)
- message(STATUS "Use OpenMP")
- add_definitions(-DUSE_OPENMP)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
- endif()
- endif()
- include_directories(include)
- set(src_files
- src/util/nms.cpp
- src/util/image_pyramid.cpp
- src/io/lab_boost_model_reader.cpp
- src/io/surf_mlp_model_reader.cpp
- src/feat/lab_feature_map.cpp
- src/feat/surf_feature_map.cpp
- src/classifier/lab_boosted_classifier.cpp
- src/classifier/mlp.cpp
- src/classifier/surf_mlp.cpp
- src/face_detection.cpp
- src/fust.cpp
- )
- add_library(face_detect SHARED ${src_files})
- set(facedet_required_libs face_detect)
- if (BUILD_EXAMPLES)
- message(STATUS "Build with examples.")
- find_package(OpenCV)
- if (NOT OpenCV_FOUND)
- message(WARNING "OpenCV not found. Test will not be built.")
- else()
- include_directories(${OpenCV_INCLUDE_DIRS})
- list(APPEND facedet_required_libs ${OpenCV_LIBS})
- add_executable(facedet_test src/test/facedetection_test.cpp)
- target_link_libraries(facedet_test ${facedet_required_libs})
- endif()
- endif()
- 建立build目錄,mkdir build
- 編譯,cd build && cmake .. && make
- 當前目錄下生成可執(zhí)行文件
運行
- 執(zhí)行完make命令以后,當前的目錄下會生成一個可執(zhí)行文件facedet_test
- 由于默認的程序讀取的是當前路徑下的test_image.jpg和seeta_fd_frontal_v1.0.bin,test_image.jpg是人臉圖片,seeta_fd_frontal_v1.0是識別的引擎。
- 確保以上的兩個文件在當前路徑下存在了,既可以./facedet_test運行了。
- 你可以修改位于src/test目錄下的文件,來達到自己的目的。
使用
我們可以參考src/test/facedetection_test.cpp這個測試程序,來達到我們?nèi)四樧R別的目的。
頭文件
- #include "opencv2/highgui/highgui.hpp"
- #include "opencv2/imgproc/imgproc.hpp"
- #include "face_detection.h"
- opencv頭文件主要用來加載圖像,face_detection.h是人臉識別的主要程序。
加載人臉識別引擎
- seeta::FaceDetection detector(‘seeta_fd_frontal_v1.0’);
設(shè)置最小人臉大小
- detector.SetMinFaceSize(40);
- 這個根據(jù)實際情況調(diào)整,圖片中,人臉越大,這個值也越大,因為這個值越小,人臉識別速度越慢。
識別圖片中的人臉
- std::vector<seeta::FaceInfo> faces = detector.Detect(img_data);
在這之前,需要對圖片進行處理,這里略過
輸出人臉識別的結(jié)果
- for (int32_t i = 0; i < num_face; i++) {
- face_rect.x = faces[i].bbox.x;
- face_rect.y = faces[i].bbox.y;
- face_rect.width = faces[i].bbox.width;
- face_rect.height = faces[i].bbox.height;
- cv::rectangle(img, face_rect, CV_RGB(0, 0, 255), 4, 8, 0);
- }
- s[i].bbox.x; faces[i].bbox.y;是人臉的左上角坐標。faces[i].bbox.width;faces[i].bbox.height;是人臉的長和寬。
結(jié)語
seetaface的確是個很好用的人臉識別庫,調(diào)用、編譯都很簡單,但是由于文檔的缺少,所以剛開始看的時候,會比較亂,不知道如何下手。本片文章主要介紹了FaceDetect的使用,接下來我會講解如何識別人臉的特征點,也就是嘴、鼻子、眼。敬請期待。