diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..f313000a7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,189 @@ +Makefile.Debug +Makefile.Release +*.bak +*~ +*.autosave +*.qm +*.user +.CCodec.h.kate-swp +.kdev4/ +.kdev_include_paths +build/ +build_android/ +build_unix_mingw/ +build_windows_mingw/ +build_unix/ +build_windows_msvc/ +*.ncb +.metadata/ +*~ +debug/ +bin/ +*.class +.deps/ +Makefile.in +aclocal.m4 +config.guess +config.h +config.h.in +config.h.in~ +config.log +config.status +config.sub +configure +depcomp +install-sh +libtool +ltmain.sh +missing +reachmonitor +stamp-h1 +.deps/ +Makefile.in +aclocal.m4 +config.guess +config.h +config.h.in +config.h.in~ +config.log +config.status +config.sub +configure +depcomp +install-sh +libtool +ltmain.sh +missing +stamp-h1 +*.bak +*.bs +*.la +*.lo +*.ft +*.ft.1 +*.made +*.o +*.obj +*.old +*.orig +*.out +*.pdb +*.rej +.libs/ +Makefile +*.cdf +*.cache +*.obj +*.ilk +*.resources +*.tlb +*.tli +*.tlh +*.tmp +*.rsp +*.pgc +*.pgd +*.meta +*.tlog +*.manifest +*.res +*.pch +*.exp +*.idb +*.rep +*.xdc +*.pdb +*_manifest.rc +*.bsc +*.sbr +*.opensdf +*.sdf +*.suo +Debug/ +release/ +Release/ +ipch/ +IncludeLocalDatabase.txt +ThirdLibrary/unix_mingw/ +ThirdLibrary/unix/ +ThirdLibrary/unix_static/ +ThirdLibrary/android/ +ThirdLibrary/android_static/ +ThirdLibrary/windows_msvc/ +ThirdLibrary/windows_mingw/ +ThirdLibrary/src/ +ThirdLibrary/windows_mingw_static/ +ThirdLibrary/windows_msvc_static/ +rabbitim.kdev4 +*.pro.user.* +Doxygen/ +Doxyfile +android/local.properties +android/gradle.properties +android/gradlew.* + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# Platform Specifics - auto generated files +PlatformSpecifics/Windows/*.rc + +# Visual studio - project files +*.sln +*.suo +*.vcxproj +*.vcxproj.filters +*.vcxproj.user + +# Visual Studio - Build Results +[Dd]ebug/ +[Rr]elease/ +[Mm]in[Ss]ize[Rr]el/ +[Rr]el[Ww]ith[Dd]eb[Ii]nfo/ + +# Visual Studio - Browsing Database File +*.sdf +*.opensdf + +#osx xcode +DerivedData/ +*.DS_Store +*.build +*.xcodeproj + +#CPACK related files +CPackConfig-*.cmake +_CPack_Packages/ + +#packages +*.tar.gz +*.zip + + +cmake_uninstall.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..5cb5467f3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 2.8.12) + +set (SEETAFACEENGINE_VERSION_MAJOR 4) +set (SEETAFACEENGINE_VERSION_MINOR 5) +set (SEETAFACEENGINE_VERSION_PATCH 0) + +# 建立要删除的文件 +CONFIGURE_FILE( + "${CMAKE_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${CMAKE_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) +# 建立删除目标 +ADD_CUSTOM_TARGET(uninstall + "${CMAKE_COMMAND}" -P "${CMAKE_BINARY_DIR}/cmake_uninstall.cmake") + +# 设置安装前缀 +IF(NOT CMAKE_INSTALL_PREFIX) + SET(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR}/${PROJECT_NAME} CACHE STRING "Install path prefix.") +ENDIF() + +# Find Git Version Patch +if(EXISTS "${CMAKE_SOURCE_DIR}/.git") + FIND_PROGRAM(GIT git) + IF(GIT) + EXECUTE_PROCESS( + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMAND ${GIT} rev-parse --short HEAD + OUTPUT_VARIABLE BUILD_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE + ) + MESSAGE("Git Version: ${BUILD_VERSION}\n") + ENDIF(GIT) +ENDIF() + +IF(MSVC) + # This option is to enable the /MP switch for Visual Studio 2005 and above compilers + OPTION(WIN32_USE_MP "Set to ON to build OpenSceneGraph with the /MP option (Visual Studio 2005 and above)." ON) + MARK_AS_ADVANCED(WIN32_USE_MP) + IF(WIN32_USE_MP) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") + ENDIF(WIN32_USE_MP) +ENDIF(MSVC) + +add_subdirectory(FaceDetection) +add_subdirectory(FaceAlignment) +add_subdirectory(FaceIdentification) + +# Install cmake files +configure_file(SeetaFaceEngineConfig.cmake.in ${CMAKE_BINARY_DIR}/SeetaFaceEngineConfig.cmake @ONLY) +install(FILES ${CMAKE_BINARY_DIR}/SeetaFaceEngineConfig.cmake DESTINATION .) \ No newline at end of file diff --git a/FaceAlignment/CMakeLists.txt b/FaceAlignment/CMakeLists.txt index ed878c8e7..ea9a03911 100644 --- a/FaceAlignment/CMakeLists.txt +++ b/FaceAlignment/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.4) project(seeta_fa_lib) # Build options -option(BUILD_EXAMPLES "Set to ON to build examples" ON) +option(BUILD_EXAMPLES "Set to ON to build examples" OFF) # Use C++11 #set(CMAKE_CXX_STANDARD 11) @@ -24,18 +24,36 @@ set(src_files ) add_library(seeta_fa_lib SHARED ${src_files}) -set(fa_required_libs seeta_fa_lib) + +# Install target +INSTALL(TARGETS ${PROJECT_NAME} + RUNTIME DESTINATION bin + LIBRARY DESTINATION "lib" + ARCHIVE DESTINATION "lib") +# Install head files +INSTALL(DIRECTORY include DESTINATION ".") +# Install model files +INSTALL(DIRECTORY model DESTINATION ".") 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} build) - link_directories(build) - list(APPEND fa_required_libs ${OpenCV_LIBS} seeta_facedet_lib) - add_executable(fa_test src/test/face_alignment_test.cpp) - target_link_libraries(fa_test ${fa_required_libs}) + message(FATAL_ERROR "OpenCV not found. Test will not be built.") endif() + + find_package(SeetaFaceEngine) + if(NOT SEETAFACEENGINE_FOUND) + message(FATAL_ERROR "Please set BUILD_EXAMPLES to OFF and isntall SeetaFaceEngine") + endif() + + include_directories(${OpenCV_INCLUDE_DIRS} ${SEETAFACEENGINE_INCLUDE_DIRS}) + add_executable(fa_test src/test/face_alignment_test.cpp) + target_link_libraries(fa_test ${OpenCV_LIBS} ${SEETAFACEENGINE_LIBRARIES}) + + # Install target + INSTALL(TARGETS fa_test RUNTIME DESTINATION bin) + # Install example data + INSTALL(DIRECTORY data DESTINATION ".") + endif() diff --git a/FaceAlignment/src/test/face_alignment_test.cpp b/FaceAlignment/src/test/face_alignment_test.cpp index 35df73a77..57ee6c07b 100644 --- a/FaceAlignment/src/test/face_alignment_test.cpp +++ b/FaceAlignment/src/test/face_alignment_test.cpp @@ -7,7 +7,7 @@ * face alignment method described in the following paper: * * - * Coarse-to-Fine Auto-Encoder Networks (CFAN) for Real-Time Face Alignment, + * Coarse-to-Fine Auto-Encoder Networks (CFAN) for Real-Time Face Alignment, * Jie Zhang, Shiguang Shan, Meina Kan, Xilin Chen. In Proceeding of the * European Conference on Computer Vision (ECCV), 2014 * @@ -34,87 +34,73 @@ #include #include -#include "cv.h" -#include "highgui.h" +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/imgproc/imgproc.hpp" #include "face_detection.h" #include "face_alignment.h" -#ifdef _WIN32 -std::string DATA_DIR = "../../data/"; -std::string MODEL_DIR = "../../model/"; -#else -std::string DATA_DIR = "./data/"; -std::string MODEL_DIR = "./model/"; -#endif - int main(int argc, char** argv) { - // Initialize face detection model - seeta::FaceDetection detector("../../../FaceDetection/model/seeta_fd_frontal_v1.0.bin"); - detector.SetMinFaceSize(40); - detector.SetScoreThresh(2.f); - detector.SetImagePyramidScaleFactor(0.8f); - detector.SetWindowStep(4, 4); + if (argc < 4) { + std::cout << "Usage: " << argv[0] + << " detection_model_path alignment_model_path image_path" + << std::endl; + return -1; + } + + // Initialize face detection model + seeta::FaceDetection detector(argv[1]); + detector.SetMinFaceSize(40); + detector.SetScoreThresh(2.f); + detector.SetImagePyramidScaleFactor(0.8f); + detector.SetWindowStep(4, 4); - // Initialize face alignment model - seeta::FaceAlignment point_detector((MODEL_DIR + "seeta_fa_v1.1.bin").c_str()); + // Initialize face alignment model + seeta::FaceAlignment point_detector(argv[2]); - //load image - IplImage *img_grayscale = NULL; - img_grayscale = cvLoadImage((DATA_DIR + "image_0001.png").c_str(), 0); - if (img_grayscale == NULL) - { - return 0; - } + //load image + cv::Mat img = cv::imread(argv[3], cv::IMREAD_UNCHANGED); + cv::Mat img_gray; - IplImage *img_color = cvLoadImage((DATA_DIR + "image_0001.png").c_str(), 1); - int pts_num = 5; - int im_width = img_grayscale->width; - int im_height = img_grayscale->height; - unsigned char* data = new unsigned char[im_width * im_height]; - unsigned char* data_ptr = data; - unsigned char* image_data_ptr = (unsigned char*)img_grayscale->imageData; - int h = 0; - for (h = 0; h < im_height; h++) { - memcpy(data_ptr, image_data_ptr, im_width); - data_ptr += im_width; - image_data_ptr += img_grayscale->widthStep; - } + if (img.channels() != 1) + cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY); + else + img_gray = img; - seeta::ImageData image_data; - image_data.data = data; - image_data.width = im_width; - image_data.height = im_height; - image_data.num_channels = 1; + seeta::ImageData img_data; + img_data.data = img_gray.data; + img_data.width = img_gray.cols; + img_data.height = img_gray.rows; + img_data.num_channels = 1; - // Detect faces - std::vector faces = detector.Detect(image_data); - int32_t face_num = static_cast(faces.size()); + // Detect faces + std::vector faces = detector.Detect(img_data); - if (face_num == 0) - { - delete[]data; - cvReleaseImage(&img_grayscale); - cvReleaseImage(&img_color); - return 0; - } + // Detect 5 facial landmarks + for (int i = 0; i < faces.size(); i++) + { + cv::Rect face_rect; + 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); - // Detect 5 facial landmarks - seeta::FacialLandmark points[5]; - point_detector.PointDetectLandmarks(image_data, faces[0], points); + // Visualize the results + seeta::FacialLandmark points[5]; + if (point_detector.PointDetectLandmarks(img_data, faces[0], points)) + { + for (int j = 0; j < 5; j++) + cv::circle(img, cv::Point(points[j].x, points[j].y), + 2, CV_RGB(0, 255, 0), CV_FILLED); + } + } - // Visualize the results - cvRectangle(img_color, cvPoint(faces[0].bbox.x, faces[0].bbox.y), cvPoint(faces[0].bbox.x + faces[0].bbox.width - 1, faces[0].bbox.y + faces[0].bbox.height - 1), CV_RGB(255, 0, 0)); - for (int i = 0; i faces = detector.Detect(img_data); - long t1 = cv::getTickCount(); - double secs = (t1 - t0)/cv::getTickFrequency(); - - cout << "Detections takes " << secs << " seconds " << endl; + if (argc < 3) { + cout << "Usage: " << argv[0] + << " model_path image_path" + << endl; + return -1; + } + + const char* img_path = argv[2]; + seeta::FaceDetection detector(argv[1]); + + detector.SetMinFaceSize(40); + detector.SetScoreThresh(2.f); + detector.SetImagePyramidScaleFactor(0.8f); + detector.SetWindowStep(4, 4); + + cv::Mat img = cv::imread(img_path, cv::IMREAD_UNCHANGED); + cv::Mat img_gray; + + if (img.channels() != 1) + cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY); + else + img_gray = img; + + seeta::ImageData img_data; + img_data.data = img_gray.data; + img_data.width = img_gray.cols; + img_data.height = img_gray.rows; + img_data.num_channels = 1; + + long t0 = cv::getTickCount(); + std::vector faces = detector.Detect(img_data); + long t1 = cv::getTickCount(); + double secs = (t1 - t0) / cv::getTickFrequency(); + + cout << "Detections takes " << secs << " seconds " << endl; #ifdef USE_OPENMP - cout << "OpenMP is used." << endl; + cout << "OpenMP is used." << endl; #else - cout << "OpenMP is not used. " << endl; + cout << "OpenMP is not used. " << endl; #endif #ifdef USE_SSE - cout << "SSE is used." << endl; + cout << "SSE is used." << endl; #else - cout << "SSE is not used." << endl; + cout << "SSE is not used." << endl; #endif - cout << "Image size (wxh): " << img_data.width << "x" - << img_data.height << endl; + cout << "Image size (wxh): " << img_data.width << "x" + << img_data.height << endl; - cv::Rect face_rect; - int32_t num_face = static_cast(faces.size()); + cv::Rect face_rect; + int32_t num_face = static_cast(faces.size()); - 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; + 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); - } + cv::rectangle(img, face_rect, CV_RGB(0, 0, 255), 4, 8, 0); + } - cv::namedWindow("Test", cv::WINDOW_AUTOSIZE); - cv::imshow("Test", img); - cv::waitKey(0); - cv::destroyAllWindows(); + cv::namedWindow("Test", cv::WINDOW_AUTOSIZE); + cv::imshow("Test", img); + cv::waitKey(0); + cv::destroyAllWindows(); } diff --git a/FaceIdentification/CMakeLists.txt b/FaceIdentification/CMakeLists.txt index 7c03b7c1e..f89921c7c 100644 --- a/FaceIdentification/CMakeLists.txt +++ b/FaceIdentification/CMakeLists.txt @@ -2,8 +2,8 @@ cmake_minimum_required (VERSION 2.6) project (viplnet) -set (VIPLNET_VERSION_MAJOR 4) -set (VIPLNET_VERSION_MINOR 5) +# Build options +option(BUILD_EXAMPLES "Set to ON to build examples" OFF) set(CMAKE_BUILD_TYPE "Release") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -std=c++11 -O2 -g -ggdb") @@ -16,19 +16,71 @@ if (CMAKE_SYSTEM_NAME MATCHES "Darwin") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DGTEST_USE_OWN_TR1_TUPLE=1") endif (CMAKE_SYSTEM_NAME MATCHES "Darwin") -set(VIPLNET_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include) -set(VIPLNET_SRC_DIR ${PROJECT_SOURCE_DIR}/src) -# set __VIOL_LOG__ macro -# add_definitions(-D__VIPL_LOG__) +include_directories(include) -include_directories(${VIPLNET_INCLUDE_DIR}) -include_directories(${VIPLNET_SRC_DIR}) +set(src_files + src/blob.cpp + src/bn_net.cpp + src/bias_adder_net.cpp + src/common_net.cpp + src/conv_net.cpp + src/eltwise_net.cpp + src/inner_product_net.cpp + src/log.cpp + src/math_functions.cpp + src/max_pooling_net.cpp + src/net.cpp + src/pad_net.cpp + src/spatial_transform_net.cpp + src/tform_maker_net.cpp + ) -add_subdirectory(src) +set(tools_files + tools/aligner.cpp + tools/face_identification.cpp + ) -aux_source_directory(./src SRC_LIST) -aux_source_directory(./tools TOOLS_LIST) -add_library(viplnet SHARED ${SRC_LIST} ${TOOLS_LIST}) +#aux_source_directory(./src src_files) +#aux_source_directory(./tools tools_files) + +add_library(viplnet SHARED ${src_files} ${tools_files}) set_target_properties(viplnet PROPERTIES VERSION ${VIPLNET_VERSION_MAJOR}.${VIPLNET_VERSION_MINOR} SOVERSION ${VIPLNET_VERSION_MAJOR}.${VIPLNET_VERSION_MINOR}) + +# Install target +INSTALL(TARGETS ${PROJECT_NAME} + RUNTIME DESTINATION bin + LIBRARY DESTINATION "lib" + ARCHIVE DESTINATION "lib") +# Install head files +INSTALL(DIRECTORY include DESTINATION ".") +# Install model files +INSTALL(DIRECTORY model DESTINATION ".") + +if (BUILD_EXAMPLES) + message(STATUS "Build with examples.") + find_package(OpenCV) + if (NOT OpenCV_FOUND) + message(FATAL_ERROR "OpenCV not found. Test will not be built.") + endif() + + find_package(SeetaFaceEngine) + if(NOT SEETAFACEENGINE_FOUND) + message(FATAL_ERROR "Please set BUILD_EXAMPLES to OFF and isntall SeetaFaceEngine") + endif() + + include_directories(${OpenCV_INCLUDE_DIRS} ${SEETAFACEENGINE_INCLUDE_DIRS}) + list(APPEND viplnet_required_libs ${OpenCV_LIBS} ${SEETAFACEENGINE_LIBRARIES}) + + add_executable(test_face_recognizer src/test/test_face_recognizer.cpp) + target_link_libraries(test_face_recognizer ${viplnet_required_libs}) + + add_executable(test_face_verification src/test/test_face_verification.cpp) + target_link_libraries(test_face_verification ${viplnet_required_libs}) + + # Install target + INSTALL(TARGETS test_face_recognizer test_face_verification RUNTIME DESTINATION bin) + # Install example data + INSTALL(DIRECTORY data DESTINATION ".") +endif() \ No newline at end of file diff --git a/FaceIdentification/src/CMakeLists.txt b/FaceIdentification/src/CMakeLists.txt deleted file mode 100644 index ac25ae7a5..000000000 --- a/FaceIdentification/src/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -set(VIPLNET_TEST_DIR ${PROJECT_SRC_DIR}/test) -add_subdirectory(test) diff --git a/FaceIdentification/src/test/CMakeLists.txt b/FaceIdentification/src/test/CMakeLists.txt deleted file mode 100644 index c1170904c..000000000 --- a/FaceIdentification/src/test/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -aux_source_directory (. SRC_LIST) - -message(${SRC_LIST}) - -# add external libraries -find_package(OpenCV REQUIRED) - -enable_testing () -foreach (f ${SRC_LIST}) - string(REGEX REPLACE "[.]cpp" ".bin" BIN ${f}) - add_executable(${BIN} ${f}) - target_link_libraries(${BIN} viplnet ${OpenCV_LIBS}) -endforeach () - diff --git a/FaceIdentification/src/test/test_face_recognizer.cpp b/FaceIdentification/src/test/test_face_recognizer.cpp index cc288692e..0cc70de4d 100644 --- a/FaceIdentification/src/test/test_face_recognizer.cpp +++ b/FaceIdentification/src/test/test_face_recognizer.cpp @@ -6,7 +6,7 @@ * This file is part of the SeetaFace Identification module, containing codes implementing the * face identification method described in the following paper: * - * + * * VIPLFaceNet: An Open Source Deep Face Recognition SDK, * Xin Liu, Meina Kan, Wanglong Wu, Shiguang Shan, Xilin Chen. * In Frontiers of Computer Science. @@ -23,34 +23,15 @@ * You should have received a copy of the BSD 2-Clause License along with the software. * If not, see < https://opensource.org/licenses/BSD-2-Clause>. * - * Contact Info: you can send an email to SeetaFace@vipl.ict.ac.cn for any problems. + * Contact Info: you can send an email to SeetaFace@vipl.ict.ac.cn for any problems. * * Note: the above information must be kept whenever or wherever the codes are used. * */ - +#pragma once #include using namespace std; -#ifdef _WIN32 -#pragma once -#include - -#define CV_VERSION_ID CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) \ - CVAUX_STR(CV_SUBMINOR_VERSION) - -#ifdef _DEBUG -#define cvLIB(name) "opencv_" name CV_VERSION_ID "d" -#else -#define cvLIB(name) "opencv_" name CV_VERSION_ID -#endif //_DEBUG - -#pragma comment( lib, cvLIB("core") ) -#pragma comment( lib, cvLIB("imgproc") ) -#pragma comment( lib, cvLIB("highgui") ) - -#endif //_WIN32 - #if defined(__unix__) || defined(__APPLE__) #ifndef fopen_s @@ -61,9 +42,8 @@ using namespace std; #endif //__unix - -#include -#include +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/imgproc/imgproc.hpp" #include "face_identification.h" #include "common.h" @@ -87,202 +67,214 @@ using namespace seeta; #define EXPECT_EQ(a, b) if ((a) != (b)) std::cout << "ERROR: " #ifdef _WIN32 -std::string DATA_DIR = "../../data/"; -std::string MODEL_DIR = "../../model/"; +std::string gszDataDir = "../../data/"; +std::string gszModelDir = "../../model/"; #else -std::string DATA_DIR = "./data/"; -std::string MODEL_DIR = "./model/"; +std::string gszDataDir = "./data/"; +std::string gszModelDir = "./model/"; #endif void TEST(FaceRecognizerTest, CropFace) { - FaceIdentification face_recognizer((MODEL_DIR + "seeta_fr_v1.0.bin").c_str()); - std::string test_dir = DATA_DIR + "test_face_recognizer/"; - /* data initialize */ - std::ifstream ifs; - std::string img_name; - FacialLandmark pt5[5]; - ifs.open(test_dir + "test_file_list.txt", std::ifstream::in); - clock_t start, count = 0; - int img_num = 0; - while (ifs >> img_name) { - img_num ++ ; - // read image - cv::Mat src_img = cv::imread(test_dir + img_name, 1); - EXPECT_NE(src_img.data, nullptr) << "Load image error!"; - - // ImageData store data of an image without memory alignment. - ImageData src_img_data(src_img.cols, src_img.rows, src_img.channels()); - src_img_data.data = src_img.data; - - // 5 located landmark points (left eye, right eye, nose, left and right - // corner of mouse). - for (int i = 0; i < 5; ++ i) { - ifs >> pt5[i].x >> pt5[i].y; - } - - // Create a image to store crop face. - cv::Mat dst_img(face_recognizer.crop_height(), - face_recognizer.crop_width(), - CV_8UC(face_recognizer.crop_channels())); - ImageData dst_img_data(dst_img.cols, dst_img.rows, dst_img.channels()); - dst_img_data.data = dst_img.data; - /* Crop Face */ - start = clock(); - face_recognizer.CropFace(src_img_data, pt5, dst_img_data); - count += clock() - start; - // Show crop face - // cv::imshow("Crop Face", dst_img); - // cv::waitKey(0); - // cv::destroyWindow("Crop Face"); - } - ifs.close(); - std::cout << "Test successful! \nAverage crop face time: " - << 1000.0 * count / CLOCKS_PER_SEC / img_num << "ms" << std::endl; + FaceIdentification face_recognizer((gszModelDir + "/seeta_fr_v1.0.bin").c_str()); + std::string test_dir = gszDataDir + "/test_face_recognizer/"; + /* data initialize */ + std::ifstream ifs; + std::string img_name; + FacialLandmark pt5[5]; + ifs.open(test_dir + "/test_file_list.txt", std::ifstream::in); + clock_t start, count = 0; + int img_num = 0; + while (ifs >> img_name) { + img_num++; + // read image + cv::Mat src_img = cv::imread(test_dir + img_name, 1); + EXPECT_NE(src_img.data, nullptr) << "Load image error!"; + + // ImageData store data of an image without memory alignment. + ImageData src_img_data(src_img.cols, src_img.rows, src_img.channels()); + src_img_data.data = src_img.data; + + // 5 located landmark points (left eye, right eye, nose, left and right + // corner of mouse). + for (int i = 0; i < 5; ++i) { + ifs >> pt5[i].x >> pt5[i].y; + } + + // Create a image to store crop face. + cv::Mat dst_img(face_recognizer.crop_height(), + face_recognizer.crop_width(), + CV_8UC(face_recognizer.crop_channels())); + ImageData dst_img_data(dst_img.cols, dst_img.rows, dst_img.channels()); + dst_img_data.data = dst_img.data; + /* Crop Face */ + start = clock(); + face_recognizer.CropFace(src_img_data, pt5, dst_img_data); + count += clock() - start; + // Show crop face + /* + cv::imshow("Source Face", src_img); + cv::imshow("Crop Face", dst_img); + cv::waitKey(0); + cv::destroyWindow("Crop Face");//*/ + } + ifs.close(); + std::cout << "Test successful! \nAverage crop face time: " + << 1000.0 * count / CLOCKS_PER_SEC / img_num << "ms" << std::endl; } void TEST(FaceRecognizerTest, ExtractFeature) { - FaceIdentification face_recognizer((MODEL_DIR + "seeta_fr_v1.0.bin").c_str()); - std::string test_dir = DATA_DIR + "test_face_recognizer/"; - - int feat_size = face_recognizer.feature_size(); - EXPECT_EQ(feat_size, 2048); - - FILE* feat_file = NULL; - - // Load features extract from caffe - fopen_s(&feat_file, (test_dir + "feats.dat").c_str(), "rb"); - int n, c, h, w; - EXPECT_EQ(fread(&n, sizeof(int), 1, feat_file), (unsigned int)1); - EXPECT_EQ(fread(&c, sizeof(int), 1, feat_file), (unsigned int)1); - EXPECT_EQ(fread(&h, sizeof(int), 1, feat_file), (unsigned int)1); - EXPECT_EQ(fread(&w, sizeof(int), 1, feat_file), (unsigned int)1); - float* feat_caffe = new float[n * c * h * w]; - float* feat_sdk = new float[n * c * h * w]; - EXPECT_EQ(fread(feat_caffe, sizeof(float), n * c * h * w, feat_file), - n * c * h * w); - EXPECT_EQ(feat_size, c * h * w); - - int cnt = 0; - - /* Data initialize */ - std::ifstream ifs(test_dir + "crop_file_list.txt"); - std::string img_name; - - clock_t start, count = 0; - int img_num = 0, lb; - double average_sim = 0.0; - while (ifs >> img_name >> lb) { - // read image - cv::Mat src_img = cv::imread(test_dir + img_name, 1); - EXPECT_NE(src_img.data, nullptr) << "Load image error!"; - cv::resize(src_img, src_img, cv::Size(face_recognizer.crop_height(), - face_recognizer.crop_width())); - - // ImageData store data of an image without memory alignment. - ImageData src_img_data(src_img.cols, src_img.rows, src_img.channels()); - src_img_data.data = src_img.data; - - /* Extract feature */ - start = clock(); - face_recognizer.ExtractFeature(src_img_data, - feat_sdk + img_num * feat_size); - count += clock() - start; - - /* Caculate similarity*/ - float* feat1 = feat_caffe + img_num * feat_size; - float* feat2 = feat_sdk + img_num * feat_size; - float sim = face_recognizer.CalcSimilarity(feat1, feat2); - average_sim += sim; - img_num ++ ; - } - ifs.close(); - average_sim /= img_num; - if (1.0 - average_sim > 0.01) { - std::cout<< "average similarity: " << average_sim << std::endl; - } - else { - std::cout << "Test successful!\nAverage extract feature time: " - << 1000.0 * count / CLOCKS_PER_SEC / img_num << "ms" << std::endl; - } - delete []feat_caffe; - delete []feat_sdk; + FaceIdentification face_recognizer((gszModelDir + "/seeta_fr_v1.0.bin").c_str()); + std::string test_dir = gszDataDir + "/test_face_recognizer/"; + + int feat_size = face_recognizer.feature_size(); + EXPECT_EQ(feat_size, 2048); + + FILE* feat_file = NULL; + + // Load features extract from caffe + fopen_s(&feat_file, (test_dir + "/feats.dat").c_str(), "rb"); + int n, c, h, w; + EXPECT_EQ(fread(&n, sizeof(int), 1, feat_file), (unsigned int)1); + EXPECT_EQ(fread(&c, sizeof(int), 1, feat_file), (unsigned int)1); + EXPECT_EQ(fread(&h, sizeof(int), 1, feat_file), (unsigned int)1); + EXPECT_EQ(fread(&w, sizeof(int), 1, feat_file), (unsigned int)1); + float* feat_caffe = new float[n * c * h * w]; + float* feat_sdk = new float[n * c * h * w]; + EXPECT_EQ(fread(feat_caffe, sizeof(float), n * c * h * w, feat_file), + n * c * h * w); + EXPECT_EQ(feat_size, c * h * w); + + int cnt = 0; + + /* Data initialize */ + std::ifstream ifs(test_dir + "/crop_file_list.txt"); + std::string img_name; + + clock_t start, count = 0; + int img_num = 0, lb; + double average_sim = 0.0; + while (ifs >> img_name >> lb) { + // read image + cv::Mat src_img = cv::imread(test_dir + img_name, 1); + EXPECT_NE(src_img.data, nullptr) << "Load image error!"; + cv::resize(src_img, src_img, cv::Size(face_recognizer.crop_height(), + face_recognizer.crop_width())); + + // ImageData store data of an image without memory alignment. + ImageData src_img_data(src_img.cols, src_img.rows, src_img.channels()); + src_img_data.data = src_img.data; + + /* Extract feature */ + start = clock(); + face_recognizer.ExtractFeature(src_img_data, + feat_sdk + img_num * feat_size); + count += clock() - start; + + /* Caculate similarity*/ + float* feat1 = feat_caffe + img_num * feat_size; + float* feat2 = feat_sdk + img_num * feat_size; + float sim = face_recognizer.CalcSimilarity(feat1, feat2); + average_sim += sim; + img_num++; + } + ifs.close(); + average_sim /= img_num; + if (1.0 - average_sim > 0.01) { + std::cout << "average similarity: " << average_sim << std::endl; + } + else { + std::cout << "Test successful!\nAverage extract feature time: " + << 1000.0 * count / CLOCKS_PER_SEC / img_num << "ms" << std::endl; + } + delete[]feat_caffe; + delete[]feat_sdk; } void TEST(FaceRecognizerTest, ExtractFeatureWithCrop) { - FaceIdentification face_recognizer((MODEL_DIR + "seeta_fr_v1.0.bin").c_str()); - std::string test_dir = DATA_DIR + "test_face_recognizer/"; - - int feat_size = face_recognizer.feature_size(); - EXPECT_EQ(feat_size, 2048); - - FILE* feat_file = NULL; - - // Load features extract from caffe - fopen_s(&feat_file, (test_dir + "feats.dat").c_str(), "rb"); - int n, c, h, w; - EXPECT_EQ(fread(&n, sizeof(int), 1, feat_file), (unsigned int)1); - EXPECT_EQ(fread(&c, sizeof(int), 1, feat_file), (unsigned int)1); - EXPECT_EQ(fread(&h, sizeof(int), 1, feat_file), (unsigned int)1); - EXPECT_EQ(fread(&w, sizeof(int), 1, feat_file), (unsigned int)1); - float* feat_caffe = new float[n * c * h * w]; - float* feat_sdk = new float[n * c * h * w]; - EXPECT_EQ(fread(feat_caffe, sizeof(float), n * c * h * w, feat_file), - n * c * h * w); - EXPECT_EQ(feat_size, c * h * w); - - int cnt = 0; - - /* Data initialize */ - std::ifstream ifs(test_dir + "test_file_list.txt"); - std::string img_name; - FacialLandmark pt5[5]; - - clock_t start, count = 0; - int img_num = 0; - double average_sim = 0.0; - while (ifs >> img_name) { - // read image - cv::Mat src_img = cv::imread(test_dir + img_name, 1); - EXPECT_NE(src_img.data, nullptr) << "Load image error!"; - - // ImageData store data of an image without memory alignment. - ImageData src_img_data(src_img.cols, src_img.rows, src_img.channels()); - src_img_data.data = src_img.data; - - // 5 located landmark points (left eye, right eye, nose, left and right - // corner of mouse). - for (int i = 0; i < 5; ++ i) { - ifs >> pt5[i].x >> pt5[i].y; - } - - /* Extract feature: ExtractFeatureWithCrop */ - start = clock(); - face_recognizer.ExtractFeatureWithCrop(src_img_data, pt5, - feat_sdk + img_num * feat_size); - count += clock() - start; - - /* Caculate similarity*/ - float* feat1 = feat_caffe + img_num * feat_size; - float* feat2 = feat_sdk + img_num * feat_size; - float sim = face_recognizer.CalcSimilarity(feat1, feat2); - average_sim += sim; - img_num ++ ; - } - ifs.close(); - average_sim /= img_num; - if (1.0 - average_sim > 0.02) { - std::cout<< "average similarity: " << average_sim << std::endl; - } - else { - std::cout << "Test successful!\nAverage extract feature time: " - << 1000.0 * count / CLOCKS_PER_SEC / img_num << "ms" << std::endl; - } - delete []feat_caffe; - delete []feat_sdk; + FaceIdentification face_recognizer((gszModelDir + "/seeta_fr_v1.0.bin").c_str()); + std::string test_dir = gszDataDir + "/test_face_recognizer/"; + + int feat_size = face_recognizer.feature_size(); + EXPECT_EQ(feat_size, 2048); + + FILE* feat_file = NULL; + + // Load features extract from caffe + fopen_s(&feat_file, (test_dir + "/feats.dat").c_str(), "rb"); + int n, c, h, w; + EXPECT_EQ(fread(&n, sizeof(int), 1, feat_file), (unsigned int)1); + EXPECT_EQ(fread(&c, sizeof(int), 1, feat_file), (unsigned int)1); + EXPECT_EQ(fread(&h, sizeof(int), 1, feat_file), (unsigned int)1); + EXPECT_EQ(fread(&w, sizeof(int), 1, feat_file), (unsigned int)1); + float* feat_caffe = new float[n * c * h * w]; + float* feat_sdk = new float[n * c * h * w]; + EXPECT_EQ(fread(feat_caffe, sizeof(float), n * c * h * w, feat_file), + n * c * h * w); + EXPECT_EQ(feat_size, c * h * w); + + int cnt = 0; + + /* Data initialize */ + std::ifstream ifs(test_dir + "/test_file_list.txt"); + std::string img_name; + FacialLandmark pt5[5]; + + clock_t start, count = 0; + int img_num = 0; + double average_sim = 0.0; + while (ifs >> img_name) { + // read image + cv::Mat src_img = cv::imread(test_dir + img_name, 1); + EXPECT_NE(src_img.data, nullptr) << "Load image error!"; + + // ImageData store data of an image without memory alignment. + ImageData src_img_data(src_img.cols, src_img.rows, src_img.channels()); + src_img_data.data = src_img.data; + + // 5 located landmark points (left eye, right eye, nose, left and right + // corner of mouse). + for (int i = 0; i < 5; ++i) { + ifs >> pt5[i].x >> pt5[i].y; + } + + /* Extract feature: ExtractFeatureWithCrop */ + start = clock(); + face_recognizer.ExtractFeatureWithCrop(src_img_data, pt5, + feat_sdk + img_num * feat_size); + count += clock() - start; + + /* Caculate similarity*/ + float* feat1 = feat_caffe + img_num * feat_size; + float* feat2 = feat_sdk + img_num * feat_size; + float sim = face_recognizer.CalcSimilarity(feat1, feat2); + average_sim += sim; + img_num++; + } + ifs.close(); + average_sim /= img_num; + if (1.0 - average_sim > 0.02) { + std::cout << "average similarity: " << average_sim << std::endl; + } + else { + std::cout << "Test successful!\nAverage extract feature time: " + << 1000.0 * count / CLOCKS_PER_SEC / img_num << "ms" << std::endl; + } + delete[]feat_caffe; + delete[]feat_sdk; } int main(int argc, char* argv[]) { - TEST(FaceRecognizerTest, CropFace); - TEST(FaceRecognizerTest, ExtractFeature); - TEST(FaceRecognizerTest, ExtractFeatureWithCrop); - return 0; + if (argc < 2) { + std::cout << "Usage: " << argv[0] + << " model_path data_path" + << std::endl; + return -1; + } + + gszModelDir = argv[1]; + gszDataDir = argv[2]; + + TEST(FaceRecognizerTest, CropFace); + TEST(FaceRecognizerTest, ExtractFeature); + TEST(FaceRecognizerTest, ExtractFeatureWithCrop); + return 0; } diff --git a/FaceIdentification/src/test/test_face_verification.cpp b/FaceIdentification/src/test/test_face_verification.cpp index b30dc4127..c4237945b 100644 --- a/FaceIdentification/src/test/test_face_verification.cpp +++ b/FaceIdentification/src/test/test_face_verification.cpp @@ -28,29 +28,11 @@ * Note: the above information must be kept whenever or wherever the codes are used. * */ +#pragma once #include using namespace std; -#ifdef _WIN32 -#pragma once -#include - -#define CV_VERSION_ID CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) \ - CVAUX_STR(CV_SUBMINOR_VERSION) - -#ifdef _DEBUG -#define cvLIB(name) "opencv_" name CV_VERSION_ID "d" -#else -#define cvLIB(name) "opencv_" name CV_VERSION_ID -#endif //_DEBUG - -#pragma comment( lib, cvLIB("core") ) -#pragma comment( lib, cvLIB("imgproc") ) -#pragma comment( lib, cvLIB("highgui") ) - -#endif //_WIN32 - #if defined(__unix__) || defined(__APPLE__) #ifndef fopen_s @@ -61,8 +43,9 @@ using namespace std; #endif //__unix -#include -#include +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/imgproc/imgproc.hpp" + #include "face_identification.h" #include "recognizer.h" #include "face_detection.h" @@ -81,92 +64,97 @@ using namespace seeta; #define EXPECT_NE(a, b) if ((a) == (b)) std::cout << "ERROR: " #define EXPECT_EQ(a, b) if ((a) != (b)) std::cout << "ERROR: " -#ifdef _WIN32 -std::string DATA_DIR = "../../data/"; -std::string MODEL_DIR = "../../model/"; -#else -std::string DATA_DIR = "./data/"; -std::string MODEL_DIR = "./model/"; -#endif - - int main(int argc, char* argv[]) { - // Initialize face detection model - seeta::FaceDetection detector("seeta_fd_frontal_v1.0.bin"); - detector.SetMinFaceSize(40); - detector.SetScoreThresh(2.f); - detector.SetImagePyramidScaleFactor(0.8f); - detector.SetWindowStep(4, 4); - - // Initialize face alignment model - seeta::FaceAlignment point_detector("seeta_fa_v1.1.bin"); - - // Initialize face Identification model - FaceIdentification face_recognizer((MODEL_DIR + "seeta_fr_v1.0.bin").c_str()); - std::string test_dir = DATA_DIR + "test_face_recognizer/"; - - //load image - cv::Mat gallery_img_color = cv::imread(test_dir + "images/compare_im/Aaron_Peirsol_0001.jpg", 1); - cv::Mat gallery_img_gray; - cv::cvtColor(gallery_img_color, gallery_img_gray, CV_BGR2GRAY); - - cv::Mat probe_img_color = cv::imread(test_dir + "images/compare_im/Aaron_Peirsol_0004.jpg", 1); - cv::Mat probe_img_gray; - cv::cvtColor(probe_img_color, probe_img_gray, CV_BGR2GRAY); - - ImageData gallery_img_data_color(gallery_img_color.cols, gallery_img_color.rows, gallery_img_color.channels()); - gallery_img_data_color.data = gallery_img_color.data; - - ImageData gallery_img_data_gray(gallery_img_gray.cols, gallery_img_gray.rows, gallery_img_gray.channels()); - gallery_img_data_gray.data = gallery_img_gray.data; - - ImageData probe_img_data_color(probe_img_color.cols, probe_img_color.rows, probe_img_color.channels()); - probe_img_data_color.data = probe_img_color.data; - - ImageData probe_img_data_gray(probe_img_gray.cols, probe_img_gray.rows, probe_img_gray.channels()); - probe_img_data_gray.data = probe_img_gray.data; - - // Detect faces - std::vector gallery_faces = detector.Detect(gallery_img_data_gray); - int32_t gallery_face_num = static_cast(gallery_faces.size()); - - std::vector probe_faces = detector.Detect(probe_img_data_gray); - int32_t probe_face_num = static_cast(probe_faces.size()); - - if (gallery_face_num == 0 || probe_face_num==0) - { - std::cout << "Faces are not detected."; - return 0; - } - - // Detect 5 facial landmarks - seeta::FacialLandmark gallery_points[5]; - point_detector.PointDetectLandmarks(gallery_img_data_gray, gallery_faces[0], gallery_points); - - seeta::FacialLandmark probe_points[5]; - point_detector.PointDetectLandmarks(probe_img_data_gray, probe_faces[0], probe_points); - - for (int i = 0; i<5; i++) - { - cv::circle(gallery_img_color, cv::Point(gallery_points[i].x, gallery_points[i].y), 2, - CV_RGB(0, 255, 0)); - cv::circle(probe_img_color, cv::Point(probe_points[i].x, probe_points[i].y), 2, - CV_RGB(0, 255, 0)); - } - cv::imwrite("gallery_point_result.jpg", gallery_img_color); - cv::imwrite("probe_point_result.jpg", probe_img_color); - - // Extract face identity feature - float gallery_fea[2048]; - float probe_fea[2048]; - face_recognizer.ExtractFeatureWithCrop(gallery_img_data_color, gallery_points, gallery_fea); - face_recognizer.ExtractFeatureWithCrop(probe_img_data_color, probe_points, probe_fea); - - // Caculate similarity of two faces - float sim = face_recognizer.CalcSimilarity(gallery_fea, probe_fea); - std::cout << sim < gallery_faces = detector.Detect(gallery_img_data_gray); + int32_t gallery_face_num = static_cast(gallery_faces.size()); + + std::vector probe_faces = detector.Detect(probe_img_data_gray); + int32_t probe_face_num = static_cast(probe_faces.size()); + + if (gallery_face_num == 0 || probe_face_num == 0) + { + std::cout << "Faces are not detected."; + return 0; + } + + // Detect 5 facial landmarks + seeta::FacialLandmark gallery_points[5]; + point_detector.PointDetectLandmarks(gallery_img_data_gray, gallery_faces[0], gallery_points); + + seeta::FacialLandmark probe_points[5]; + point_detector.PointDetectLandmarks(probe_img_data_gray, probe_faces[0], probe_points); + + for (int i = 0; i < 5; i++) + { + cv::circle(gallery_img_color, cv::Point(gallery_points[i].x, gallery_points[i].y), 2, + CV_RGB(0, 255, 0)); + cv::circle(probe_img_color, cv::Point(probe_points[i].x, probe_points[i].y), 2, + CV_RGB(0, 255, 0)); + } + //cv::imwrite("gallery_point_result.jpg", gallery_img_color); + //cv::imwrite("probe_point_result.jpg", probe_img_color); + + // Extract face identity feature + float gallery_fea[2048]; + float probe_fea[2048]; + face_recognizer.ExtractFeatureWithCrop(gallery_img_data_color, gallery_points, gallery_fea); + face_recognizer.ExtractFeatureWithCrop(probe_img_data_color, probe_points, probe_fea); + + // Caculate similarity of two faces + float sim = face_recognizer.CalcSimilarity(gallery_fea, probe_fea); + std::cout << sim << endl; + + cv::namedWindow("Test", cv::WINDOW_AUTOSIZE); + cv::imshow("gallery", gallery_img_color); + cv::imshow("proble", probe_img_color); + cv::waitKey(0); + cv::destroyAllWindows(); + + return 0; } diff --git a/SeetaFaceEngineConfig.cmake.in b/SeetaFaceEngineConfig.cmake.in new file mode 100644 index 000000000..22a3b5e45 --- /dev/null +++ b/SeetaFaceEngineConfig.cmake.in @@ -0,0 +1,82 @@ +# Author: KangLin(kl222@126.com) + +#.rst: +# SeetaFaceEngine +# -------- +# +# Find SeetaFaceEngine +# +# Find the SeetaFaceEngine libraries (asound) +# +# :: +# +# This module defines the following variables: +# SEETAFACEENGINE_FOUND - True if SeetaFaceEngine libraries are found +# SEETAFACEENGINE_LIBRARIES - Set when SeetaFaceEngine libraries is found +# SEETAFACEENGINE_INCLUDE_DIRS - where to find SeetaFaceEngine heard directory. +# SEETAFACEENGINE_VERSION_STRING - the version of SeetaFaceEngine found (since CMake 2.8.8) + +set(SEETAFACEENGINE_VERSION_STRING @SEETAFACEENGINE_VERSION_MAJOR@.@SEETAFACEENGINE_VERSION_MINOR@.@SEETAFACEENGINE_VERSION_PATCH@) + +find_path(FaceDetection_INCLUDE_DIR NAMES face_detection.h + DOC "The face detection include directory" +) + +find_library(FaceDetection_LIBRARIE NAMES seeta_facedet_lib + DOC "The face detection library" +) + +find_path(FaceAlignment_INCLUDE_DIR NAMES face_alignment.h + DOC "The face alignment include directory" +) + +find_library(FaceAlignment_LIBRARIE NAMES seeta_fa_lib + DOC "The face alignment library" +) + +find_path(FaceIdentification_INCLUDE_DIR NAMES viplnet.h + DOC "The face identification include directory" +) + +find_library(FaceIdentification_LIBRARIE NAMES viplnet + DOC "The face identification library" +) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SEETAFACEENGINE + REQUIRED_VARS FaceDetection_INCLUDE_DIR + FaceDetection_LIBRARIE + FaceAlignment_INCLUDE_DIR + FaceAlignment_LIBRARIE + FaceIdentification_INCLUDE_DIR + FaceIdentification_LIBRARIE + VERSION_VAR SEETAFACEENGINE_VERSION_STRING + ) + +if(SEETAFACEENGINE_FOUND) + + set( SEETAFACEENGINE_LIBRARIES + ${FaceIdentification_LIBRARIE} + ${FaceAlignment_LIBRARIE} + ${FaceDetection_LIBRARIE} + ) + set( SEETAFACEENGINE_INCLUDE_DIRS + ${FaceIdentification_INCLUDE_DIR} + ${FaceAlignment_INCLUDE_DIR} + ${FaceDetection_INCLUDE_DIR} + ) + + get_filename_component(SEETAFACEENGINE_PATH "${FaceDetection_LIBRARIE}" DIRECTORY) + file(TO_NATIVE_PATH "${SEETAFACEENGINE_PATH}" SEETAFACEENGINE_PATH) + message(STATUS "Found SeetaFaceEngine ${SEETAFACEENGINE_VERSION_STRING} in ${SEETAFACEENGINE_PATH}") + get_filename_component(SEETAFACEENGINE_BIN_PATH "${FaceDetection_LIBRARIE}" DIRECTORY) + get_filename_component(SEETAFACEENGINE_BIN_PATH "${SEETAFACEENGINE_BIN_PATH}/../bin" ABSOLUTE) + file(TO_NATIVE_PATH "${SEETAFACEENGINE_BIN_PATH}" SEETAFACEENGINE_BIN_PATH) + message(STATUS "You might need to add ${SEETAFACEENGINE_BIN_PATH} to your PATH to be able to run your applications.") +endif() + +mark_as_advanced(FaceDetection_INCLUDE_DIR + FaceDetection_LIBRARIE + FaceAlignment_INCLUDE_DIR + FaceAlignment_LIBRARIE + FaceIdentification_INCLUDE_DIR + FaceIdentification_LIBRARIE) diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in new file mode 100644 index 000000000..c185f9b55 --- /dev/null +++ b/cmake_uninstall.cmake.in @@ -0,0 +1,23 @@ + +IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +STRING(REGEX REPLACE "\n" ";" files "${files}") +FOREACH(file ${files}) + MESSAGE(STATUS "Uninstalling \"${file}\"") + IF(EXISTS "${file}") + EXEC_PROGRAM( + "@CMAKE_COMMAND@" ARGS "-E remove \"${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + IF("${rm_retval}" STREQUAL 0) + ELSE("${rm_retval}" STREQUAL 0) + MESSAGE(FATAL_ERROR "Problem when removing \"${file}\"") + ENDIF("${rm_retval}" STREQUAL 0) + ELSE(EXISTS "${file}") + MESSAGE(STATUS "File \"${file}\" does not exist.") + ENDIF(EXISTS "${file}") +ENDFOREACH(file)