To use the library, you can do either of the following:
- Copy the .cpp files in src folder directly to your project's source folder, and then compile them with the other files in your project. The source code are written in standard C/C++, so they should compile on any platform that supports C/C++;
- Or follow the steps below to generate dynamic/static libraries under different environments.
-
Set up OpenCV with 4.51+ version.
-
Download libfacedetection and then run powershell terminal as administrator:
cd libfacedetection mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=install -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DDEMO=OFF cmake --build . --config Release cmake --build . --config Release --target installDynamic library(facedetection.dll) is generated. Then, to generate static library(lib), you need to set the parameter
BUILD_SHARED_LIBStoOFFwith the above commands. -
To deploy the facedetection libraries in a Visual Studio C++ console app, in your console application's property pages, under Release mode (because the build type is Release), add the path of your
libfacedetection\build\install\include\facedetectionto VC++ Directories -> Include Directories and the path of yourlibfacedetection\build\install\libto VC++ Directories -> Library Directories, and addfacedetection.libto Linker -> Input -> Additional Dependencies. -
Add
#include "facedetectcnn.h"to your source files. See code example built with Visual Studio.
-
Set up OpenCV with 4.51+ version.
-
Same as the step 1 above with Visual Studio.
libfacedetection.sois built withBUILD_SHARED_LIBS=ONandlibfacedetecion.ais built with the variable set toOFF. -
Set the environment variable
facedetection_DIRtopath\to\libfacedetection\build. -
Use
find_package(facedetection)in the CMakeLists of your project, or usetarget_link_libraries( your-program /path/to/libfacedetection/build/install/lib/libfacedetection.so).find_package(facedetection) if(facedetection_FOUND) //your code endif() -
Add
#include "facedetectcnn.h"to your source files to use the libraries.
- Set up OpenCV with 4.51+ version.
- Same as the step 1 above with Visual Studio.
libfacedetection.sois built withBUILD_SHARED_LIBS=ONandlibfacedetecion.ais built with the variable set toOFF. - Set the environment variable
facedetection_DIRtopath\to\libfacedetection\build. - Use
target_link_libraries( your-program /path/to/libfacedetection/build/install/lib/libfacedetection.so)in the CMakelists of your project to use the shared object. - Add
#include "facedetectcnn.h"to your source files to use the libraries. See code example built with GNU on Linux/Ubuntu.
-
Install ndk
-
Download and install to /home/android-ndk from https://developer.android.com/ndk/downloads
-
Setting environment variables
export ANDROID_NDK=/home/android-ndk
-
-
Complie
-
The host is Linux / Ubuntu
-
Build
mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=install \ -DCMAKE_BUILD_TYPE=MinSizeRel \ -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \ -DANDROID_ABI="arm64-v8a" \ -DANDROID_PLATFORM=android-18 \ -DUSE_OPENMP=OFF \ -DENABLE_NEON=ON \ -DENABLE_AVX2=OFF \ -DDEMO=OFF cmake --build . --config MinSizeRel -
Install
cmake --build . --config MinSizeRel --target install/strip
-
-
The host is Windows
-
Build
mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=%cd%\install -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%/build/cmake/android.toolchain.cmake -DCMAKE_MAKE_PROGRAM=%ANDROID_NDK%/prebuilt/windows-x86_64/bin/make.exe -DANDROID_ABI=arm64-v8a -DANDROID_ARM_NEON=ON -DANDROID_PLATFORM=android-24 -DUSE_OPENMP=OFF -DENABLE_NEON=ON -DENABLE_AVX2=OFF -DDEMO=OFF cmake --build . --config MinSizeRel -
Install
cmake --build . --config MinSizeRel --target install/strip
-
-
msys2 or cygwin
-
Build
mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=install \ -G"Unix Makefiles" \ -DCMAKE_BUILD_TYPE=MinSizeRel \ -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \ -DCMAKE_MAKE_PROGRAM=${ANDROID_NDK}\prebuilt\windows-x86_64\bin\make.exe \ -DANDROID_ABI=arm64-v8a \ -DANDROID_ARM_NEON=ON \ -DUSE_OPENMP=OFF \ -DENABLE_NEON=ON \ -DENABLE_AVX2=OFF \ -DDEMO=OFF cmake --build . --config MinSizeRel -
Install
cmake --build . --config MinSizeRel --target install/strip
-
-
- Parameter Description: https://developer.android.google.cn/ndk/guides/cmake
- ANDROID_ABI: The following values can be taken:
Goal ABI. If the target ABI is not specified, CMake uses armeabi-v7a by default.
Valid ABI are:
- armeabi:CPU with software floating point arithmetic based on ARMv5TE
- armeabi-v7a:ARMv7-based device with hardware FPU instructions (VFP v3 D16)
- armeabi-v7a with NEON:Same as armeabi-v7a, but with NEON floating point instructions enabled. This is equivalent to setting -DANDROID_ABI=armeabi-v7a and -DANDROID_ARM_NEON=ON.
- arm64-v8a:ARMv8 AArch64 Instruction Set
- x86:IA-32 Instruction Set
- x86_64 - x86-64 Instruction Set
- ANDROID_NDK The path of installed ndk in host
- ANDROID_PLATFORM: For a full list of platform names and corresponding Android system images, see the [Android NDK Native API] (https://developer.android.google.com/ndk/guides/stable_apis.html)
- ANDROID_ARM_MODE
- ANDROID_ARM_NEON
- ANDROID_STL:Specifies the STL that CMake should use.
- c++_shared: use libc++ shared library
- c++_static: use libc++ static library
- none: no stl
- system: use system STL
- ANDROID_ABI: The following values can be taken:
Goal ABI. If the target ABI is not specified, CMake uses armeabi-v7a by default.
Valid ABI are:
- To deploy libfacedetection with the OpenCV DNN module and ONNX model, see face detection with OpenCV DNN.
The highway/ directory contains an independent Highway-based implementation
for performance experiments and platform-specific builds. It keeps the same
external calling style as facedetect_cnn, but exposes a separate entry point:
#include "facedetect_hw.h"
int* results = facedetect_hw_cnn(buffer, bgr_image_data, width, height, step);The Highway version is built as a separate CMake project. It uses
find_package(hwy 1.3.0 CONFIG) and does not hard-code third-party paths.
Pass hwy_DIR or FDT_HW_HIGHWAY_ROOT explicitly.
cmake -S highway -B build-hw `
-Dhwy_DIR=<path-to-highway>/lib/cmake/hwy `
-DOpenCV_DIR=<path-to-opencv>/staticlib `
-DFDT_HW_BUILD_IMAGE_BENCHMARK=ON
cmake --build build-hw --config Release --target fdt_hw_tests
cmake --build build-hw --config Release --target fdt_hw_image_benchmark
.\build-hw\Release\fdt_hw_tests.exe
.\build-hw\Release\fdt_hw_image_benchmark.exe images\cnnresult.pngIf your local prebuilt packages use the same variant layout as the development environment, you can pass root directories instead:
cmake -S highway -B build-hw `
-DFDT_HW_HIGHWAY_ROOT=<path-to-highway-root> `
-DFDT_HW_OPENCV_ROOT=<path-to-opencv-root>On x86/x64, the default build enables the current fastest backend:
FDT_HW_EFFECTIVE_BACKEND = x86-hybrid-avx2
This backend uses Highway kernels plus guarded AVX2/FMA intrinsics for selected x86-only kernels. For a pure Highway build, use:
cmake -S highway -B build-hw-pure `
-Dhwy_DIR=<path-to-highway>/lib/cmake/hwy `
-DOpenCV_DIR=<path-to-opencv>/staticlib `
-DFDT_HW_ENABLE_HYBRID_CEILING=OFF `
-DFDT_HW_ENABLE_INTRINSICS_COMPARE=OFFCommon instruction-set build modes:
Highway scalar:
-DFDT_HW_FORCE_SCALAR=ON
-DFDT_HW_X86_ARCH=DEFAULT
-DFDT_HW_ENABLE_HYBRID_CEILING=OFF
-DFDT_HW_ENABLE_INTRINSICS_COMPARE=OFF
SSE/default x86:
-DFDT_HW_FORCE_SCALAR=OFF
-DFDT_HW_X86_ARCH=DEFAULT
-DFDT_HW_ENABLE_HYBRID_CEILING=OFF
-DFDT_HW_ENABLE_INTRINSICS_COMPARE=OFF
AVX2 pure Highway:
-DFDT_HW_FORCE_SCALAR=OFF
-DFDT_HW_X86_ARCH=AVX2
-DFDT_HW_ENABLE_HYBRID_CEILING=OFF
-DFDT_HW_ENABLE_INTRINSICS_COMPARE=OFF
AVX2 x86 hybrid:
-DFDT_HW_FORCE_SCALAR=OFF
-DFDT_HW_X86_ARCH=AVX2
-DFDT_HW_ENABLE_HYBRID_CEILING=ON
-DFDT_HW_ENABLE_INTRINSICS_COMPARE=ON
AVX512 pure Highway:
-DFDT_HW_X86_ARCH=AVX512
-DFDT_HW_ENABLE_HYBRID_CEILING=OFF
-DFDT_HW_ENABLE_INTRINSICS_COMPARE=OFF
To reproduce the README resolution table, build and run:
cmake --build build-hw --config Release --target fdt_hw_resolution_benchmark
.\build-hw\Release\fdt_hw_resolution_benchmark.exe images\cnnresult.png 128 28Two Highway examples are provided:
example/detect-image-highway.cpp
example/benchmark-highway.cpp
detect-image-highway.cpp runs detection and draws the result.
benchmark-highway.cpp demonstrates the recommended external multi-threading
model: each calling thread owns a separate result buffer. The Highway public API
uses thread-local internal workspace, but the caller must not share one
result_buffer across threads.
When integrating the examples into your own CMake project, link against
fdt_hw_kernels, OpenCV, and include highway/include:
find_package(OpenCV REQUIRED COMPONENTS core imgcodecs highgui imgproc)
add_subdirectory(path/to/libfacedetection/highway fdt_hw)
add_executable(detect-image-highway
path/to/libfacedetection/example/detect-image-highway.cpp)
target_include_directories(detect-image-highway PRIVATE ${OpenCV_INCLUDE_DIRS})
target_link_libraries(detect-image-highway PRIVATE
fdt_hw_kernels
${OpenCV_LIBS})The current hw implementation follows the same deployment style as the
original project: build separately for different instruction sets/platforms
instead of using Highway runtime dynamic dispatch.
- Set cross compiler for aarch64 (please refer to aarch64-toolchain.cmake).
- Set opencv path since the example code depends on opencv.
cmake \
-DENABLE_NEON=ON \
-DCMAKE_BUILD_TYPE=RELEASE \
-DCMAKE_TOOLCHAIN_FILE=../aarch64-toolchain.cmake \
..
makeHere is an example of how to use the face detection model in C++:
#include "facedetectcnn.h"
#include <opencv2/opencv.hpp>
#define DETECT_BUFFER_SIZE FACEDETECTION_RESULT_BUFFER_SIZE
int main()
{
int * pResults = NULL;
unsigned char * pBuffer = (unsigned char *)malloc(DETECT_BUFFER_SIZE);
Mat image = imread(file_path);
/**
The function that loads the face detection model.
@param result_buffer Buffer memory for storing face detection results, whose size must be FACEDETECTION_RESULT_BUFFER_SIZE bytes.
@param rgb_image_data Input image, which must be BGR (three channels) instead of RGB image.
@param width The width of the input image.
@param height The height.
@param step The step.
@return An int pointer reflecting the face detection result, see Example for detailed usage.
*/
int * pResults = facedetect_cnn(pBuffer, (unsigned char*)(image.ptr(0)), image.cols, image.rows, (int)image.step);
}-
To build the ./example of libfacedetection:
- Tips:
- Please add facedetection_export.h file in the position where you copy your facedetectcnn.h files, add #define FACEDETECTION_EXPORT to facedetection_export.h file. See: issues #222
- Please add -O3 to turn on optimizations when you compile the source code using g++.
- Please choose 'Maximize Speed/-O2' when you compile the source code using Microsoft Visual Studio.
- You can enable OpenMP to speedup. But the best solution is to call the detection function in different threads.
If using Linux/Ubuntu, you can:
-
Add CMakeLists.txt:
cmake_minimum_required( VERSION 2.8 ) project( example ) find_package( OpenCV REQUIRED ) message(STATUS "OpenCV_LIBS = ${OpenCV_LIBS}") include_directories( ${OpenCV_INCLUDE_DIRS} ) add_executable( detect-image detect-image.cpp ) add_executable( detect-camera detect-camera.cpp ) target_link_libraries( detect-image ${OpenCV_LIBS} ) target_link_libraries( detect-image /libfacedetection/build/install/lib/libfacedetection.so ) target_link_libraries( detect-image /opencv/build/lib/libopencv_highgui.so ) target_link_libraries( detect-image /opencv/build/lib/libopencv_imgproc.so ) target_link_libraries( detect-image /opencv/build/lib/libopencv_core.so ) target_link_libraries( detect-image /opencv/build/lib/libopencv_imgcodecs.so ) target_link_libraries( detect-camera ${OpenCV_LIBS} ) target_link_libraries( detect-camera /libfacedetection/build/install/lib/libfacedetection.so ) target_link_libraries( detect-camera /opencv/build/lib/libopencv_highgui.so ) target_link_libraries( detect-camera /opencv/build/lib/libopencv_video.so ) target_link_libraries( detect-camera /opencv/build/lib/libopencv_imgproc.so ) target_link_libraries( detect-camera /opencv/build/lib/libopencv_core.so ) target_link_libraries( detect-camera /opencv/build/lib/libopencv_videoio.so ) -
CMake and make:
cd example mkdir build cd build cmake .. make // detect using an image ./detect-image <path to image> // or detect using camera ./detect-camera <camera-index>
If using Visual Studio 2019, you can:
-
Generate facedetection.lib as well as facedetection.dll (to avoid errors);
-
You can either:
- Add a similar CMakeLists, but instead linking the project to *.lib and compile the folder as a whole into a solution(.sln) that opens in Visual Studio.
OR
- Create a new project with C++ Console App template. Go to Project->Properties and select Release in Configuration, x64 in Platform, then do the following: add the path of your
libfacedetection\build\install\include\facedetection(as well as your OpenCV include path) to VC++ Directories -> Include Directories and the path of yourlibfacedetection\build\install\lib(as well as your OpenCV lib path)to VC++ Directories -> Library Directories, and addfacedetection.liband other necessary dependencies to Linker -> Input -> Additional Dependencies. - Add one file in the example folder to the project's Source foler. To build another example, you can right-click the current Solution in the Solution Explorer, Add->New Project and follow the above step (or use property manager to copy-paste Property Sheet).
-
Build the solution and run the powershell terminal in Visual Studio:
cd x64/Release // detect using an image ./detect-image <path/to/your/image/file> // or detect using camera ./detect-camera <camera-index>
- Tips:
-
Third-party examples
- FaceRecognizer: https://github.com/KangLin/FaceRecognizer
This is a cross-platforms program. It has supported windows, linux, android, etc.
- FaceRecognizer: https://github.com/KangLin/FaceRecognizer
