├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── FaceDetector ├── CMakeLists.txt ├── FaceDetector.pc.in ├── include │ └── seeta │ │ ├── CFaceInfo.h │ │ ├── CStruct.h │ │ ├── FaceDetector.h │ │ └── Struct.h ├── jni │ ├── Android.mk │ └── Application.mk ├── seeta │ ├── CommonStruct.h │ ├── DataHelper.h │ ├── FaceDetectorPrivate.cpp │ ├── FaceDetectorPrivate.h │ ├── ImageProcess.cpp │ ├── ImageProcess.h │ ├── SeetaFaceDetectorConfig.h │ ├── common_alignment.cpp │ ├── common_alignment.h │ ├── graphics2d.cpp │ └── graphics2d.h └── src │ └── seeta │ └── FaceDetector.cpp ├── FaceLandmarker ├── CMakeLists.txt ├── SeetaFaceLandmarker.pc.in ├── include │ └── seeta │ │ ├── CStruct.h │ │ ├── FaceLandmarker.h │ │ └── Struct.h ├── jni │ ├── Android.mk │ └── Application.mk ├── seeta │ ├── CFaceInfo.h │ ├── CommonStruct.h │ ├── DataHelper.h │ ├── FaceLandmarkerPrivate.cpp │ ├── FaceLandmarkerPrivate.h │ ├── ImageProcess.cpp │ ├── ImageProcess.h │ ├── SeetaFaceLandmarkerConfig.h │ ├── SeetaFaceLandmarkerConfig.h.in │ ├── common_alignment.cpp │ ├── common_alignment.h │ ├── graphics2d.cpp │ └── graphics2d.h └── src │ └── seeta │ └── FaceLandmarker.cpp ├── FaceRecognizer ├── CMakeLists.txt ├── FaceRecognizer.pc.in ├── include │ └── seeta │ │ ├── CStream.h │ │ ├── CStruct.h │ │ ├── FaceDatabase.h │ │ ├── FaceRecognizer.h │ │ ├── Stream.h │ │ └── Struct.h ├── jni │ ├── Android.mk │ └── Application.mk ├── seeta │ ├── CFaceInfo.h │ ├── CommonStruct.h │ ├── DataHelper.h │ ├── FaceRecognizerPrivate.cpp │ ├── FaceRecognizerPrivate.h │ ├── ImageProcess.cpp │ ├── ImageProcess.h │ ├── Mutex.h │ ├── SeetaFaceRecognizerConfig.h │ ├── SeetaFaceRecognizerConfig.h.in │ ├── SeetaModelHeader.h │ ├── SeetaNetParseProto.cpp │ ├── SeetaNetParseProto.h │ ├── common_alignment.cpp │ ├── common_alignment.h │ ├── graphics2d.cpp │ └── graphics2d.h └── src │ └── seeta │ ├── FaceDatabase.cpp │ └── FaceRecognizer.cpp ├── FaceTracker ├── CMakeLists.txt ├── FaceTracker.pc.in ├── include │ └── seeta │ │ ├── CStruct.h │ │ ├── CTrackingFaceInfo.h │ │ ├── FaceTracker.h │ │ └── Struct.h └── src │ └── seeta │ └── FaceTracker.cpp ├── LICENSE ├── QualityAssessor ├── CMakeLists.txt ├── QualityAssessor.pc.in ├── include │ └── seeta │ │ ├── CStruct.h │ │ ├── QualityAssessor.h │ │ └── Struct.h ├── seeta │ ├── CommonStruct.h │ ├── DataHelper.h │ ├── ImageProcess.cpp │ ├── ImageProcess.h │ ├── common_alignment.cpp │ ├── common_alignment.h │ ├── graphics2d.cpp │ └── graphics2d.h └── src │ ├── ClarityQuality.cpp │ ├── ClarityQuality.h │ ├── PoseQuality.cpp │ ├── PoseQuality.h │ └── QualityAssessor.cpp ├── README.md ├── README_en.md ├── SeetaFace.pc.in ├── SeetaNet ├── CMakeLists.txt ├── SeetaNet.pc.in ├── include │ ├── SeetaNetForward.h │ └── SeetaNetStruct.h ├── jni │ ├── Android.mk │ └── Application.mk └── src │ ├── ReadFromSeetaNetLayer.cpp │ ├── SeetaNet.cpp │ ├── SeetaNetForward.cpp │ ├── SeetaNetIm2Col.cpp │ ├── SeetaNetMathCPU.cpp │ ├── SeetaNetParseProto.cpp │ ├── SeetaNetProto.cpp │ ├── include_inner │ ├── ReadFromSeetaNetLayer.h │ ├── SeetaNet.h │ ├── SeetaNetBlobCpu.h │ ├── SeetaNetCommon.h │ ├── SeetaNetCommonfuction.h │ ├── SeetaNetCreateLayerDetailCPU.h │ ├── SeetaNetCreateLayerMapCPU.h │ ├── SeetaNetFeatureMap.h │ ├── SeetaNetHypeShape.h │ ├── SeetaNetIm2Col.h │ ├── SeetaNetLayerType.h │ ├── SeetaNetMacro.h │ ├── SeetaNetMathCPU.h │ ├── SeetaNetMemoryModel.h │ ├── SeetaNetParseProto.h │ ├── SeetaNetProto.h │ ├── SeetaNetResource.h │ ├── SeetaNetSimd.h │ └── layers │ │ ├── SeetaNetBaseLayer.h │ │ ├── SeetaNetBatchNormalizeCPU.h │ │ ├── SeetaNetBatchToSpaceNDCPU.h │ │ ├── SeetaNetConcatCPU.h │ │ ├── SeetaNetConvolutionCPU.h │ │ ├── SeetaNetCropCPU.h │ │ ├── SeetaNetDeconvolutionCPU.h │ │ ├── SeetaNetEltwiseCPU.h │ │ ├── SeetaNetExpCPU.h │ │ ├── SeetaNetInnerproductCPU.h │ │ ├── SeetaNetMemoryDataLayerCPU.h │ │ ├── SeetaNetPoolingCPU.h │ │ ├── SeetaNetPowerCPU.h │ │ ├── SeetaNetPreReluCPU.h │ │ ├── SeetaNetRealMulCPU.h │ │ ├── SeetaNetReluCPU.h │ │ ├── SeetaNetReshapeCPU.h │ │ ├── SeetaNetScaleCPU.h │ │ ├── SeetaNetShapeIndexPatchCPU.h │ │ ├── SeetaNetSigmoidCPU.h │ │ ├── SeetaNetSoftmaxCPU.h │ │ ├── SeetaNetSpaceToBatchNDCPU.h │ │ └── SeetaNetSplitCPU.h │ └── orz │ ├── mem │ ├── pot.cpp │ ├── pot.h │ ├── vat.cpp │ └── vat.h │ ├── sync │ ├── canyon.cpp │ ├── canyon.h │ ├── cartridge.cpp │ ├── cartridge.h │ ├── shotgun.cpp │ └── shotgun.h │ └── tools │ ├── box.cpp │ ├── box.h │ ├── ctxmgr_lite.h │ ├── ctxmgr_lite_support.h │ └── void_bind.h ├── appveyor.yml ├── asserts ├── QR.png ├── grid.png └── pipeline.png ├── build_android.sh ├── change.log ├── ci ├── build-install-tools-windows.sh ├── build-install-tools.sh └── build.sh ├── cmake ├── SeetaFaceConfig.cmake └── cmake_uninstall.cmake.in ├── documents ├── FaceDetector.pdf ├── FaceLandmarks.pdf └── FaceRecognizer.pdf ├── example ├── CMakeLists.txt ├── SeetaExample │ └── SeetaExample.sln ├── crop_face │ ├── CMakeLists.txt │ ├── UserTemplate.xml │ ├── example.cpp │ └── seeta │ │ └── Struct_cv.h ├── points81 │ ├── 1.jpg │ ├── CMakeLists.txt │ ├── UserTemplate.xml │ ├── example.cpp │ ├── points81.vcxproj │ └── seeta │ │ └── Struct_cv.h ├── props │ ├── OpenCV2.props │ ├── OpenCV3.props │ ├── SeetaFaceDetector.props │ ├── SeetaFaceLandmarker.props │ ├── SeetaFaceRecognizer.props │ └── SeetaNet.props ├── search │ ├── 1.jpg │ ├── CMakeLists.txt │ ├── UserTemplate.xml │ ├── example.cpp │ ├── search.vcxproj │ └── seeta │ │ ├── FaceEngine.h │ │ └── Struct_cv.h └── tracking │ ├── CMakeLists.txt │ ├── UserTemplate.xml │ ├── example.cpp │ └── seeta │ └── Struct_cv.h └── ios ├── cmake.sh └── iOS.cmake /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | Makefile.Debug 3 | Makefile.Release 4 | Version.h 5 | Update/Update_*.xml 6 | *.bak 7 | *~ 8 | *.autosave 9 | *.qm 10 | *.user 11 | test.xml 12 | .CCodec.h.kate-swp 13 | .kdev4/ 14 | .kdev_include_paths 15 | .vs/ 16 | CMakeSettings.json 17 | build-*/ 18 | build/ 19 | build_android/ 20 | build_unix_mingw/ 21 | build_windows_mingw/ 22 | build_unix/ 23 | build_windows_msvc/ 24 | *.ncb 25 | .metadata/ 26 | *~ 27 | debug/ 28 | bin/ 29 | *.class 30 | .deps/ 31 | Makefile.in 32 | aclocal.m4 33 | config.guess 34 | config.h 35 | config.h.in 36 | config.h.in~ 37 | config.log 38 | config.status 39 | config.sub 40 | configure 41 | depcomp 42 | install-sh 43 | libtool 44 | ltmain.sh 45 | missing 46 | reachmonitor 47 | stamp-h1 48 | .deps/ 49 | Makefile.in 50 | aclocal.m4 51 | config.guess 52 | config.h 53 | config.h.in 54 | config.h.in~ 55 | config.log 56 | config.status 57 | config.sub 58 | configure 59 | depcomp 60 | install-sh 61 | libtool 62 | ltmain.sh 63 | missing 64 | stamp-h1 65 | *.bak 66 | *.bs 67 | *.la 68 | *.lo 69 | *.ft 70 | *.ft.1 71 | *.made 72 | *.o 73 | *.obj 74 | *.old 75 | *.orig 76 | *.out 77 | *.pdb 78 | *.rej 79 | .libs/ 80 | Makefile 81 | *.cdf 82 | *.cache 83 | *.obj 84 | *.ilk 85 | *.resources 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.rsp 91 | *.pgc 92 | *.pgd 93 | *.meta 94 | *.tlog 95 | *.manifest 96 | *.res 97 | *.pch 98 | *.exp 99 | *.idb 100 | *.rep 101 | *.xdc 102 | *.pdb 103 | *_manifest.rc 104 | *.bsc 105 | *.sbr 106 | *.opensdf 107 | *.sdf 108 | *.suo 109 | Debug/ 110 | release/ 111 | Release/ 112 | ipch/ 113 | rabbitim.kdev4 114 | *.pro.user.* 115 | Doxygen/ 116 | Doxyfile 117 | android/local.properties 118 | android/gradlew.* 119 | android/gradle.properties 120 | *.iml 121 | 122 | # Compiled Object files 123 | *.slo 124 | *.lo 125 | *.o 126 | *.obj 127 | 128 | # Precompiled Headers 129 | *.gch 130 | *.pch 131 | 132 | # Compiled Dynamic libraries 133 | *.so 134 | *.dylib 135 | *.dll 136 | 137 | # Fortran module files 138 | *.mod 139 | 140 | # Compiled Static libraries 141 | *.lai 142 | *.la 143 | *.a 144 | *.lib 145 | 146 | # Executables 147 | *.exe 148 | *.out 149 | *.app 150 | 151 | # Platform Specifics - auto generated files 152 | PlatformSpecifics/Windows/*.rc 153 | 154 | # Visual studio - project files 155 | *.sln 156 | *.suo 157 | *.vcxproj 158 | *.vcxproj.filters 159 | *.vcxproj.user 160 | 161 | # Visual Studio - Build Results 162 | [Dd]ebug/ 163 | [Rr]elease/ 164 | [Mm]in[Ss]ize[Rr]el/ 165 | [Rr]el[Ww]ith[Dd]eb[Ii]nfo/ 166 | 167 | # Visual Studio - Browsing Database File 168 | *.sdf 169 | *.opensdf 170 | 171 | #osx xcode 172 | DerivedData/ 173 | *.DS_Store 174 | *.build 175 | *.xcodeproj 176 | 177 | #CPACK related files 178 | CPackConfig-*.cmake 179 | _CPack_Packages/ 180 | 181 | #packages 182 | *.tar.gz 183 | *.zip 184 | 185 | android/.gradle/ 186 | android/.idea/ 187 | android/android.iml 188 | android/gradle/ 189 | android/gradlew 190 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: xenial 3 | language: cpp 4 | 5 | cache: 6 | - apt 7 | - directories: 8 | 9 | compiler: 10 | - g++ 11 | 12 | os: 13 | - unix 14 | 15 | addons: 16 | ssh_known_hosts: 17 | - github.com 18 | - frs.sourceforge.net 19 | 20 | env: 21 | global: 22 | - SOURCE_DIR=$TRAVIS_BUILD_DIR 23 | 24 | matrix: 25 | - BUILD_TARGERT="unix" BUILD_SHARED_LIBS=ON GENERATORS="Unix Makefiles" 26 | - BUILD_TARGERT="unix" BUILD_SHARED_LIBS=OFF GENERATORS="Unix Makefiles" 27 | 28 | - BUILD_TARGERT="android" BUILD_ARCH="armeabi-v7a with NEON" ANDROID_API=android-24 GENERATORS="Unix Makefiles" BUILD_SHARED_LIBS=OFF 29 | - BUILD_TARGERT="android" BUILD_ARCH="armeabi-v7a" ANDROID_API=android-18 ANDROID_ARM_NEON=ON GENERATORS="Unix Makefiles" BUILD_SHARED_LIBS=ON 30 | - BUILD_TARGERT="android" BUILD_ARCH="x86" ANDROID_API=android-18 GENERATORS="Unix Makefiles" BUILD_SHARED_LIBS=ON 31 | 32 | before_install: 33 | - echo "TRAVIS_OS_NAME=${TRAVIS_OS_NAME}" 34 | - sudo apt-get install -y -qq xvfb xpra 35 | - sudo Xvfb :99 -ac & 36 | - export DISPLAY=:99.0 37 | - mkdir ${SOURCE_DIR}/Tools 38 | - | 39 | export VERSION=`git describe --tags`; \ 40 | if [ -z "$VERSION" ]; then \ 41 | export VERSION=`git rev-parse --short HEAD` 42 | fi 43 | 44 | install: 45 | - cd ${SOURCE_DIR} 46 | - bash ci/build-install-tools.sh > /dev/null 47 | 48 | before_script: 49 | - cd ${SOURCE_DIR} 50 | 51 | script: 52 | - bash ${SOURCE_DIR}/ci/build.sh ${SOURCE_DIR} 53 | -------------------------------------------------------------------------------- /FaceDetector/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Author: Kang Lin 3 | # Date : 2019-08-20 4 | # 5 | 6 | cmake_minimum_required(VERSION 2.8) 7 | 8 | project(SeetaFaceDetector) 9 | 10 | add_definitions(-DSEETA_EXPORTS) 11 | 12 | file(GLOB_RECURSE ROOT_SRC_FILES 13 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c 14 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc 15 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp 16 | ) 17 | 18 | file(GLOB_RECURSE ROOT_SEETA_FILES 19 | ${CMAKE_CURRENT_SOURCE_DIR}/seeta/*.c 20 | ${CMAKE_CURRENT_SOURCE_DIR}/seeta/*.cc 21 | ${CMAKE_CURRENT_SOURCE_DIR}/seeta/*.cpp 22 | ) 23 | 24 | file(GLOB INCLUDE_FILES 25 | ${CMAKE_CURRENT_SOURCE_DIR}/include/seeta/*.h 26 | ${CMAKE_CURRENT_SOURCE_DIR}/include/seeta/*.hh 27 | ${CMAKE_CURRENT_SOURCE_DIR}/include/seeta/*.hpp 28 | ) 29 | 30 | list(APPEND SRC_FILES ${ROOT_SRC_FILES}) 31 | list(APPEND SRC_FILES ${ROOT_SEETA_FILES}) 32 | 33 | # add library 34 | add_library(${PROJECT_NAME} ${SRC_FILES}) 35 | target_include_directories(${PROJECT_NAME} PRIVATE 36 | ${CMAKE_CURRENT_SOURCE_DIR} 37 | ${PROJECT_SOURCE_DIR}/include 38 | ${PROJECT_SOURCE_DIR}/include/seeta 39 | ${PROJECT_SOURCE_DIR}/seeta 40 | ) 41 | target_include_directories(${PROJECT_NAME} PRIVATE 42 | ${CMAKE_SOURCE_DIR}/SeetaNet/include 43 | ) 44 | target_link_libraries(${PROJECT_NAME} PUBLIC SeetaNet) 45 | 46 | GENERATE_EXPORT_HEADER(${PROJECT_NAME} 47 | EXPORT_MACRO_NAME SEETA_DETECTOR_API 48 | EXPORT_FILE_NAME SeetaDetectorExport.h 49 | ) 50 | file(COPY ${CMAKE_CURRENT_BINARY_DIR}/SeetaDetectorExport.h 51 | DESTINATION ${CMAKE_BINARY_DIR}) 52 | install( 53 | FILES 54 | ${CMAKE_CURRENT_BINARY_DIR}/SeetaDetectorExport.h 55 | DESTINATION 56 | ${CMAKE_INSTALL_INCLUDEDIR}/seeta 57 | ) 58 | target_include_directories(${PROJECT_NAME} PRIVATE 59 | ${CMAKE_BINARY_DIR} 60 | ) 61 | 62 | set_target_properties(${PROJECT_NAME} PROPERTIES 63 | RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 64 | LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 65 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib 66 | VERSION ${BUILD_VERSION}) 67 | 68 | # Be will to install header files 69 | set_property(TARGET ${PROJECT_NAME} PROPERTY PUBLIC_HEADER ${INCLUDE_FILES}) 70 | 71 | if(WIN32) 72 | INSTALL(TARGETS ${PROJECT_NAME} 73 | EXPORT ${PROJECT_NAME}Config 74 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 75 | LIBRARY DESTINATION "${CMAKE_INSTALL_BINDIR}" 76 | ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 77 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/seeta 78 | INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 79 | ) 80 | else() 81 | INSTALL(TARGETS ${PROJECT_NAME} 82 | EXPORT ${PROJECT_NAME}Config 83 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 84 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 85 | ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 86 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/seeta 87 | INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 88 | ) 89 | endif() 90 | export(TARGETS ${PROJECT_NAME} 91 | APPEND FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake 92 | ) 93 | # Install cmake configure files 94 | install( 95 | EXPORT ${PROJECT_NAME}Config 96 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake" 97 | NAMESPACE 98 | SeetaFace:: 99 | ) 100 | write_basic_package_version_file( 101 | "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 102 | VERSION ${BUILD_VERSION} 103 | COMPATIBILITY AnyNewerVersion) 104 | install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake") 105 | 106 | # Install configure file 107 | set(SeetaFace2_LIBS "${PROJECT_NAME} ${SeetaFace2_LIBS}" PARENT_SCOPE) 108 | configure_file(FaceDetector.pc.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc @ONLY) 109 | install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc 110 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") 111 | -------------------------------------------------------------------------------- /FaceDetector/FaceDetector.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: @PROJECT_NAME@ 7 | Description: @PROJECT_NAME@ module 8 | Version: @BUILD_VERSION@ 9 | Requires: SeetaNet 10 | Requires.private: 11 | Conflicts: 12 | Libs: -L${libdir} @PROJECT_NAME@ 13 | Libs.private: 14 | Cflags: -I${includedir} 15 | -------------------------------------------------------------------------------- /FaceDetector/include/seeta/CFaceInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CStruct.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | struct SeetaFaceInfo 10 | { 11 | SeetaRect pos; 12 | float score; 13 | }; 14 | 15 | struct SeetaFaceInfoArray 16 | { 17 | struct SeetaFaceInfo *data; 18 | int size; 19 | }; 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /FaceDetector/include/seeta/CStruct.h: -------------------------------------------------------------------------------- 1 | #ifndef INC_SEETA_C_STRUCT_H 2 | #define INC_SEETA_C_STRUCT_H 3 | 4 | #ifdef _MSC_VER 5 | #ifdef SEETA_EXPORTS 6 | #define SEETA_API __declspec(dllexport) 7 | #else 8 | #define SEETA_API __declspec(dllimport) 9 | #endif 10 | #else 11 | #define SEETA_API __attribute__ ((visibility("default"))) 12 | #endif 13 | 14 | #define SEETA_C_API extern "C" SEETA_API 15 | 16 | #define INCLUDED_SEETA_CSTRUCT 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | 24 | struct SeetaImageData 25 | { 26 | int width; 27 | int height; 28 | int channels; 29 | unsigned char *data; 30 | }; 31 | 32 | struct SeetaPoint 33 | { 34 | int x; 35 | int y; 36 | }; 37 | 38 | struct SeetaPointF 39 | { 40 | double x; 41 | double y; 42 | }; 43 | 44 | struct SeetaSize 45 | { 46 | int width; 47 | int height; 48 | }; 49 | 50 | struct SeetaRect 51 | { 52 | int x; 53 | int y; 54 | int width; 55 | int height; 56 | }; 57 | 58 | struct SeetaRegion 59 | { 60 | int top; 61 | int bottom; 62 | int left; 63 | int right; 64 | }; 65 | 66 | enum SeetaDevice 67 | { 68 | SEETA_DEVICE_AUTO = 0, 69 | SEETA_DEVICE_CPU = 1, 70 | SEETA_DEVICE_GPU = 2, 71 | }; 72 | 73 | struct SeetaModelSetting 74 | { 75 | enum SeetaDevice device; 76 | int id; // when device is GPU, id means GPU id 77 | const char **model; // model string terminate with nullptr 78 | }; 79 | 80 | struct SeetaBuffer 81 | { 82 | void *buffer; 83 | int64_t size; 84 | }; 85 | 86 | struct SeetaModelBuffer 87 | { 88 | enum SeetaDevice device; 89 | int id; // when device is GPU, id means GPU id 90 | const SeetaBuffer *buffer; // input buffers, terminate with empty buffer(buffer=nullptr, size=0) 91 | }; 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif // INC_SEETA_C_STRUCT_H 98 | -------------------------------------------------------------------------------- /FaceDetector/include/seeta/FaceDetector.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by kier on 19-4-24. 3 | // 4 | 5 | #ifndef INC_SEETA_FACEDETECTOR_H 6 | #define INC_SEETA_FACEDETECTOR_H 7 | 8 | #include "Struct.h" 9 | #include "CFaceInfo.h" 10 | 11 | namespace seeta 12 | { 13 | namespace v2 14 | { 15 | 16 | class FaceDetector { 17 | public: 18 | enum Property 19 | { 20 | PROPERTY_MIN_FACE_SIZE, 21 | PROPERTY_THRESHOLD1, 22 | PROPERTY_THRESHOLD2, 23 | PROPERTY_THRESHOLD3, 24 | PROPERTY_VIDEO_STABLE, 25 | }; 26 | /** 27 | * \brief load model 28 | * \param [in] setting model file 29 | */ 30 | SEETA_API explicit FaceDetector( const SeetaModelSetting &setting ); 31 | 32 | /** 33 | * \brief load model 34 | * \param [in] setting model file 35 | * \param [in] core_width width of calculation core 36 | * \param [in] core_height height of calculation core 37 | */ 38 | SEETA_API explicit FaceDetector( const SeetaModelSetting &setting, int core_width, int core_height ); 39 | SEETA_API ~FaceDetector(); 40 | 41 | /** 42 | * \brief detect faces 43 | * \param [in] image image data to input 44 | * \return detected faces info array 45 | */ 46 | SEETA_API SeetaFaceInfoArray detect( const SeetaImageData &image ) const; 47 | 48 | /** 49 | * \brief set property 50 | * \param [in] property face detector property to set 51 | * \param [in] value value of corresponding property to set 52 | */ 53 | SEETA_API void set( Property property, double value ); 54 | 55 | /** 56 | * \brief get property 57 | * \param [in] property to get 58 | * \return property value to get 59 | */ 60 | SEETA_API double get( Property property ) const; 61 | 62 | private: 63 | FaceDetector( const FaceDetector & ) = delete; 64 | const FaceDetector &operator=( const FaceDetector & ) = delete; 65 | 66 | private: 67 | void *m_impl; 68 | }; 69 | } 70 | using namespace v2; 71 | } 72 | 73 | #endif //INC_SEETA_FACEDETECTOR_H 74 | -------------------------------------------------------------------------------- /FaceDetector/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | LOCAL_MODULE := seetanet-prebuilt 5 | LOCAL_SRC_FILES := $(LOCAL_PATH)/../../SeetaNet/libs/$(TARGET_ARCH_ABI)/libseetanet2.so 6 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../SeetaNet/include/ 7 | include $(PREBUILT_SHARED_LIBRARY) 8 | 9 | include $(CLEAR_VARS) 10 | 11 | LOCAL_MODULE := SeetaFaceDetector2 12 | 13 | MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/../seeta/*.cpp) 14 | MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/../src/seeta/*.cpp) 15 | 16 | LOCAL_SRC_FILES := $(MY_CPP_LIST:$(LOCAL_PATH)/%=%) 17 | 18 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/../ 19 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/../seeta/ 20 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include/ 21 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include/seeta/ 22 | 23 | LOCAL_LDFLAGS += -L$(LOCAL_PATH)/lib -fuse-ld=bfd 24 | 25 | LOCAL_LDLIBS += -llog -lz 26 | 27 | LOCAL_CFLAGS += -mfpu=neon-vfpv4 -funsafe-math-optimizations -ftree-vectorize -ffast-math 28 | 29 | LOCAL_SHARED_LIBRARIES += seetanet-prebuilt 30 | 31 | include $(BUILD_SHARED_LIBRARY) 32 | -------------------------------------------------------------------------------- /FaceDetector/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_STL := c++_static 2 | APP_CPPFLAGS := -std=c++11 3 | APP_CPPFLAGS += -fexceptions 4 | APP_CPPFLAGS += -fPIC -frtti -fpermissive 5 | APP_ABI := armeabi-v7a 6 | APP_OPTIM := release 7 | APP_PLATFORM := android-16 8 | -------------------------------------------------------------------------------- /FaceDetector/seeta/CommonStruct.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Struct.h" 4 | #include "DataHelper.h" 5 | #include 6 | 7 | namespace seeta 8 | { 9 | class Meanshape { 10 | public: 11 | std::vector points; 12 | Size size; 13 | }; 14 | 15 | class Landmarks { 16 | public: 17 | Landmarks() {}; 18 | std::vector points; 19 | }; 20 | 21 | class Image : public Blob { 22 | public: 23 | using self = Image; 24 | using supper = Blob; 25 | using Datum = uint8_t; 26 | 27 | Image( const SeetaImageData &vimg ) : Image( vimg.data, vimg.width, vimg.height, vimg.channels ) {} 28 | operator SeetaImageData() const { 29 | SeetaImageData vimg = { width(), height(), channels(), const_cast( data() ) }; 30 | return vimg; 31 | } 32 | Image( const ImageData &vimg ) : Image( vimg.data, vimg.width, vimg.height, vimg.channels ) {} 33 | operator ImageData() const { 34 | ImageData vimg( const_cast( data() ), width(), height(), channels() ); 35 | return std::move( vimg ); 36 | } 37 | 38 | Image( int width, int height, int channels ) 39 | : supper( height, width, channels ) { 40 | } 41 | 42 | Image( const uint8_t *data, int width, int height, int channels ) 43 | : supper( data, height, width, channels ) { 44 | } 45 | 46 | Image() 47 | : Image( 0, 0, 0 ) { 48 | } 49 | 50 | int height() const { 51 | return supper::shape( 1 ); 52 | } 53 | 54 | int width() const { 55 | return supper::shape( 2 ); 56 | } 57 | 58 | int channels() const { 59 | return supper::shape( 3 ); 60 | } 61 | 62 | template 63 | static Image FromBlob( const Blob &blob ) { 64 | if( blob.shape( 0 ) != 1 ) throw std::logic_error( "Can not convert multi images." ); 65 | Image image( blob.shape( 2 ), blob.shape( 1 ), blob.shape( 3 ) ); 66 | for( int i = 0; i < blob.count(); ++i ) { 67 | image[i] = static_cast( std::max( 0, std::min( 255, blob[i] ) ) ); 68 | } 69 | return std::move( image ); 70 | } 71 | 72 | }; 73 | 74 | inline void _out_str( std::ostream &out ) { } 75 | 76 | // there is no error anyway, this is a new feature about C++11 77 | template 78 | inline void _out_str( std::ostream &out, const T &t, Args... args ) 79 | { 80 | _out_str( out << t, args... ); 81 | } 82 | 83 | template 84 | inline const std::string str( Args... args ) 85 | { 86 | std::ostringstream oss; 87 | _out_str( oss, args... ); 88 | return std::move( oss.str() ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /FaceDetector/seeta/ImageProcess.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataHelper.h" 4 | #include "CommonStruct.h" 5 | #include "graphics2d.h" 6 | 7 | namespace seeta 8 | { 9 | enum SAMPLING_METHOD 10 | { 11 | BY_LINEAR, ///< 12 | BY_BICUBIC ///< Cubic 13 | }; 14 | 15 | const Image color( const Image &img ); 16 | const Image gray( const Image &img ); 17 | const Image crop( const Image &img, const Rect &rect ); 18 | using Padding = Size; 19 | const Image pad( const Image &img, const Padding &padding ); 20 | const Image resize( const Image &img, const Size &size ); 21 | const Image crop_resize( const Image &img, const Rect &rect, const Size &size ); 22 | const Image equalize_hist( const Image &img ); 23 | 24 | void fill( Image &img, const Point &point, const Image &patch ); 25 | void fill( Image &img, const Rect &rect, const Image &patch ); 26 | 27 | const Meanshape face_meanshape( int num, int id = 0 ); 28 | const Meanshape resize( const Meanshape &shape, double scaler ); 29 | const Meanshape resize( const Meanshape &shape, const Size &size ); 30 | const Image crop_face( const Image &img, const Meanshape &shape, const Landmarks &marks, SAMPLING_METHOD type ); 31 | const Image crop_face( const Image &img, const Meanshape &shape, const Landmarks &marks, SAMPLING_METHOD type, const Size &final_size ); 32 | const Image crop_face( const Image &img, const Meanshape &shape, const Landmarks &marks, SAMPLING_METHOD type, const Size &final_size, Landmarks &final_points ); 33 | 34 | // sample image with `size` on `image` by trasfromation 35 | const Image sample( const Image &image, const Size &size, const Trans2D &transformation ); 36 | } 37 | -------------------------------------------------------------------------------- /FaceDetector/seeta/SeetaFaceDetectorConfig.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SEETA_FACE_DETECTOR_MAJOR_VERSION 2 4 | #define SEETA_FACE_DETECTOR_MINOR_VERSION 5 5 | #define SEETA_FACE_DETECTOR_SINOR_VERSION 5 6 | 7 | #define SEETA_FACE_DETECTOR_LIBRARY_NAME "SeetaFaceDetector" 8 | 9 | #define SEETA_FACE_DETECTOR_NAMESPACE_VERSION v2 10 | -------------------------------------------------------------------------------- /FaceDetector/seeta/common_alignment.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETA_COMMON_ALIGNMENT_H 2 | #define _SEETA_COMMON_ALIGNMENT_H 3 | #include 4 | 5 | /** 6 | * \brief sample type 7 | */ 8 | enum SAMPLING_TYPE 9 | { 10 | LINEAR, ///< 11 | BICUBIC ///< 12 | }; 13 | 14 | /** 15 | * \brief type of padding value if sample out of image 16 | */ 17 | enum PADDING_TYPE 18 | { 19 | ZERO_PADDING, ///< 0 padding 20 | NEAREST_PADDING, ///< padding with value of nearest pixel 21 | }; 22 | 23 | /** 24 | * \brief Crop face 25 | * \param [in] image_data input image, format like height * width * channels 26 | * \param [in] image_width image width 27 | * \param [in] image_height image height 28 | * \param [in] image_channels image channels 29 | * \param [in] crop_data output [crop_width + pad_left + pad_right, crop_height + pad_top + pad_bottom, image_channels] 30 | * \param [in] crop_width output crop face width, based on meanshape, \b not output image size, infected by pad value 31 | * \param [in] crop_height output crop face height, based on meanshape, \b not output image size, infected by pad value 32 | * \param [in] points face landmark, format {(x1, y1), (x2, y2), ...} 33 | * \param [in] points_num number of landmark 34 | * \param [in] mean_shape meanshape, fomat {(x1, y1), (x2, y2), ...} 35 | * \param [in] mean_shape_width meanshape face width 36 | * \param [in] mean_shape_height meanshape face height 37 | * \param [in] pad_top pad on top, can be neg value 38 | * \param [in] pad_bottom pad on bottom, can be neg value 39 | * \param [in] pad_left pad on left, can be neg value 40 | * \param [in] pad_right pad on right, can be neg value 41 | * \param [out] final_points landmarks on cropped face {(x1, y1), (x2, y2), ...}, can be NULL. 42 | * \param [in] type method of sample 43 | * \return ture if succeed 44 | * \note final face data size should be [crop_width + pad_left + pad_right, crop_height + pad_top + pad_bottom] 45 | */ 46 | bool face_crop_core( 47 | const uint8_t *image_data, int image_width, int image_height, int image_channels, 48 | uint8_t *crop_data, int crop_width, int crop_height, 49 | const float *points, int points_num, 50 | const float *mean_shape, int mean_shape_width, int mean_shape_height, 51 | int pad_top = 0, int pad_bottom = 0, int pad_left = 0, int pad_right = 0, 52 | float *final_points = nullptr, 53 | SAMPLING_TYPE type = LINEAR ); 54 | 55 | bool face_crop_core_ex( 56 | const uint8_t *image_data, int image_width, int image_height, int image_channels, 57 | uint8_t *crop_data, int crop_width, int crop_height, 58 | const float *points, int points_num, 59 | const float *mean_shape, int mean_shape_width, int mean_shape_height, 60 | int pad_top = 0, int pad_bottom = 0, int pad_left = 0, int pad_right = 0, 61 | float *final_points = nullptr, 62 | SAMPLING_TYPE type = LINEAR, 63 | PADDING_TYPE ptype = ZERO_PADDING ); 64 | 65 | #endif // _SEETA_COMMON_ALIGNMENT_H 66 | -------------------------------------------------------------------------------- /FaceDetector/seeta/graphics2d.cpp: -------------------------------------------------------------------------------- 1 | #include "graphics2d.h" 2 | 3 | -------------------------------------------------------------------------------- /FaceDetector/src/seeta/FaceDetector.cpp: -------------------------------------------------------------------------------- 1 | #include "seeta/FaceDetector.h" 2 | #include 3 | #include 4 | #include 5 | #include "CStruct.h" 6 | #include "FaceDetectorPrivate.h" 7 | 8 | namespace seeta 9 | { 10 | namespace v2 11 | { 12 | 13 | //////////////////////////////////////////////////////////// 14 | FaceDetector::FaceDetector( const SeetaModelSetting &setting ) 15 | { 16 | m_impl = new FaceDetectorPrivate( setting.model[0], setting.device, setting.id ); 17 | } 18 | 19 | FaceDetector::FaceDetector( const SeetaModelSetting &setting, int core_width, int core_height ) 20 | { 21 | FaceDetectorPrivate::CoreSize coresize( core_width, core_height ); 22 | m_impl = new FaceDetectorPrivate( setting.model[0], coresize, setting.device, setting.id ); 23 | } 24 | FaceDetector::~FaceDetector() 25 | { 26 | FaceDetectorPrivate *ptr = ( FaceDetectorPrivate * )m_impl; 27 | delete ptr; 28 | m_impl = nullptr; 29 | } 30 | 31 | SeetaFaceInfoArray FaceDetector::detect( const SeetaImageData &image ) const 32 | { 33 | FaceDetectorPrivate *ptr = ( FaceDetectorPrivate * )m_impl; 34 | return ptr->Detect( image ); 35 | } 36 | 37 | void FaceDetector::set( FaceDetector::Property property, double value ) 38 | { 39 | FaceDetectorPrivate *ptr = ( FaceDetectorPrivate * )m_impl; 40 | // std::cout << "property: " << property << ", value: " << value << std::endl; 41 | switch( property ) 42 | { 43 | default: 44 | break; 45 | case FaceDetector::PROPERTY_THRESHOLD1: 46 | { 47 | ptr->SetScoreThresh1( float( value ) ); 48 | break; 49 | } 50 | case FaceDetector::PROPERTY_THRESHOLD2: 51 | { 52 | ptr->SetScoreThresh2( float( value ) ); 53 | break; 54 | } 55 | case FaceDetector::PROPERTY_THRESHOLD3: 56 | { 57 | ptr->SetScoreThresh3( float( value ) ); 58 | break; 59 | } 60 | case FaceDetector::PROPERTY_MIN_FACE_SIZE: 61 | ptr->SetMinFaceSize( int32_t( value ) ); 62 | break; 63 | case FaceDetector::PROPERTY_VIDEO_STABLE: 64 | ptr->SetVideoStable( value != 0 ); 65 | break; 66 | } 67 | 68 | } 69 | 70 | double FaceDetector::get( FaceDetector::Property property ) const 71 | { 72 | FaceDetectorPrivate *ptr = ( FaceDetectorPrivate * )m_impl; 73 | switch( property ) 74 | { 75 | default: 76 | return 0; 77 | case FaceDetector::PROPERTY_THRESHOLD1: 78 | return ptr->GetScoreThresh1(); 79 | 80 | case FaceDetector::PROPERTY_THRESHOLD2: 81 | return ptr->GetScoreThresh2(); 82 | case FaceDetector::PROPERTY_THRESHOLD3: 83 | return ptr->GetScoreThresh3(); 84 | 85 | case FaceDetector::PROPERTY_MIN_FACE_SIZE: 86 | return ptr->GetMinFaceSize(); 87 | 88 | case FaceDetector::PROPERTY_VIDEO_STABLE: 89 | return ptr->GetVideoStable() ? 1 : 0; 90 | } 91 | 92 | } 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /FaceLandmarker/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Author: Kang Lin 3 | # Date : 2019-08-20 4 | # 5 | 6 | cmake_minimum_required(VERSION 2.8) 7 | 8 | project(SeetaFaceLandmarker) 9 | 10 | add_definitions(-DSEETA_EXPORTS) 11 | 12 | file(GLOB_RECURSE ROOT_SRC_FILES 13 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c 14 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc 15 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp 16 | ) 17 | 18 | file(GLOB_RECURSE ROOT_SEETA_FILES 19 | ${CMAKE_CURRENT_SOURCE_DIR}/seeta/*.c 20 | ${CMAKE_CURRENT_SOURCE_DIR}/seeta/*.cc 21 | ${CMAKE_CURRENT_SOURCE_DIR}/seeta/*.cpp 22 | ) 23 | 24 | file(GLOB INCLUDE_FILES 25 | ${CMAKE_CURRENT_SOURCE_DIR}/include/seeta/*.h 26 | ${CMAKE_CURRENT_SOURCE_DIR}/include/seeta/*.hh 27 | ${CMAKE_CURRENT_SOURCE_DIR}/include/seeta/*.hpp 28 | ) 29 | 30 | list(APPEND SRC_FILES ${ROOT_SRC_FILES}) 31 | list(APPEND SRC_FILES ${ROOT_SEETA_FILES}) 32 | 33 | # add library 34 | add_library(${PROJECT_NAME} ${SRC_FILES}) 35 | target_include_directories(${PROJECT_NAME} PRIVATE 36 | ${CMAKE_CURRENT_SOURCE_DIR} 37 | ${PROJECT_SOURCE_DIR}/include 38 | ${PROJECT_SOURCE_DIR}/include/seeta 39 | ${PROJECT_SOURCE_DIR}/seeta 40 | ) 41 | target_include_directories(${PROJECT_NAME} PRIVATE 42 | ${CMAKE_SOURCE_DIR}/SeetaNet/include 43 | ) 44 | target_link_libraries(${PROJECT_NAME} PUBLIC SeetaNet) 45 | 46 | GENERATE_EXPORT_HEADER(${PROJECT_NAME} 47 | EXPORT_MACRO_NAME SEETA_LANDMARKER_API 48 | EXPORT_FILE_NAME SeetaLandmarkerExport.h 49 | ) 50 | file(COPY ${CMAKE_CURRENT_BINARY_DIR}/SeetaLandmarkerExport.h 51 | DESTINATION ${CMAKE_BINARY_DIR}) 52 | install( 53 | FILES 54 | ${CMAKE_CURRENT_BINARY_DIR}/SeetaLandmarkerExport.h 55 | DESTINATION 56 | ${CMAKE_INSTALL_INCLUDEDIR}/seeta 57 | ) 58 | target_include_directories(${PROJECT_NAME} PRIVATE 59 | ${CMAKE_BINARY_DIR} 60 | ) 61 | 62 | set_target_properties(${PROJECT_NAME} PROPERTIES 63 | RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 64 | LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 65 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib 66 | VERSION ${BUILD_VERSION}) 67 | # Be will to install header files 68 | set_property(TARGET ${PROJECT_NAME} PROPERTY PUBLIC_HEADER ${INCLUDE_FILES}) 69 | 70 | if(WIN32) 71 | INSTALL(TARGETS ${PROJECT_NAME} 72 | EXPORT ${PROJECT_NAME}Config 73 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 74 | LIBRARY DESTINATION "${CMAKE_INSTALL_BINDIR}" 75 | ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 76 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/seeta 77 | INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 78 | ) 79 | else() 80 | INSTALL(TARGETS ${PROJECT_NAME} 81 | EXPORT ${PROJECT_NAME}Config 82 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 83 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 84 | ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 85 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/seeta 86 | INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 87 | ) 88 | endif() 89 | export(TARGETS ${PROJECT_NAME} 90 | APPEND FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake 91 | ) 92 | # Install cmake configure files 93 | install( 94 | EXPORT ${PROJECT_NAME}Config 95 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake" 96 | NAMESPACE 97 | SeetaFace:: 98 | ) 99 | write_basic_package_version_file( 100 | "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 101 | VERSION ${BUILD_VERSION} 102 | COMPATIBILITY AnyNewerVersion) 103 | install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake") 104 | # Install configure file 105 | set(SeetaFace2_LIBS "${PROJECT_NAME} ${SeetaFace2_LIBS}" PARENT_SCOPE) 106 | configure_file(SeetaFaceLandmarker.pc.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc @ONLY) 107 | install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc 108 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") 109 | -------------------------------------------------------------------------------- /FaceLandmarker/SeetaFaceLandmarker.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: @PROJECT_NAME@ 7 | Description: @PROJECT_NAME@ module 8 | Version: @BUILD_VERSION@ 9 | Requires: SeetaNet 10 | Requires.private: 11 | Conflicts: 12 | Libs: -L${libdir} @PROJECT_NAME@ 13 | Libs.private: 14 | Cflags: -I${includedir} 15 | 16 | -------------------------------------------------------------------------------- /FaceLandmarker/include/seeta/CStruct.h: -------------------------------------------------------------------------------- 1 | #ifndef INC_SEETA_C_STRUCT_H 2 | #define INC_SEETA_C_STRUCT_H 3 | 4 | #ifdef _MSC_VER 5 | #ifdef SEETA_EXPORTS 6 | #define SEETA_API __declspec(dllexport) 7 | #else 8 | #define SEETA_API __declspec(dllimport) 9 | #endif 10 | #else 11 | #define SEETA_API __attribute__ ((visibility("default"))) 12 | #endif 13 | 14 | #define SEETA_C_API extern "C" SEETA_API 15 | 16 | #define INCLUDED_SEETA_CSTRUCT 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | 24 | struct SeetaImageData 25 | { 26 | int width; 27 | int height; 28 | int channels; 29 | unsigned char *data; 30 | }; 31 | 32 | struct SeetaPoint 33 | { 34 | int x; 35 | int y; 36 | }; 37 | 38 | struct SeetaPointF 39 | { 40 | double x; 41 | double y; 42 | }; 43 | 44 | struct SeetaSize 45 | { 46 | int width; 47 | int height; 48 | }; 49 | 50 | struct SeetaRect 51 | { 52 | int x; 53 | int y; 54 | int width; 55 | int height; 56 | }; 57 | 58 | struct SeetaRegion 59 | { 60 | int top; 61 | int bottom; 62 | int left; 63 | int right; 64 | }; 65 | 66 | enum SeetaDevice 67 | { 68 | SEETA_DEVICE_AUTO = 0, 69 | SEETA_DEVICE_CPU = 1, 70 | SEETA_DEVICE_GPU = 2, 71 | }; 72 | 73 | struct SeetaModelSetting 74 | { 75 | enum SeetaDevice device; 76 | int id; // when device is GPU, id means GPU id 77 | const char **model; // model string terminate with nullptr 78 | }; 79 | 80 | struct SeetaBuffer 81 | { 82 | void *buffer; 83 | int64_t size; 84 | }; 85 | 86 | struct SeetaModelBuffer 87 | { 88 | enum SeetaDevice device; 89 | int id; // when device is GPU, id means GPU id 90 | const SeetaBuffer *buffer; // input buffers, terminate with empty buffer(buffer=nullptr, size=0) 91 | }; 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif // INC_SEETA_C_STRUCT_H 98 | -------------------------------------------------------------------------------- /FaceLandmarker/include/seeta/FaceLandmarker.h: -------------------------------------------------------------------------------- 1 | #ifndef SEETA_FACELANDMARKER_FACELANDMARKER_H 2 | #define SEETA_FACELANDMARKER_FACELANDMARKER_H 3 | 4 | #include "Struct.h" 5 | 6 | namespace seeta 7 | { 8 | namespace v2 9 | { 10 | class FaceLandmarker { 11 | public: 12 | /** 13 | * \brief load model 14 | * \param [in] setting model file 15 | * \return 16 | */ 17 | SEETA_API explicit FaceLandmarker( const SeetaModelSetting &setting ); 18 | SEETA_API ~FaceLandmarker(); 19 | 20 | /** 21 | * \brief get face landmarks number 22 | * \return face landmarks number 23 | */ 24 | SEETA_API int number() const; 25 | 26 | /** 27 | * \brief detect face landmars of corresponding face 28 | * \param [in] image image data to input 29 | * \param [in] face face location 30 | * \param [out] points face landmarks 31 | */ 32 | SEETA_API void mark( const SeetaImageData &image, const SeetaRect &face, SeetaPointF *points ) const; 33 | 34 | /** 35 | * \brief detect face landmars of corresponding face 36 | * \param [in] image image data to input 37 | * \param [in] face face location 38 | * \return face landmarks 39 | */ 40 | std::vector mark( const SeetaImageData &image, const SeetaRect &face ) const { 41 | std::vector points( this->number() ); 42 | mark( image, face, points.data() ); 43 | return points; 44 | } 45 | 46 | private: 47 | FaceLandmarker( const FaceLandmarker & ) = delete; 48 | const FaceLandmarker &operator=( const FaceLandmarker & ) = delete; 49 | 50 | private: 51 | 52 | void *m_impl; 53 | }; 54 | } 55 | using namespace v2; 56 | } 57 | 58 | #endif //SEETA_FACELANDMARKER_FACELANDMARKER_H 59 | -------------------------------------------------------------------------------- /FaceLandmarker/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | 4 | include $(CLEAR_VARS) 5 | LOCAL_MODULE := seetanet-prebuilt 6 | LOCAL_SRC_FILES := $(LOCAL_PATH)/../../SeetaNet/libs/$(TARGET_ARCH_ABI)/libseetanet2.so 7 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../SeetaNet/include/ 8 | include $(PREBUILT_SHARED_LIBRARY) 9 | 10 | include $(CLEAR_VARS) 11 | 12 | LOCAL_MODULE := SeetaFaceLandmarker2 13 | 14 | MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/../seeta/*.cpp) 15 | MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/../src/seeta/*.cpp) 16 | 17 | LOCAL_SRC_FILES := $(MY_CPP_LIST:$(LOCAL_PATH)/%=%) 18 | 19 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/../ 20 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/../seeta/ 21 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include/ 22 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include/seeta/ 23 | 24 | LOCAL_LDFLAGS += -L$(LOCAL_PATH)/lib -fuse-ld=bfd 25 | 26 | LOCAL_LDLIBS += -llog -lz 27 | 28 | LOCAL_CFLAGS += -mfpu=neon-vfpv4 -funsafe-math-optimizations -ftree-vectorize -ffast-math 29 | 30 | LOCAL_SHARED_LIBRARIES += seetanet-prebuilt 31 | 32 | include $(BUILD_SHARED_LIBRARY) 33 | -------------------------------------------------------------------------------- /FaceLandmarker/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_STL := c++_static 2 | APP_CPPFLAGS := -std=c++11 3 | APP_CPPFLAGS += -fexceptions 4 | APP_CPPFLAGS += -fPIC -frtti -fpermissive 5 | APP_ABI := armeabi-v7a 6 | APP_OPTIM := release 7 | APP_PLATFORM := android-16 8 | -------------------------------------------------------------------------------- /FaceLandmarker/seeta/CFaceInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Common/CStruct.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | struct SeetaFaceInfo 10 | { 11 | SeetaRect pos; 12 | float score; 13 | }; 14 | 15 | struct SeetaFaceInfoArray 16 | { 17 | struct SeetaFaceInfo *data; 18 | int size; 19 | }; 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /FaceLandmarker/seeta/CommonStruct.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Struct.h" 4 | #include "DataHelper.h" 5 | #include 6 | 7 | namespace seeta 8 | { 9 | class Meanshape { 10 | public: 11 | std::vector points; 12 | Size size; 13 | }; 14 | 15 | class Landmarks { 16 | public: 17 | Landmarks() {}; 18 | std::vector points; 19 | }; 20 | 21 | class Image : public Blob { 22 | public: 23 | using self = Image; 24 | using supper = Blob; 25 | using Datum = uint8_t; 26 | 27 | Image( const SeetaImageData &vimg ) : Image( vimg.data, vimg.width, vimg.height, vimg.channels ) {} 28 | operator SeetaImageData() const { 29 | SeetaImageData vimg = { width(), height(), channels(), const_cast( data() ) }; 30 | return vimg; 31 | } 32 | Image( const ImageData &vimg ) : Image( vimg.data, vimg.width, vimg.height, vimg.channels ) {} 33 | operator ImageData() const { 34 | ImageData vimg( const_cast( data() ), width(), height(), channels() ); 35 | return std::move( vimg ); 36 | } 37 | 38 | Image( int width, int height, int channels ) 39 | : supper( height, width, channels ) { 40 | } 41 | 42 | Image( const uint8_t *data, int width, int height, int channels ) 43 | : supper( data, height, width, channels ) { 44 | } 45 | 46 | Image() 47 | : Image( 0, 0, 0 ) { 48 | } 49 | 50 | int height() const { 51 | return supper::shape( 1 ); 52 | } 53 | 54 | int width() const { 55 | return supper::shape( 2 ); 56 | } 57 | 58 | int channels() const { 59 | return supper::shape( 3 ); 60 | } 61 | 62 | template 63 | static Image FromBlob( const Blob &blob ) { 64 | if( blob.shape( 0 ) != 1 ) throw std::logic_error( "Can not convert multi images." ); 65 | Image image( blob.shape( 2 ), blob.shape( 1 ), blob.shape( 3 ) ); 66 | for( int i = 0; i < blob.count(); ++i ) { 67 | image[i] = static_cast( std::max( 0, std::min( 255, blob[i] ) ) ); 68 | } 69 | return std::move( image ); 70 | } 71 | 72 | }; 73 | 74 | inline void _out_str( std::ostream &out ) { } 75 | 76 | // there is no error anyway, this is a new feature about C++11 77 | template 78 | inline void _out_str( std::ostream &out, const T &t, Args... args ) 79 | { 80 | _out_str( out << t, args... ); 81 | } 82 | 83 | template 84 | inline const std::string str( Args... args ) 85 | { 86 | std::ostringstream oss; 87 | _out_str( oss, args... ); 88 | return std::move( oss.str() ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /FaceLandmarker/seeta/FaceLandmarkerPrivate.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETA_FACELANDMARKER_H_ 2 | #define _SEETA_FACELANDMARKER_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "CStruct.h" 8 | 9 | #include 10 | 11 | 12 | 13 | class FaceLandmarkerPrivate { 14 | public: 15 | FaceLandmarkerPrivate( const char *model_path = nullptr, SeetaDevice device = SEETA_DEVICE_AUTO, int gpuid = 0 ); 16 | ~FaceLandmarkerPrivate() { 17 | if( model_ != nullptr ) SeetaReleaseModel( model_ ); 18 | model_ = nullptr; 19 | if( seeta_net_ != nullptr ) SeetaReleaseNet( seeta_net_ ); 20 | seeta_net_ = nullptr; 21 | } 22 | 23 | void LoadModel( const char *model_path, SeetaDevice device, int gpuid = 0 ); 24 | 25 | void LoadModel( const char *buffer, int len, SeetaDevice device, int gpuid = 0 ); 26 | int LandmarkNum() const { 27 | return landmark_num_; 28 | } 29 | 30 | // need a cropped face 31 | bool PredictLandmark( const SeetaImageData &src_img, SeetaPointF *landmarks, int *masks ) const; 32 | bool PredictLandmark( const SeetaImageData &src_img, std::vector &landmarks, std::vector &masks ) const; 33 | 34 | bool PointDetectLandmarks( const SeetaImageData &src_img, const SeetaRect &face_info, SeetaPointF *landmarks, int *masks ) const; // interface used before 35 | 36 | private: 37 | int input_channels_; 38 | int input_height_; 39 | int input_width_; 40 | int landmark_num_; 41 | float x_move_; 42 | float y_move_; 43 | float expand_size_; 44 | 45 | 46 | ///////////////////// 47 | SeetaNet_Model *model_ = nullptr; 48 | SeetaNet_Net *seeta_net_ = nullptr; 49 | SeetaNet_SharedParam *param_ = nullptr; 50 | SeetaNet_DEVICE_TYPE type_; 51 | int gpuid_ = 0; 52 | bool isLoadModel() const { 53 | return seeta_net_ != nullptr; 54 | } 55 | void ShowModelInputShape() const; 56 | 57 | // need a cropped face image with correct size 58 | // corresponding to the model input size 59 | // output is in range [0,1] 60 | bool Predict( const SeetaImageData &src_img, std::vector &landmarks, std::vector &masks ) const; 61 | 62 | static void CropFace( const unsigned char *src_img, int src_width, int src_height, int src_channels, 63 | unsigned char *dst_img, int min_x, int min_y, int max_x, int max_y ); 64 | 65 | static bool ResizeImage( const unsigned char *src_im, int src_width, int src_height, int src_channels, 66 | unsigned char *dst_im, int dst_width, int dst_height, int dst_channels ); 67 | }; 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /FaceLandmarker/seeta/ImageProcess.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataHelper.h" 4 | #include "CommonStruct.h" 5 | #include "graphics2d.h" 6 | 7 | namespace seeta 8 | { 9 | enum SAMPLING_METHOD 10 | { 11 | BY_LINEAR, ///< 12 | BY_BICUBIC ///< Cubic 13 | }; 14 | 15 | const Image color( const Image &img ); 16 | const Image gray( const Image &img ); 17 | const Image crop( const Image &img, const Rect &rect ); 18 | using Padding = Size; 19 | const Image pad( const Image &img, const Padding &padding ); 20 | const Image resize( const Image &img, const Size &size ); 21 | const Image crop_resize( const Image &img, const Rect &rect, const Size &size ); 22 | const Image equalize_hist( const Image &img ); 23 | 24 | void fill( Image &img, const Point &point, const Image &patch ); 25 | void fill( Image &img, const Rect &rect, const Image &patch ); 26 | 27 | const Meanshape face_meanshape( int num, int id = 0 ); 28 | const Meanshape resize( const Meanshape &shape, double scaler ); 29 | const Meanshape resize( const Meanshape &shape, const Size &size ); 30 | const Image crop_face( const Image &img, const Meanshape &shape, const Landmarks &marks, SAMPLING_METHOD type ); 31 | const Image crop_face( const Image &img, const Meanshape &shape, const Landmarks &marks, SAMPLING_METHOD type, const Size &final_size ); 32 | const Image crop_face( const Image &img, const Meanshape &shape, const Landmarks &marks, SAMPLING_METHOD type, const Size &final_size, Landmarks &final_points ); 33 | 34 | // sample image with `size` on `image` by trasfromation 35 | const Image sample( const Image &image, const Size &size, const Trans2D &transformation ); 36 | } 37 | -------------------------------------------------------------------------------- /FaceLandmarker/seeta/SeetaFaceLandmarkerConfig.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SEETA_FACE_LANDMARKER_MAJOR_VERSION 2 4 | #define SEETA_FACE_LANDMARKER_MINOR_VERSION 5 5 | #define SEETA_FACE_LANDMARKER_SINOR_VERSION 5 6 | 7 | #define SEETA_FACE_LANDMARKER_LIBRARY_NAME "SeetaFaceLandmarker" 8 | 9 | #define SEETA_FACE_LANDMARKER_NAMESPACE_VERSION v2 10 | -------------------------------------------------------------------------------- /FaceLandmarker/seeta/SeetaFaceLandmarkerConfig.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SEETA_FACE_LANDMARKER_MAJOR_VERSION @SeetaFaceLandmarker_VERSION_MAJOR@ 4 | #define SEETA_FACE_LANDMARKER_MINOR_VERSION @SeetaFaceLandmarker_VERSION_MINOR@ 5 | #define SEETA_FACE_LANDMARKER_SINOR_VERSION @SeetaFaceLandmarker_VERSION_SINOR@ 6 | 7 | #define SEETA_FACE_LANDMARKER_LIBRARY_NAME "@SeetaFaceLandmarker_NAME@" 8 | 9 | #define SEETA_FACE_LANDMARKER_NAMESPACE_VERSION v@SeetaFaceLandmarker_VERSION_MAJOR@ 10 | -------------------------------------------------------------------------------- /FaceLandmarker/seeta/common_alignment.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETA_COMMON_ALIGNMENT_H 2 | #define _SEETA_COMMON_ALIGNMENT_H 3 | #include 4 | 5 | /** 6 | * \brief sample type 7 | */ 8 | enum SAMPLING_TYPE 9 | { 10 | LINEAR, ///< 11 | BICUBIC ///< 12 | }; 13 | 14 | /** 15 | * \brief type of padding value if sample out of image 16 | */ 17 | enum PADDING_TYPE 18 | { 19 | ZERO_PADDING, ///< 0 padding 20 | NEAREST_PADDING, ///< padding with value of nearest pixel 21 | }; 22 | 23 | /** 24 | * \brief Crop face 25 | * \param [in] image_data input image, format like height * width * channels 26 | * \param [in] image_width image width 27 | * \param [in] image_height image height 28 | * \param [in] image_channels image channels 29 | * \param [in] crop_data output [crop_width + pad_left + pad_right, crop_height + pad_top + pad_bottom, image_channels] 30 | * \param [in] crop_width output crop face width, based on meanshape, \b not output image size, infected by pad value 31 | * \param [in] crop_height output crop face height, based on meanshape, \b not output image size, infected by pad value 32 | * \param [in] points face landmark, format {(x1, y1), (x2, y2), ...} 33 | * \param [in] points_num number of landmark 34 | * \param [in] mean_shape meanshape, fomat {(x1, y1), (x2, y2), ...} 35 | * \param [in] mean_shape_width meanshape face width 36 | * \param [in] mean_shape_height meanshape face height 37 | * \param [in] pad_top pad on top, can be neg value 38 | * \param [in] pad_bottom pad on bottom, can be neg value 39 | * \param [in] pad_left pad on left, can be neg value 40 | * \param [in] pad_right pad on right, can be neg value 41 | * \param [out] final_points landmarks on cropped face {(x1, y1), (x2, y2), ...}, can be NULL. 42 | * \param [in] type method of sample 43 | * \return ture if succeed 44 | * \note final face data size should be [crop_width + pad_left + pad_right, crop_height + pad_top + pad_bottom] 45 | */ 46 | bool face_crop_core( 47 | const uint8_t *image_data, int image_width, int image_height, int image_channels, 48 | uint8_t *crop_data, int crop_width, int crop_height, 49 | const float *points, int points_num, 50 | const float *mean_shape, int mean_shape_width, int mean_shape_height, 51 | int pad_top = 0, int pad_bottom = 0, int pad_left = 0, int pad_right = 0, 52 | float *final_points = nullptr, 53 | SAMPLING_TYPE type = LINEAR ); 54 | 55 | bool face_crop_core_ex( 56 | const uint8_t *image_data, int image_width, int image_height, int image_channels, 57 | uint8_t *crop_data, int crop_width, int crop_height, 58 | const float *points, int points_num, 59 | const float *mean_shape, int mean_shape_width, int mean_shape_height, 60 | int pad_top = 0, int pad_bottom = 0, int pad_left = 0, int pad_right = 0, 61 | float *final_points = nullptr, 62 | SAMPLING_TYPE type = LINEAR, 63 | PADDING_TYPE ptype = ZERO_PADDING ); 64 | 65 | #endif // _SEETA_COMMON_ALIGNMENT_H 66 | -------------------------------------------------------------------------------- /FaceLandmarker/seeta/graphics2d.cpp: -------------------------------------------------------------------------------- 1 | #include "graphics2d.h" 2 | 3 | -------------------------------------------------------------------------------- /FaceLandmarker/src/seeta/FaceLandmarker.cpp: -------------------------------------------------------------------------------- 1 | #include "seeta/FaceLandmarker.h" 2 | #include "common_alignment.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include "FaceLandmarkerPrivate.h" 11 | 12 | namespace seeta 13 | { 14 | namespace v2 15 | { 16 | 17 | FaceLandmarker::FaceLandmarker( const SeetaModelSetting &setting ) 18 | : m_impl( new FaceLandmarkerPrivate( setting.model[0], setting.device, setting.id ) ) 19 | { 20 | 21 | } 22 | 23 | FaceLandmarker::~FaceLandmarker() 24 | { 25 | FaceLandmarkerPrivate *ptr = ( FaceLandmarkerPrivate * )m_impl; 26 | delete ptr; 27 | ptr = nullptr; 28 | } 29 | 30 | int FaceLandmarker::number() const 31 | { 32 | 33 | FaceLandmarkerPrivate *ptr = ( FaceLandmarkerPrivate * )m_impl; 34 | return ptr->LandmarkNum(); 35 | } 36 | 37 | void FaceLandmarker::mark( const SeetaImageData &image, const SeetaRect &face, SeetaPointF *points ) const 38 | { 39 | FaceLandmarkerPrivate *ptr = ( FaceLandmarkerPrivate * )m_impl; 40 | bool result = ptr->PointDetectLandmarks( image, face, points, nullptr ); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /FaceRecognizer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Author: Kang Lin 3 | # Date : 2019-08-20 4 | # 5 | 6 | cmake_minimum_required(VERSION 2.8) 7 | 8 | project(SeetaFaceRecognizer) 9 | 10 | add_definitions(-DSEETA_EXPORTS) 11 | 12 | file(GLOB_RECURSE ROOT_SRC_FILES 13 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c 14 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc 15 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp 16 | ) 17 | 18 | file(GLOB_RECURSE ROOT_SEETA_FILES 19 | ${CMAKE_CURRENT_SOURCE_DIR}/seeta/*.c 20 | ${CMAKE_CURRENT_SOURCE_DIR}/seeta/*.cc 21 | ${CMAKE_CURRENT_SOURCE_DIR}/seeta/*.cpp 22 | ) 23 | 24 | file(GLOB INCLUDE_FILES 25 | ${CMAKE_CURRENT_SOURCE_DIR}/include/seeta/*.h 26 | ${CMAKE_CURRENT_SOURCE_DIR}/include/seeta/*.hh 27 | ${CMAKE_CURRENT_SOURCE_DIR}/include/seeta/*.hpp 28 | ) 29 | 30 | list(APPEND SRC_FILES ${ROOT_SRC_FILES}) 31 | list(APPEND SRC_FILES ${ROOT_SEETA_FILES}) 32 | 33 | # add library 34 | add_library(${PROJECT_NAME} ${SRC_FILES}) 35 | target_include_directories(${PROJECT_NAME} PRIVATE 36 | ${CMAKE_CURRENT_SOURCE_DIR} 37 | ${PROJECT_SOURCE_DIR}/include 38 | ${PROJECT_SOURCE_DIR}/include/seeta 39 | ${PROJECT_SOURCE_DIR}/seeta 40 | ) 41 | target_include_directories(${PROJECT_NAME} PRIVATE 42 | ${CMAKE_SOURCE_DIR}/SeetaNet/include 43 | ) 44 | target_link_libraries(${PROJECT_NAME} PUBLIC SeetaNet) 45 | 46 | GENERATE_EXPORT_HEADER(${PROJECT_NAME} 47 | EXPORT_MACRO_NAME SEETA_RECOGNIZER_API 48 | EXPORT_FILE_NAME SeetaRecognizerExport.h 49 | ) 50 | file(COPY ${CMAKE_CURRENT_BINARY_DIR}/SeetaRecognizerExport.h 51 | DESTINATION ${CMAKE_BINARY_DIR}) 52 | install( 53 | FILES 54 | ${CMAKE_CURRENT_BINARY_DIR}/SeetaRecognizerExport.h 55 | DESTINATION 56 | ${CMAKE_INSTALL_INCLUDEDIR}/seeta 57 | ) 58 | target_include_directories(${PROJECT_NAME} PRIVATE 59 | ${CMAKE_BINARY_DIR} 60 | ) 61 | 62 | set_target_properties(${PROJECT_NAME} PROPERTIES 63 | RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 64 | LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 65 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib 66 | VERSION ${BUILD_VERSION}) 67 | # Be will to install header files 68 | set_property(TARGET ${PROJECT_NAME} PROPERTY PUBLIC_HEADER ${INCLUDE_FILES}) 69 | 70 | if(WIN32) 71 | INSTALL(TARGETS ${PROJECT_NAME} 72 | EXPORT ${PROJECT_NAME}Config 73 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 74 | LIBRARY DESTINATION "${CMAKE_INSTALL_BINDIR}" 75 | ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 76 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/seeta 77 | INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 78 | ) 79 | else() 80 | INSTALL(TARGETS ${PROJECT_NAME} 81 | EXPORT ${PROJECT_NAME}Config 82 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 83 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 84 | ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 85 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/seeta 86 | INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 87 | ) 88 | endif() 89 | export(TARGETS ${PROJECT_NAME} 90 | APPEND FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake 91 | ) 92 | # Install cmake configure files 93 | install( 94 | EXPORT ${PROJECT_NAME}Config 95 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake" 96 | NAMESPACE 97 | SeetaFace:: 98 | ) 99 | write_basic_package_version_file( 100 | "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 101 | VERSION ${BUILD_VERSION} 102 | COMPATIBILITY AnyNewerVersion) 103 | install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake") 104 | # Install configure file 105 | set(SeetaFace2_LIBS "${PROJECT_NAME} ${SeetaFace2_LIBS}" PARENT_SCOPE) 106 | configure_file(FaceRecognizer.pc.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc @ONLY) 107 | install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc 108 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") 109 | -------------------------------------------------------------------------------- /FaceRecognizer/FaceRecognizer.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: @PROJECT_NAME@ 7 | Description: @PROJECT_NAME@ module 8 | Version: @BUILD_VERSION@ 9 | Requires: SeetaNet 10 | Requires.private: 11 | Conflicts: 12 | Libs: -L${libdir} @PROJECT_NAME@ 13 | Libs.private: 14 | Cflags: -I${includedir} 15 | -------------------------------------------------------------------------------- /FaceRecognizer/include/seeta/CStream.h: -------------------------------------------------------------------------------- 1 | #ifndef INC_SEETA_C_STREAM_H 2 | #define INC_SEETA_C_STREAM_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | 11 | typedef size_t SeetaStreamWrite( void *obj, const char *data, size_t length ); 12 | typedef size_t SeetaStreamRead( void *obj, char *data, size_t length ); 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | 18 | #endif // INC_SEETA_C_STREAM_H 19 | -------------------------------------------------------------------------------- /FaceRecognizer/include/seeta/CStruct.h: -------------------------------------------------------------------------------- 1 | #ifndef INC_SEETA_C_STRUCT_H 2 | #define INC_SEETA_C_STRUCT_H 3 | 4 | #ifdef _MSC_VER 5 | #ifdef SEETA_EXPORTS 6 | #define SEETA_API __declspec(dllexport) 7 | #else 8 | #define SEETA_API __declspec(dllimport) 9 | #endif 10 | #else 11 | #define SEETA_API __attribute__ ((visibility("default"))) 12 | #endif 13 | 14 | #define SEETA_C_API extern "C" SEETA_API 15 | 16 | #define INCLUDED_SEETA_CSTRUCT 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | 24 | struct SeetaImageData 25 | { 26 | int width; 27 | int height; 28 | int channels; 29 | unsigned char *data; 30 | }; 31 | 32 | struct SeetaPoint 33 | { 34 | int x; 35 | int y; 36 | }; 37 | 38 | struct SeetaPointF 39 | { 40 | double x; 41 | double y; 42 | }; 43 | 44 | struct SeetaSize 45 | { 46 | int width; 47 | int height; 48 | }; 49 | 50 | struct SeetaRect 51 | { 52 | int x; 53 | int y; 54 | int width; 55 | int height; 56 | }; 57 | 58 | struct SeetaRegion 59 | { 60 | int top; 61 | int bottom; 62 | int left; 63 | int right; 64 | }; 65 | 66 | enum SeetaDevice 67 | { 68 | SEETA_DEVICE_AUTO = 0, 69 | SEETA_DEVICE_CPU = 1, 70 | SEETA_DEVICE_GPU = 2, 71 | }; 72 | 73 | struct SeetaModelSetting 74 | { 75 | enum SeetaDevice device; 76 | int id; // when device is GPU, id means GPU id 77 | const char **model; // model string terminate with nullptr 78 | }; 79 | 80 | struct SeetaBuffer 81 | { 82 | void *buffer; 83 | int64_t size; 84 | }; 85 | 86 | struct SeetaModelBuffer 87 | { 88 | enum SeetaDevice device; 89 | int id; // when device is GPU, id means GPU id 90 | const SeetaBuffer *buffer; // input buffers, terminate with empty buffer(buffer=nullptr, size=0) 91 | }; 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif // INC_SEETA_C_STRUCT_H 98 | -------------------------------------------------------------------------------- /FaceRecognizer/include/seeta/FaceRecognizer.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by kier on 19-4-24. 3 | // 4 | 5 | #ifndef SEETA_FACERECOGNIZER_FACERECOGNIZER_H 6 | #define SEETA_FACERECOGNIZER_FACERECOGNIZER_H 7 | 8 | #include "CStruct.h" 9 | #include "Struct.h" 10 | 11 | namespace seeta 12 | { 13 | namespace v2 14 | { 15 | class FaceRecognizer { 16 | public: 17 | /** 18 | * \brief load model 19 | * \param [in] setting model file 20 | * \note if setting contains no model, construct as FaceRecognizer::FaceRecognizer(). 21 | */ 22 | SEETA_API explicit FaceRecognizer( const SeetaModelSetting &setting ); 23 | 24 | /** 25 | * \brief default construct FR, only CropFace supported to crop 256x256 faces. 26 | */ 27 | SEETA_API explicit FaceRecognizer(); 28 | 29 | SEETA_API ~FaceRecognizer(); 30 | 31 | /** 32 | * \brief get cropped face width 33 | * \return cropped face width 34 | */ 35 | SEETA_API int GetCropFaceWidth(); 36 | 37 | /** 38 | * \brief get cropped face height 39 | * \return cropped face height 40 | */ 41 | SEETA_API int GetCropFaceHeight(); 42 | 43 | /** 44 | * \brief get cropped face channels 45 | * \return cropped face channels 46 | */ 47 | SEETA_API int GetCropFaceChannels(); 48 | 49 | /** 50 | * \brief crop face 51 | * \param [in] image image data to input 52 | * \param [in] points face landmars 53 | * \param [out] face cropped face data 54 | */ 55 | SEETA_API bool CropFace( const SeetaImageData &image, const SeetaPointF *points, SeetaImageData &face ); 56 | 57 | seeta::ImageData CropFace(const SeetaImageData &image, const SeetaPointF *points) { 58 | seeta::ImageData face(this->GetCropFaceWidth(), this->GetCropFaceHeight(), this->GetCropFaceChannels()); 59 | CropFace(image, points, face); 60 | return face; 61 | } 62 | 63 | /** 64 | * \brief get extracted feature size 65 | * \return extracted feature size 66 | */ 67 | SEETA_API int GetExtractFeatureSize() const; 68 | 69 | /** 70 | * \brief extract cropped face image's feature 71 | * \param [in] image face image data to input 72 | * \param [out] features extracted features of face 73 | * \return true if extract feature success 74 | */ 75 | SEETA_API bool ExtractCroppedFace( const SeetaImageData &image, float *features ) const; 76 | 77 | /** 78 | * \brief extract face feature in origin image 79 | * \param [in] image origin image data to input 80 | * \param [in] points face landmarks 81 | * \param [out] feature face feature extracted 82 | * \return true if extract feature success 83 | */ 84 | SEETA_API bool Extract( const SeetaImageData &image, const SeetaPointF *points, float *features ) const; 85 | 86 | /** 87 | * \brief calculate two faces's similarity 88 | * \param [in] features1 face1 features 89 | * \param [in] features2 face2 features 90 | * \return two faces similarity 91 | */ 92 | SEETA_API float CalculateSimilarity( const float *features1, const float *features2 ) const; 93 | 94 | 95 | private: 96 | FaceRecognizer( const FaceRecognizer & ) = delete; 97 | const FaceRecognizer &operator=( const FaceRecognizer & ) = delete; 98 | 99 | private: 100 | void *m_impl; 101 | }; 102 | } 103 | using namespace v2; 104 | } 105 | 106 | #endif //SEETA_FACERECOGNIZER_FACERECOGNIZER_H 107 | -------------------------------------------------------------------------------- /FaceRecognizer/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | LOCAL_MODULE := seetanet-prebuilt 5 | LOCAL_SRC_FILES := $(LOCAL_PATH)/../../SeetaNet/libs/$(TARGET_ARCH_ABI)/libseetanet2.so 6 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../SeetaNet/include/ 7 | include $(PREBUILT_SHARED_LIBRARY) 8 | 9 | include $(CLEAR_VARS) 10 | 11 | LOCAL_MODULE := SeetaFaceRecognizer2 12 | 13 | MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/../seeta/*.cpp) 14 | MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/../src/seeta/*.cpp) 15 | 16 | LOCAL_SRC_FILES := $(MY_CPP_LIST:$(LOCAL_PATH)/%=%) 17 | 18 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/../ 19 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/../seeta/ 20 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include/ 21 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include/seeta/ 22 | 23 | LOCAL_LDFLAGS += -L$(LOCAL_PATH)/lib -fuse-ld=bfd 24 | 25 | LOCAL_LDLIBS += -llog -lz 26 | 27 | LOCAL_CFLAGS += -mfpu=neon-vfpv4 -funsafe-math-optimizations -ftree-vectorize -ffast-math 28 | 29 | LOCAL_SHARED_LIBRARIES += seetanet-prebuilt 30 | 31 | include $(BUILD_SHARED_LIBRARY) 32 | -------------------------------------------------------------------------------- /FaceRecognizer/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_STL := c++_static 2 | APP_CPPFLAGS := -std=c++11 3 | APP_CPPFLAGS += -fexceptions 4 | APP_CPPFLAGS += -fPIC -frtti -fpermissive 5 | APP_ABI := armeabi-v7a 6 | APP_OPTIM := release 7 | APP_PLATFORM := android-16 8 | -------------------------------------------------------------------------------- /FaceRecognizer/seeta/CFaceInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Common/CStruct.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | struct SeetaFaceInfo 10 | { 11 | SeetaRect pos; 12 | float score; 13 | }; 14 | 15 | struct SeetaFaceInfoArray 16 | { 17 | struct SeetaFaceInfo *data; 18 | int size; 19 | }; 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /FaceRecognizer/seeta/CommonStruct.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Struct.h" 4 | #include "DataHelper.h" 5 | #include 6 | 7 | namespace seeta 8 | { 9 | class Meanshape { 10 | public: 11 | std::vector points; 12 | Size size; 13 | }; 14 | 15 | class Landmarks { 16 | public: 17 | Landmarks() {}; 18 | std::vector points; 19 | }; 20 | 21 | class Image : public Blob { 22 | public: 23 | using self = Image; 24 | using supper = Blob; 25 | using Datum = uint8_t; 26 | 27 | Image( const SeetaImageData &vimg ) : Image( vimg.data, vimg.width, vimg.height, vimg.channels ) {} 28 | operator SeetaImageData() const { 29 | SeetaImageData vimg = { width(), height(), channels(), const_cast( data() ) }; 30 | return vimg; 31 | } 32 | Image( const ImageData &vimg ) : Image( vimg.data, vimg.width, vimg.height, vimg.channels ) {} 33 | operator ImageData() const { 34 | ImageData vimg( const_cast( data() ), width(), height(), channels() ); 35 | return std::move( vimg ); 36 | } 37 | 38 | Image( int width, int height, int channels ) 39 | : supper( height, width, channels ) { 40 | } 41 | 42 | Image( const uint8_t *data, int width, int height, int channels ) 43 | : supper( data, height, width, channels ) { 44 | } 45 | 46 | Image() 47 | : Image( 0, 0, 0 ) { 48 | } 49 | 50 | int height() const { 51 | return supper::shape( 1 ); 52 | } 53 | 54 | int width() const { 55 | return supper::shape( 2 ); 56 | } 57 | 58 | int channels() const { 59 | return supper::shape( 3 ); 60 | } 61 | 62 | template 63 | static Image FromBlob( const Blob &blob ) { 64 | if( blob.shape( 0 ) != 1 ) throw std::logic_error( "Can not convert multi images." ); 65 | Image image( blob.shape( 2 ), blob.shape( 1 ), blob.shape( 3 ) ); 66 | for( int i = 0; i < blob.count(); ++i ) { 67 | image[i] = static_cast( std::max( 0, std::min( 255, blob[i] ) ) ); 68 | } 69 | return std::move( image ); 70 | } 71 | 72 | }; 73 | 74 | inline void _out_str( std::ostream &out ) { } 75 | 76 | // there is no error anyway, this is a new feature about C++11 77 | template 78 | inline void _out_str( std::ostream &out, const T &t, Args... args ) 79 | { 80 | _out_str( out << t, args... ); 81 | } 82 | 83 | template 84 | inline const std::string str( Args... args ) 85 | { 86 | std::ostringstream oss; 87 | _out_str( oss, args... ); 88 | return std::move( oss.str() ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /FaceRecognizer/seeta/ImageProcess.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataHelper.h" 4 | #include "CommonStruct.h" 5 | #include "graphics2d.h" 6 | 7 | namespace seeta 8 | { 9 | enum SAMPLING_METHOD 10 | { 11 | BY_LINEAR, ///< 12 | BY_BICUBIC ///< Cubic 13 | }; 14 | 15 | const Image color( const Image &img ); 16 | const Image gray( const Image &img ); 17 | const Image crop( const Image &img, const Rect &rect ); 18 | using Padding = Size; 19 | const Image pad( const Image &img, const Padding &padding ); 20 | const Image resize( const Image &img, const Size &size ); 21 | const Image crop_resize( const Image &img, const Rect &rect, const Size &size ); 22 | const Image equalize_hist( const Image &img ); 23 | 24 | void fill( Image &img, const Point &point, const Image &patch ); 25 | void fill( Image &img, const Rect &rect, const Image &patch ); 26 | 27 | const Meanshape face_meanshape( int num, int id = 0 ); 28 | const Meanshape resize( const Meanshape &shape, double scaler ); 29 | const Meanshape resize( const Meanshape &shape, const Size &size ); 30 | const Image crop_face( const Image &img, const Meanshape &shape, const Landmarks &marks, SAMPLING_METHOD type ); 31 | const Image crop_face( const Image &img, const Meanshape &shape, const Landmarks &marks, SAMPLING_METHOD type, const Size &final_size ); 32 | const Image crop_face( const Image &img, const Meanshape &shape, const Landmarks &marks, SAMPLING_METHOD type, const Size &final_size, Landmarks &final_points ); 33 | 34 | // sample image with `size` on `image` by trasfromation 35 | const Image sample( const Image &image, const Size &size, const Trans2D &transformation ); 36 | } 37 | -------------------------------------------------------------------------------- /FaceRecognizer/seeta/SeetaFaceRecognizerConfig.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SEETA_FACE_RECOGNIZER_MAJOR_VERSION 2 4 | #define SEETA_FACE_RECOGNIZER_MINOR_VERSION 5 5 | #define SEETA_FACE_RECOGNIZER_SINOR_VERSION 5 6 | 7 | #define SEETA_FACE_RECOGNIZER_LIBRARY_NAME "SeetaFaceRecognizer" 8 | 9 | #define SEETA_FACE_RECOGNIZER_NAMESPACE_VERSION v2 10 | -------------------------------------------------------------------------------- /FaceRecognizer/seeta/SeetaFaceRecognizerConfig.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SEETA_FACE_RECOGNIZER_MAJOR_VERSION @SeetaFaceRecognizer_VERSION_MAJOR@ 4 | #define SEETA_FACE_RECOGNIZER_MINOR_VERSION @SeetaFaceRecognizer_VERSION_MINOR@ 5 | #define SEETA_FACE_RECOGNIZER_SINOR_VERSION @SeetaFaceRecognizer_VERSION_SINOR@ 6 | 7 | #define SEETA_FACE_RECOGNIZER_LIBRARY_NAME "@SeetaFaceRecognizer_NAME@" 8 | 9 | #define SEETA_FACE_RECOGNIZER_NAMESPACE_VERSION v@SeetaFaceRecognizer_VERSION_MAJOR@ 10 | -------------------------------------------------------------------------------- /FaceRecognizer/seeta/SeetaNetParseProto.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_PARSE_PROTO_HELPER_H 2 | #define _SEETANET_PARSE_PROTO_HELPER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using std::vector; 10 | using std::string; 11 | 12 | int read( const char *buf, int len, int32_t &value ); 13 | int read( const char *buf, int len, uint32_t &value ); 14 | int read( const char *buf, int len, bool &value ); 15 | int read( const char *buf, int len, float &value ); 16 | int read( const char *buf, int len, vector &value ); 17 | int read( const char *buf, int len, vector &value ); 18 | int read( const char *buf, int len, vector &value ); 19 | int read( const char *buf, int len, std::string &value ); 20 | int read( const char *buf, int len, vector &value ); 21 | 22 | int write( char *buf, int len, int32_t value ); 23 | int write( char *buf, int len, uint32_t value ); 24 | int write( char *buf, int len, bool value ); 25 | int write( char *buf, int len, float value ); 26 | int write( char *buf, int len, const vector &value ); 27 | int write( char *buf, int len, const vector &value ); 28 | int write( char *buf, int len, const vector &value ); 29 | 30 | int write( char *buf, int len, const std::string &value ); 31 | int write( char *buf, int len, const vector &value ); 32 | 33 | 34 | int WriteStringToFile( const std::string &input_string, std::fstream &outputfstream ); 35 | int WriteStringVectorToFile( const std::vector &vec, std::fstream &outputfstream ); 36 | 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /FaceRecognizer/seeta/common_alignment.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETA_COMMON_ALIGNMENT_H 2 | #define _SEETA_COMMON_ALIGNMENT_H 3 | #include 4 | 5 | /** 6 | * \brief sample type 7 | */ 8 | enum SAMPLING_TYPE 9 | { 10 | LINEAR, ///< 11 | BICUBIC ///< 12 | }; 13 | 14 | /** 15 | * \brief type of padding value if sample out of image 16 | */ 17 | enum PADDING_TYPE 18 | { 19 | ZERO_PADDING, ///< 0 padding 20 | NEAREST_PADDING, ///< padding with value of nearest pixel 21 | }; 22 | 23 | /** 24 | * \brief Crop face 25 | * \param [in] image_data input image, format like height * width * channels 26 | * \param [in] image_width image width 27 | * \param [in] image_height image height 28 | * \param [in] image_channels image channels 29 | * \param [in] crop_data output [crop_width + pad_left + pad_right, crop_height + pad_top + pad_bottom, image_channels] 30 | * \param [in] crop_width output crop face width, based on meanshape, \b not output image size, infected by pad value 31 | * \param [in] crop_height output crop face height, based on meanshape, \b not output image size, infected by pad value 32 | * \param [in] points face landmark, format {(x1, y1), (x2, y2), ...} 33 | * \param [in] points_num number of landmark 34 | * \param [in] mean_shape meanshape, fomat {(x1, y1), (x2, y2), ...} 35 | * \param [in] mean_shape_width meanshape face width 36 | * \param [in] mean_shape_height meanshape face height 37 | * \param [in] pad_top pad on top, can be neg value 38 | * \param [in] pad_bottom pad on bottom, can be neg value 39 | * \param [in] pad_left pad on left, can be neg value 40 | * \param [in] pad_right pad on right, can be neg value 41 | * \param [out] final_points landmarks on cropped face {(x1, y1), (x2, y2), ...}, can be NULL. 42 | * \param [in] type method of sample 43 | * \return ture if succeed 44 | * \note final face data size should be [crop_width + pad_left + pad_right, crop_height + pad_top + pad_bottom] 45 | */ 46 | bool face_crop_core( 47 | const uint8_t *image_data, int image_width, int image_height, int image_channels, 48 | uint8_t *crop_data, int crop_width, int crop_height, 49 | const float *points, int points_num, 50 | const float *mean_shape, int mean_shape_width, int mean_shape_height, 51 | int pad_top = 0, int pad_bottom = 0, int pad_left = 0, int pad_right = 0, 52 | float *final_points = nullptr, 53 | SAMPLING_TYPE type = LINEAR ); 54 | 55 | bool face_crop_core_ex( 56 | const uint8_t *image_data, int image_width, int image_height, int image_channels, 57 | uint8_t *crop_data, int crop_width, int crop_height, 58 | const float *points, int points_num, 59 | const float *mean_shape, int mean_shape_width, int mean_shape_height, 60 | int pad_top = 0, int pad_bottom = 0, int pad_left = 0, int pad_right = 0, 61 | float *final_points = nullptr, 62 | SAMPLING_TYPE type = LINEAR, 63 | PADDING_TYPE ptype = ZERO_PADDING ); 64 | 65 | #endif // _SEETA_COMMON_ALIGNMENT_H 66 | -------------------------------------------------------------------------------- /FaceRecognizer/seeta/graphics2d.cpp: -------------------------------------------------------------------------------- 1 | #include "graphics2d.h" 2 | 3 | -------------------------------------------------------------------------------- /FaceRecognizer/src/seeta/FaceRecognizer.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by kier on 19-4-24. 3 | // 4 | 5 | #include "seeta/FaceRecognizer.h" 6 | #include "seeta/FaceRecognizerPrivate.h" 7 | 8 | 9 | namespace seeta 10 | { 11 | namespace v2 12 | { 13 | 14 | FaceRecognizer::FaceRecognizer( const SeetaModelSetting &setting ) 15 | : m_impl( new FaceRecognizerPrivate( setting.model[0], setting.device, setting.id ) ) 16 | { 17 | 18 | } 19 | 20 | FaceRecognizer::FaceRecognizer() 21 | : m_impl( new FaceRecognizerPrivate() ) 22 | { 23 | 24 | } 25 | 26 | FaceRecognizer::~FaceRecognizer() 27 | { 28 | FaceRecognizerPrivate *ptr = ( FaceRecognizerPrivate * )m_impl; 29 | delete ptr; 30 | m_impl = nullptr; 31 | } 32 | 33 | int FaceRecognizer::GetCropFaceWidth() 34 | { 35 | 36 | FaceRecognizerPrivate *ptr = ( FaceRecognizerPrivate * )m_impl; 37 | return ptr->GetCropWidth(); 38 | } 39 | 40 | int FaceRecognizer::GetCropFaceHeight() 41 | { 42 | 43 | FaceRecognizerPrivate *ptr = ( FaceRecognizerPrivate * )m_impl; 44 | return ptr->GetCropHeight(); 45 | } 46 | 47 | int FaceRecognizer::GetCropFaceChannels() 48 | { 49 | 50 | FaceRecognizerPrivate *ptr = ( FaceRecognizerPrivate * )m_impl; 51 | return ptr->GetCropChannels(); 52 | } 53 | 54 | int FaceRecognizer::GetExtractFeatureSize() const 55 | { 56 | 57 | FaceRecognizerPrivate *ptr = ( FaceRecognizerPrivate * )m_impl; 58 | return ptr->GetFeatureSize(); 59 | } 60 | 61 | bool FaceRecognizer::ExtractCroppedFace( const SeetaImageData &image, float *features ) const 62 | { 63 | 64 | FaceRecognizerPrivate *ptr = ( FaceRecognizerPrivate * )m_impl; 65 | return ptr->ExtractFeatureNormalized( image, features ); 66 | } 67 | 68 | float FaceRecognizer::CalculateSimilarity( const float *features1, const float *features2 ) const 69 | { 70 | 71 | FaceRecognizerPrivate *ptr = ( FaceRecognizerPrivate * )m_impl; 72 | return ptr->CalcSimilarityNormalized( features1, features2 ); 73 | } 74 | 75 | bool FaceRecognizer::Extract( const SeetaImageData &image, const SeetaPointF *points, float *features ) const 76 | { 77 | if( features == nullptr ) return false; 78 | 79 | FaceRecognizerPrivate *ptr = ( FaceRecognizerPrivate * )m_impl; 80 | return ptr->ExtractFeatureWithCropNormalized( image, points, features ); 81 | } 82 | 83 | bool FaceRecognizer::CropFace( const SeetaImageData &image, const SeetaPointF *points, SeetaImageData &face ) 84 | { 85 | 86 | if( points == nullptr ) return false; 87 | 88 | FaceRecognizerPrivate *ptr = ( FaceRecognizerPrivate * )m_impl; 89 | return ptr->CropFace( image, points, face ); 90 | } 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /FaceTracker/FaceTracker.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: @PROJECT_NAME@ 7 | Description: @PROJECT_NAME@ module 8 | Version: @BUILD_VERSION@ 9 | Requires: SeetaFaceDetector 10 | Requires.private: 11 | Conflicts: 12 | Libs: -L${libdir} @PROJECT_NAME@ 13 | Libs.private: 14 | Cflags: -I${includedir} 15 | -------------------------------------------------------------------------------- /FaceTracker/include/seeta/CStruct.h: -------------------------------------------------------------------------------- 1 | #ifndef INC_SEETA_C_STRUCT_H 2 | #define INC_SEETA_C_STRUCT_H 3 | 4 | #ifdef _MSC_VER 5 | #ifdef SEETA_EXPORTS 6 | #define SEETA_API __declspec(dllexport) 7 | #else 8 | #define SEETA_API __declspec(dllimport) 9 | #endif 10 | #else 11 | #define SEETA_API __attribute__ ((visibility("default"))) 12 | #endif 13 | 14 | #define SEETA_C_API extern "C" SEETA_API 15 | 16 | #define INCLUDED_SEETA_CSTRUCT 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | 24 | struct SeetaImageData 25 | { 26 | int width; 27 | int height; 28 | int channels; 29 | unsigned char *data; 30 | }; 31 | 32 | struct SeetaPoint 33 | { 34 | int x; 35 | int y; 36 | }; 37 | 38 | struct SeetaPointF 39 | { 40 | double x; 41 | double y; 42 | }; 43 | 44 | struct SeetaSize 45 | { 46 | int width; 47 | int height; 48 | }; 49 | 50 | struct SeetaRect 51 | { 52 | int x; 53 | int y; 54 | int width; 55 | int height; 56 | }; 57 | 58 | struct SeetaRegion 59 | { 60 | int top; 61 | int bottom; 62 | int left; 63 | int right; 64 | }; 65 | 66 | enum SeetaDevice 67 | { 68 | SEETA_DEVICE_AUTO = 0, 69 | SEETA_DEVICE_CPU = 1, 70 | SEETA_DEVICE_GPU = 2, 71 | }; 72 | 73 | struct SeetaModelSetting 74 | { 75 | enum SeetaDevice device; 76 | int id; // when device is GPU, id means GPU id 77 | const char **model; // model string terminate with nullptr 78 | }; 79 | 80 | struct SeetaBuffer 81 | { 82 | void *buffer; 83 | int64_t size; 84 | }; 85 | 86 | struct SeetaModelBuffer 87 | { 88 | enum SeetaDevice device; 89 | int id; // when device is GPU, id means GPU id 90 | const SeetaBuffer *buffer; // input buffers, terminate with empty buffer(buffer=nullptr, size=0) 91 | }; 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif // INC_SEETA_C_STRUCT_H 98 | -------------------------------------------------------------------------------- /FaceTracker/include/seeta/CTrackingFaceInfo.h: -------------------------------------------------------------------------------- 1 | #ifndef INC_SEETA_C_TRACKING_FACEINFO_H 2 | #define INC_SEETA_C_TRACKING_FACEINFO_H 3 | 4 | #include "Struct.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | struct SeetaTrackingFaceInfo 11 | { 12 | SeetaRect pos; 13 | float score; 14 | 15 | int frame_no; 16 | int PID; 17 | }; 18 | 19 | struct SeetaTrackingFaceInfoArray 20 | { 21 | struct SeetaTrackingFaceInfo *data; 22 | int size; 23 | }; 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif // INC_SEETA_C_TRACKING_FACEINFO_H 30 | -------------------------------------------------------------------------------- /FaceTracker/include/seeta/FaceTracker.h: -------------------------------------------------------------------------------- 1 | #ifndef __FACETRACKER_H_2019_10_17__ 2 | #define __FACETRACKER_H_2019_10_17__ 3 | 4 | #pragma once 5 | 6 | #include "Struct.h" 7 | #include "CTrackingFaceInfo.h" 8 | #include 9 | #include 10 | 11 | namespace seeta { 12 | namespace v2 { 13 | class FaceTracker { 14 | public: 15 | /** 16 | * \brief initialize FaceTracker with face detector model 17 | * \param setting model used by FaceDetector5.1.0 18 | * \param video_width input video frame width 19 | * \param video_height input video frame height 20 | */ 21 | SEETA_API explicit FaceTracker(const SeetaModelSetting &setting); 22 | 23 | SEETA_API explicit FaceTracker(const SeetaModelSetting &setting, int core_width, int core_height); 24 | 25 | SEETA_API ~FaceTracker(); 26 | 27 | SEETA_API SeetaTrackingFaceInfoArray track(const SeetaImageData &image, int frame_no = -1) const; 28 | 29 | enum Property { 30 | PROPERTY_MIN_FACE_SIZE, 31 | PROPERTY_THRESHOLD1, 32 | PROPERTY_THRESHOLD2, 33 | PROPERTY_THRESHOLD3, 34 | PROPERTY_VIDEO_STABLE, 35 | }; 36 | 37 | /** 38 | * \brief set property 39 | * \param [in] property face detector property to set 40 | * \param [in] value value of corresponding property to set 41 | */ 42 | SEETA_API void set(Property property, double value); 43 | 44 | /** 45 | * \brief get property 46 | * \param [in] property to get 47 | * \return property value to get 48 | */ 49 | SEETA_API double get(Property property) const; 50 | 51 | private: 52 | FaceTracker(const FaceTracker &other) = delete; 53 | 54 | const FaceTracker &operator=(const FaceTracker &other) = delete; 55 | 56 | private: 57 | class Implement; 58 | 59 | Implement *m_impl; 60 | }; 61 | } 62 | using namespace v2; 63 | } 64 | 65 | #endif //__FACETRACKER_H_2019_10_17__ 66 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019, SeetaTech, 2 | Institute of Computing Technology, Chinese Academy of Sciences, Beijing, China 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /QualityAssessor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Author: Kang Lin 3 | # Date : 2019-08-20 4 | # 5 | 6 | cmake_minimum_required(VERSION 2.8) 7 | 8 | project(SeetaQualityAssessor) 9 | 10 | add_definitions(-DSEETA_EXPORTS) 11 | 12 | file(GLOB_RECURSE ROOT_SRC_FILES 13 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c 14 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc 15 | ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp 16 | ) 17 | 18 | file(GLOB_RECURSE ROOT_SEETA_FILES 19 | ${CMAKE_CURRENT_SOURCE_DIR}/seeta/*.c 20 | ${CMAKE_CURRENT_SOURCE_DIR}/seeta/*.cc 21 | ${CMAKE_CURRENT_SOURCE_DIR}/seeta/*.cpp 22 | ) 23 | 24 | file(GLOB INCLUDE_FILES 25 | ${CMAKE_CURRENT_SOURCE_DIR}/include/seeta/*.h 26 | ${CMAKE_CURRENT_SOURCE_DIR}/include/seeta/*.hh 27 | ${CMAKE_CURRENT_SOURCE_DIR}/include/seeta/*.hpp 28 | ) 29 | 30 | list(APPEND SRC_FILES ${ROOT_SRC_FILES}) 31 | list(APPEND SRC_FILES ${ROOT_SEETA_FILES}) 32 | 33 | # add library 34 | add_library(${PROJECT_NAME} ${SRC_FILES}) 35 | target_include_directories(${PROJECT_NAME} PRIVATE 36 | ${CMAKE_CURRENT_SOURCE_DIR} 37 | ${PROJECT_SOURCE_DIR}/include 38 | ${PROJECT_SOURCE_DIR}/include/seeta 39 | ${PROJECT_SOURCE_DIR}/seeta 40 | ) 41 | 42 | set_target_properties(${PROJECT_NAME} PROPERTIES 43 | RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 44 | LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 45 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib 46 | VERSION ${BUILD_VERSION}) 47 | # Be will to install header files 48 | set_property(TARGET ${PROJECT_NAME} PROPERTY PUBLIC_HEADER ${INCLUDE_FILES}) 49 | if(WIN32) 50 | INSTALL(TARGETS ${PROJECT_NAME} 51 | EXPORT ${PROJECT_NAME}Config 52 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 53 | LIBRARY DESTINATION "${CMAKE_INSTALL_BINDIR}" 54 | ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 55 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/seeta 56 | INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 57 | ) 58 | else() 59 | INSTALL(TARGETS ${PROJECT_NAME} 60 | EXPORT ${PROJECT_NAME}Config 61 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 62 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 63 | ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 64 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/seeta 65 | INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 66 | ) 67 | endif() 68 | export(TARGETS ${PROJECT_NAME} 69 | APPEND FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.cmake 70 | ) 71 | # Install cmake configure files 72 | install(EXPORT ${PROJECT_NAME}Config 73 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake" 74 | NAMESPACE 75 | SeetaFace:: 76 | ) 77 | write_basic_package_version_file( 78 | "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 79 | VERSION ${BUILD_VERSION} 80 | COMPATIBILITY AnyNewerVersion) 81 | install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake") 82 | # Install configure file 83 | set(SeetaFace2_LIBS "${PROJECT_NAME} ${SeetaFace2_LIBS}" PARENT_SCOPE) 84 | configure_file(QualityAssessor.pc.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc @ONLY) 85 | install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc 86 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") 87 | -------------------------------------------------------------------------------- /QualityAssessor/QualityAssessor.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: @PROJECT_NAME@ 7 | Description: @PROJECT_NAME@ module 8 | Version: @BUILD_VERSION@ 9 | Requires: 10 | Requires.private: 11 | Conflicts: 12 | Libs: -L${libdir} @PROJECT_NAME@ 13 | Libs.private: 14 | Cflags: -I${includedir} 15 | -------------------------------------------------------------------------------- /QualityAssessor/include/seeta/CStruct.h: -------------------------------------------------------------------------------- 1 | #ifndef INC_SEETA_C_STRUCT_H 2 | #define INC_SEETA_C_STRUCT_H 3 | 4 | #ifdef _MSC_VER 5 | #ifdef SEETA_EXPORTS 6 | #define SEETA_API __declspec(dllexport) 7 | #else 8 | #define SEETA_API __declspec(dllimport) 9 | #endif 10 | #else 11 | #define SEETA_API __attribute__ ((visibility("default"))) 12 | #endif 13 | 14 | #define SEETA_C_API extern "C" SEETA_API 15 | 16 | #define INCLUDED_SEETA_CSTRUCT 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | #include 23 | 24 | struct SeetaImageData 25 | { 26 | int width; 27 | int height; 28 | int channels; 29 | unsigned char *data; 30 | }; 31 | 32 | struct SeetaPoint 33 | { 34 | int x; 35 | int y; 36 | }; 37 | 38 | struct SeetaPointF 39 | { 40 | double x; 41 | double y; 42 | }; 43 | 44 | struct SeetaSize 45 | { 46 | int width; 47 | int height; 48 | }; 49 | 50 | struct SeetaRect 51 | { 52 | int x; 53 | int y; 54 | int width; 55 | int height; 56 | }; 57 | 58 | struct SeetaRegion 59 | { 60 | int top; 61 | int bottom; 62 | int left; 63 | int right; 64 | }; 65 | 66 | enum SeetaDevice 67 | { 68 | SEETA_DEVICE_AUTO = 0, 69 | SEETA_DEVICE_CPU = 1, 70 | SEETA_DEVICE_GPU = 2, 71 | }; 72 | 73 | struct SeetaModelSetting 74 | { 75 | enum SeetaDevice device; 76 | int id; // when device is GPU, id means GPU id 77 | const char **model; // model string terminate with nullptr 78 | }; 79 | 80 | struct SeetaBuffer 81 | { 82 | void *buffer; 83 | int64_t size; 84 | }; 85 | 86 | struct SeetaModelBuffer 87 | { 88 | enum SeetaDevice device; 89 | int id; // when device is GPU, id means GPU id 90 | const SeetaBuffer *buffer; // input buffers, terminate with empty buffer(buffer=nullptr, size=0) 91 | }; 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif // INC_SEETA_C_STRUCT_H 98 | -------------------------------------------------------------------------------- /QualityAssessor/include/seeta/QualityAssessor.h: -------------------------------------------------------------------------------- 1 | #ifndef _INC_SEETA_QUALITY_ASSESSOR_H 2 | #define _INC_SEETA_QUALITY_ASSESSOR_H 3 | 4 | #include "Struct.h" 5 | 6 | namespace seeta 7 | { 8 | namespace v2 9 | { 10 | class QualityAssessor { 11 | public: 12 | /** 13 | * \brief load model 14 | * \return 15 | */ 16 | SEETA_API explicit QualityAssessor(); 17 | SEETA_API ~QualityAssessor(); 18 | 19 | /** 20 | * \brief evaluate score 21 | * \param image original image 22 | * \param face face position 23 | * \param points 5 landmarks 24 | * \return 0 if not satisfied, of return score 25 | */ 26 | SEETA_API float evaluate(const SeetaImageData &image, 27 | const SeetaRect &face, 28 | const SeetaPointF *points) const; 29 | enum ERROR_CODE 30 | { 31 | ERROR_OK = 0, 32 | ERROR_LIGHTNESS = 0x01, 33 | ERROR_FACE_SIZE = 0x02, 34 | ERROR_FACE_POSE = 0x04, 35 | ERROR_CLARITY = 0x08 36 | }; 37 | /** 38 | * @brief evaluate score 39 | * @param image original image 40 | * @param face face position 41 | * @param points 5 landmarks 42 | * @param clarity 43 | * @return ERROR_OK if is ok. other reture ERROR_CODE combination. 44 | */ 45 | SEETA_API int evaluate(const SeetaImageData &image, 46 | const SeetaRect &face, 47 | const SeetaPointF *points, float &score) const; 48 | SEETA_API int setFaceSize(int size); 49 | SEETA_API int getFaceSize() const; 50 | 51 | private: 52 | QualityAssessor( const QualityAssessor & ) = delete; 53 | const QualityAssessor &operator=( const QualityAssessor & ) = delete; 54 | 55 | private: 56 | class Implement; 57 | Implement *m_impl; 58 | int m_FaceSize; 59 | }; 60 | } 61 | using namespace v2; 62 | } 63 | 64 | #endif //_INC_SEETA_QUALITY_ASSESSOR_H 65 | -------------------------------------------------------------------------------- /QualityAssessor/seeta/CommonStruct.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Struct.h" 4 | #include "DataHelper.h" 5 | #include 6 | 7 | namespace seeta 8 | { 9 | class Meanshape { 10 | public: 11 | std::vector points; 12 | Size size; 13 | }; 14 | 15 | class Landmarks { 16 | public: 17 | Landmarks() {}; 18 | std::vector points; 19 | }; 20 | 21 | class Image : public Blob { 22 | public: 23 | using self = Image; 24 | using supper = Blob; 25 | using Datum = uint8_t; 26 | 27 | Image( const SeetaImageData &vimg ) : Image( vimg.data, vimg.width, vimg.height, vimg.channels ) {} 28 | operator SeetaImageData() const { 29 | SeetaImageData vimg = { width(), height(), channels(), const_cast( data() ) }; 30 | return vimg; 31 | } 32 | Image( const ImageData &vimg ) : Image( vimg.data, vimg.width, vimg.height, vimg.channels ) {} 33 | operator ImageData() const { 34 | ImageData vimg( const_cast( data() ), width(), height(), channels() ); 35 | return std::move( vimg ); 36 | } 37 | 38 | Image( int width, int height, int channels ) 39 | : supper( height, width, channels ) { 40 | } 41 | 42 | Image( const uint8_t *data, int width, int height, int channels ) 43 | : supper( data, height, width, channels ) { 44 | } 45 | 46 | Image() 47 | : Image( 0, 0, 0 ) { 48 | } 49 | 50 | int height() const { 51 | return supper::shape( 1 ); 52 | } 53 | 54 | int width() const { 55 | return supper::shape( 2 ); 56 | } 57 | 58 | int channels() const { 59 | return supper::shape( 3 ); 60 | } 61 | 62 | template 63 | static Image FromBlob( const Blob &blob ) { 64 | if( blob.shape( 0 ) != 1 ) throw std::logic_error( "Can not convert multi images." ); 65 | Image image( blob.shape( 2 ), blob.shape( 1 ), blob.shape( 3 ) ); 66 | for( int i = 0; i < blob.count(); ++i ) { 67 | image[i] = static_cast( std::max( 0, std::min( 255, blob[i] ) ) ); 68 | } 69 | return std::move( image ); 70 | } 71 | 72 | }; 73 | 74 | inline void _out_str( std::ostream &out ) { } 75 | 76 | // there is no error anyway, this is a new feature about C++11 77 | template 78 | inline void _out_str( std::ostream &out, const T &t, Args... args ) 79 | { 80 | _out_str( out << t, args... ); 81 | } 82 | 83 | template 84 | inline const std::string str( Args... args ) 85 | { 86 | std::ostringstream oss; 87 | _out_str( oss, args... ); 88 | return std::move( oss.str() ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /QualityAssessor/seeta/ImageProcess.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataHelper.h" 4 | #include "CommonStruct.h" 5 | #include "graphics2d.h" 6 | 7 | namespace seeta 8 | { 9 | enum SAMPLING_METHOD 10 | { 11 | BY_LINEAR, ///< 12 | BY_BICUBIC ///< Cubic 13 | }; 14 | 15 | const Image color( const Image &img ); 16 | const Image gray( const Image &img ); 17 | const Image crop( const Image &img, const Rect &rect ); 18 | using Padding = Size; 19 | const Image pad( const Image &img, const Padding &padding ); 20 | const Image resize( const Image &img, const Size &size ); 21 | const Image crop_resize( const Image &img, const Rect &rect, const Size &size ); 22 | const Image equalize_hist( const Image &img ); 23 | 24 | void fill( Image &img, const Point &point, const Image &patch ); 25 | void fill( Image &img, const Rect &rect, const Image &patch ); 26 | 27 | const Meanshape face_meanshape( int num, int id = 0 ); 28 | const Meanshape resize( const Meanshape &shape, double scaler ); 29 | const Meanshape resize( const Meanshape &shape, const Size &size ); 30 | const Image crop_face( const Image &img, const Meanshape &shape, const Landmarks &marks, SAMPLING_METHOD type ); 31 | const Image crop_face( const Image &img, const Meanshape &shape, const Landmarks &marks, SAMPLING_METHOD type, const Size &final_size ); 32 | const Image crop_face( const Image &img, const Meanshape &shape, const Landmarks &marks, SAMPLING_METHOD type, const Size &final_size, Landmarks &final_points ); 33 | 34 | // sample image with `size` on `image` by trasfromation 35 | const Image sample( const Image &image, const Size &size, const Trans2D &transformation ); 36 | } 37 | -------------------------------------------------------------------------------- /QualityAssessor/seeta/common_alignment.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETA_COMMON_ALIGNMENT_H 2 | #define _SEETA_COMMON_ALIGNMENT_H 3 | #include 4 | 5 | /** 6 | * \brief sample type 7 | */ 8 | enum SAMPLING_TYPE 9 | { 10 | LINEAR, ///< 11 | BICUBIC ///< 12 | }; 13 | 14 | /** 15 | * \brief type of padding value if sample out of image 16 | */ 17 | enum PADDING_TYPE 18 | { 19 | ZERO_PADDING, ///< 0 padding 20 | NEAREST_PADDING, ///< padding with value of nearest pixel 21 | }; 22 | 23 | /** 24 | * \brief Crop face 25 | * \param [in] image_data input image, format like height * width * channels 26 | * \param [in] image_width image width 27 | * \param [in] image_height image height 28 | * \param [in] image_channels image channels 29 | * \param [in] crop_data output [crop_width + pad_left + pad_right, crop_height + pad_top + pad_bottom, image_channels] 30 | * \param [in] crop_width output crop face width, based on meanshape, \b not output image size, infected by pad value 31 | * \param [in] crop_height output crop face height, based on meanshape, \b not output image size, infected by pad value 32 | * \param [in] points face landmark, format {(x1, y1), (x2, y2), ...} 33 | * \param [in] points_num number of landmark 34 | * \param [in] mean_shape meanshape, fomat {(x1, y1), (x2, y2), ...} 35 | * \param [in] mean_shape_width meanshape face width 36 | * \param [in] mean_shape_height meanshape face height 37 | * \param [in] pad_top pad on top, can be neg value 38 | * \param [in] pad_bottom pad on bottom, can be neg value 39 | * \param [in] pad_left pad on left, can be neg value 40 | * \param [in] pad_right pad on right, can be neg value 41 | * \param [out] final_points landmarks on cropped face {(x1, y1), (x2, y2), ...}, can be NULL. 42 | * \param [in] type method of sample 43 | * \return ture if succeed 44 | * \note final face data size should be [crop_width + pad_left + pad_right, crop_height + pad_top + pad_bottom] 45 | */ 46 | bool face_crop_core( 47 | const uint8_t *image_data, int image_width, int image_height, int image_channels, 48 | uint8_t *crop_data, int crop_width, int crop_height, 49 | const float *points, int points_num, 50 | const float *mean_shape, int mean_shape_width, int mean_shape_height, 51 | int pad_top = 0, int pad_bottom = 0, int pad_left = 0, int pad_right = 0, 52 | float *final_points = nullptr, 53 | SAMPLING_TYPE type = LINEAR ); 54 | 55 | bool face_crop_core_ex( 56 | const uint8_t *image_data, int image_width, int image_height, int image_channels, 57 | uint8_t *crop_data, int crop_width, int crop_height, 58 | const float *points, int points_num, 59 | const float *mean_shape, int mean_shape_width, int mean_shape_height, 60 | int pad_top = 0, int pad_bottom = 0, int pad_left = 0, int pad_right = 0, 61 | float *final_points = nullptr, 62 | SAMPLING_TYPE type = LINEAR, 63 | PADDING_TYPE ptype = ZERO_PADDING ); 64 | 65 | #endif // _SEETA_COMMON_ALIGNMENT_H 66 | -------------------------------------------------------------------------------- /QualityAssessor/seeta/graphics2d.cpp: -------------------------------------------------------------------------------- 1 | #include "graphics2d.h" 2 | 3 | -------------------------------------------------------------------------------- /QualityAssessor/src/ClarityQuality.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by seetadev on 2019/10/31. 3 | // 4 | 5 | #ifndef SEETAFACE_CLARITYQUALITY_H 6 | #define SEETAFACE_CLARITYQUALITY_H 7 | 8 | #include "seeta/Struct.h" 9 | 10 | float evaluate_clarity(const SeetaImageData &image, const SeetaRect &info); 11 | 12 | 13 | #endif //SEETAFACE_CLARITYQUALITY_H 14 | -------------------------------------------------------------------------------- /QualityAssessor/src/PoseQuality.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by seetadev on 2019/10/31. 3 | // 4 | 5 | #ifndef SEETAFACE_POSEQUALITY_H 6 | #define SEETAFACE_POSEQUALITY_H 7 | 8 | #include 9 | 10 | /** 11 | * 12 | * @param image original image 13 | * @param face face position 14 | * @param points 5 landmarks 15 | * @param roll 16 | * @param yaw 17 | * @param pitch 18 | */ 19 | void evaluate_pose(const SeetaImageData &image, const SeetaRect &face, const SeetaPointF *points, 20 | float &roll, float &yaw, float &pitch); 21 | 22 | 23 | #endif //SEETAFACE_POSEQUALITY_H 24 | -------------------------------------------------------------------------------- /SeetaFace.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: SeetaFace2 7 | Description: SeetaFace2 8 | Version: @BUILD_VERSION@ 9 | Requires: @SeetaFace2_LIBS@ 10 | Requires.private: 11 | Conflicts: 12 | Libs: -L${libdir} 13 | Libs.private: 14 | Cflags: -I${includedir} 15 | -------------------------------------------------------------------------------- /SeetaNet/SeetaNet.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: @PROJECT_NAME@ 7 | Description: @PROJECT_NAME@ module 8 | Version: @BUILD_VERSION@ 9 | Requires: 10 | Requires.private: 11 | Conflicts: 12 | Libs: -L${libdir} @PROJECT_NAME@ @SeetaNet_LIBS@ 13 | Libs.private: 14 | Cflags: -I${includedir} @SeetaNet_definitions@ 15 | -------------------------------------------------------------------------------- /SeetaNet/include/SeetaNetStruct.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_STRUCT_H 2 | #define _SEETANET_STRUCT_H 3 | 4 | #if defined(SEETA_EXPORTS) 5 | #define SEETANET_EXPORTS 6 | #endif 7 | 8 | #if defined(_MSC_VER) 9 | #ifdef SEETANET_EXPORTS 10 | #define SEETANET_API __declspec(dllexport) 11 | #else 12 | #define SEETANET_API __declspec(dllimport) 13 | #endif 14 | #else 15 | #define SEETANET_API 16 | #endif 17 | 18 | #ifdef __cplusplus 19 | #define SEETANET_C_API extern "C" SEETANET_API 20 | #else 21 | #define SEETANET_C_API SEETANET_API 22 | #endif 23 | 24 | /** 25 | * @brief The supported device. 26 | */ 27 | enum SeetaNet_DEVICE_TYPE 28 | { 29 | SEETANET_CPU_DEVICE = 0, /**< CPU, default */ 30 | SEETANET_GPU_DEVICE = 1 /**< GPU, only supported in gpu version, reserved*/ 31 | }; 32 | typedef enum SeetaNet_DEVICE_TYPE SeetaNet_DEVICE_TYPE; 33 | 34 | /** 35 | * @brief The dummy model structure 36 | */ 37 | struct SeetaNet_Model; 38 | typedef struct SeetaNet_Model SeetaNet_Model; 39 | 40 | /** 41 | * @brief The dummy net structure 42 | */ 43 | struct SeetaNet_Net; 44 | typedef struct SeetaNet_Net SeetaNet_Net; 45 | 46 | 47 | /** 48 | * @brief The dummy SharedParam structure 49 | */ 50 | struct SeetaNet_SharedParam; 51 | typedef struct SeetaNet_SharedParam SeetaNet_SharedParam; 52 | 53 | //for buffer_type enum 54 | typedef enum 55 | { 56 | SEETANET_BGR_IMGE_CHAR = 0, 57 | SEETANET_BGR_IMGE_FLOAT = 1, 58 | SEETANET_NCHW_FLOAT = 2, 59 | 60 | } SEETANET_BUFFER_STORAGE_ODER_TYPE; 61 | 62 | /** 63 | * @brief The base data structure 64 | */ 65 | struct SeetaNet_InputOutputData 66 | { 67 | float *data_point_float; /**< Used in output mode, pointing to the specific blob */ 68 | unsigned char *data_point_char; /**< Used in input mode, pointing to image data */ 69 | int number; /**< Number of the batch size */ 70 | int channel; /**< Number of the channels */ 71 | int width; /**< Width of the blob (or input image) */ 72 | int height; /**< Height of the blob (or input image) */ 73 | int buffer_type; /**< Not used reserve parameter, 0 for default (means local memory data)*/ 74 | }; 75 | typedef struct SeetaNet_InputOutputData SeetaNet_InputOutputData; 76 | 77 | 78 | /** 79 | * @brief The global error code 80 | */ 81 | enum SeetaNet_ErrorCode 82 | { 83 | NOERROR = 0, /**< No error */ 84 | UNIDENTIFIED_LAYER = 1, /**< Got an unidentified layer */ 85 | MISSMATCH_DEVICE_ID = 2, /**< Missmatch */ 86 | }; 87 | typedef enum SeetaNet_ErrorCode SeetaNet_ErrorCode; 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /SeetaNet/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | 4 | include $(CLEAR_VARS) 5 | 6 | LOCAL_MODULE := seetanet2 7 | 8 | MY_CPP_LIST := $(wildcard $(LOCAL_PATH)/../src/*.cpp) 9 | MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/../src/mem/*.cpp) 10 | MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/../src/proto/*.cc) 11 | MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/../src/orz/mem/*.cpp) 12 | MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/../src/orz/sync/*.cpp) 13 | MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/../src/orz/tools/*.cpp) 14 | 15 | LOCAL_SRC_FILES := $(MY_CPP_LIST:$(LOCAL_PATH)/%=%) 16 | 17 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/.. \ 18 | $(LOCAL_PATH)/../include \ 19 | $(LOCAL_PATH)/../src/include_inner \ 20 | $(LOCAL_PATH)/../src/include_inner/layers \ 21 | $(LOCAL_PATH)/../src/mem \ 22 | $(LOCAL_PATH)/../thirdParty/Android/include/ \ 23 | $(LOCAL_PATH)/../thirdParty/Android/protobuf/include \ 24 | $(LOCAL_PATH)/../thirdParty/Android/openblas/include \ 25 | $(LOCAL_PATH)/../src/proto \ 26 | $(LOCAL_PATH)/../src 27 | 28 | LOCAL_LDFLAGS += -L$(LOCAL_PATH)/lib -fuse-ld=bfd 29 | 30 | LOCAL_CFLAGS += -mfpu=neon-vfpv4 -funsafe-math-optimizations -ftree-vectorize -ffast-math 31 | 32 | LOCAL_LDLIBS += -lc -llog -latomic -lm 33 | include $(BUILD_SHARED_LIBRARY) 34 | -------------------------------------------------------------------------------- /SeetaNet/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_STL := c++_static 2 | APP_CPPFLAGS := -std=c++11 3 | APP_CPPFLAGS += -std=c++0x 4 | APP_CPPFLAGS += -fexceptions -O3 5 | APP_CPPFLAGS += -fPIC -frtti 6 | APP_ABI := armeabi-v7a 7 | APP_PLATFORM := android-16 8 | APP_OPTIM := release 9 | -------------------------------------------------------------------------------- /SeetaNet/src/ReadFromSeetaNetLayer.cpp: -------------------------------------------------------------------------------- 1 | #include "ReadFromSeetaNetLayer.h" 2 | #include "SeetaNetMemoryModel.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "SeetaNetParseProto.h" 10 | 11 | 12 | 13 | int ReadAllContentFromFile( const char *inputfilename, char **ppbuffer, int64_t &file_length ) 14 | { 15 | std::ifstream fin( inputfilename, std::ios::binary | std::ios::in ); 16 | if( !fin.is_open() ) 17 | { 18 | return -1; 19 | } 20 | fin.seekg( 0, std::ios::end ); 21 | file_length = fin.tellg(); 22 | 23 | *ppbuffer = new char[file_length]; 24 | fin.seekg( 0, std::ios::beg ); 25 | fin.read( *ppbuffer, file_length); 26 | fin.close(); 27 | 28 | return 0; 29 | } 30 | 31 | 32 | int SeetaNetReadModelFromBuffer( const char *buffer, size_t buffer_length, void **model ) 33 | { 34 | MemoryModel **tmp_model = ( MemoryModel ** )model; 35 | *tmp_model = new MemoryModel; 36 | if( buffer == nullptr ) 37 | { 38 | return NULL_PTR; 39 | } 40 | 41 | auto ibuffer_length = int(buffer_length); 42 | 43 | int offset = read( buffer, ibuffer_length, ( *tmp_model )->vector_blob_names ); 44 | offset += read( buffer + offset, ibuffer_length - offset, ( *tmp_model )->vector_layer_names ); 45 | 46 | int32_t nlayers = 0; 47 | offset += read( buffer + offset, ibuffer_length - offset, nlayers ); 48 | 49 | int index_layer = 0; 50 | int return_result = -1; 51 | 52 | for( int i = 0; i < nlayers; i++ ) 53 | { 54 | return_result = -1; 55 | seeta::SeetaNet_LayerParameter *output_param = new seeta::SeetaNet_LayerParameter; 56 | return_result = output_param->read( buffer + offset, ibuffer_length - offset ); 57 | 58 | output_param->set_layer_index( index_layer ); 59 | index_layer++; 60 | 61 | if( return_result >= 0 ) 62 | { 63 | ( *tmp_model )->all_layer_params.push_back( output_param ); 64 | } 65 | else 66 | { 67 | std::cout << "SeetaNetReadModelFromBuffer failed" << std::endl; 68 | delete( *tmp_model ); 69 | throw std::logic_error("SeetanetReadModelFromBuffer failed!"); 70 | } 71 | offset += return_result; 72 | } 73 | 74 | return 0; 75 | } 76 | 77 | 78 | int SeetaNetReleaseModel( void **model ) 79 | { 80 | MemoryModel **tmp_model = ( MemoryModel ** )model; 81 | for( int i = 0; i < ( *tmp_model )->all_layer_params.size(); i++ ) 82 | { 83 | delete( *tmp_model )->all_layer_params[i]; 84 | } 85 | ( *tmp_model )->all_layer_params.clear(); 86 | ( *tmp_model )->vector_blob_names.clear(); 87 | ( *tmp_model )->vector_layer_names.clear(); 88 | 89 | delete *tmp_model; 90 | 91 | *tmp_model = nullptr; 92 | 93 | return 0; 94 | } 95 | 96 | int SeetaNetModelResetInput( void *model, int width, int height ) 97 | { 98 | MemoryModel *tmp_model = ( MemoryModel * )model; 99 | tmp_model->m_new_width = width; 100 | tmp_model->m_new_height = height; 101 | return 0; 102 | } 103 | 104 | 105 | -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/ReadFromSeetaNetLayer.h: -------------------------------------------------------------------------------- 1 | #ifndef _READ_FROM_SEETANET_LAYER_H_ 2 | #define _READ_FROM_SEETANET_LAYER_H_ 3 | 4 | #include 5 | #include 6 | typedef enum 7 | { 8 | NULL_PTR = -1, 9 | FILE_NOT_EXIST = -2, 10 | BLOB_NOT_EXIST = -3, 11 | LAYER_READ_NOT_FOUND = -4, 12 | LAYER_PROCESS_NOT_FOUND = -5, 13 | BUFFER_LENGTH_LESS_ZERO = -6, 14 | LAYER_CREATE_NOT_FOUND = -7, 15 | } ReadCNNErrorNum; 16 | 17 | int SeetaNetReadModelFromBuffer( const char *buffer, size_t buffer_length, void **model ); 18 | int ReadAllContentFromFile( const char *inputfilename, char **ppbuffer, int64_t &file_length ); 19 | int SeetaNetReleaseModel( void **model ); 20 | 21 | int SeetaNetModelResetInput( void *model, int width, int height ); 22 | 23 | #endif -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/SeetaNet.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_H_ 2 | #define _SEETANET_H_ 3 | 4 | #include "SeetaNetStruct.h" 5 | 6 | #define NetF float 7 | 8 | 9 | enum MyEnum 10 | { 11 | BLOB_NAME_NOT_EXIST = -1, 12 | }; 13 | 14 | 15 | /** 16 | * \brief 17 | * \param model 18 | * \param max_batch_size 19 | * \param process_device_type 20 | * \param output_net_out 21 | * \param gpu_device_id, not use 22 | * \return 23 | */ 24 | int CreateNet( void *model, int max_batch_size, SeetaNet_DEVICE_TYPE process_device_type, void **output_net_out, int gpu_device_id = 0 ); 25 | 26 | int CreateNetSharedParam( void *model, int max_batchsize, SeetaNet_DEVICE_TYPE process_device_type, void **output_net_out, void **output_shared_param, int gpu_device_id = 0 ); 27 | 28 | int RunNetChar( void *output_net_out, int counts, SeetaNet_InputOutputData *pinput_Data ); 29 | int RunNetFloat( void *output_net_out, int counts, SeetaNet_InputOutputData *pinput_Data ); 30 | int SeetaNetGetFeatureMap( const char *buffer_name, void *pNetIn, SeetaNet_InputOutputData *outputData ); 31 | 32 | int SeetaNetGetAllFeatureMap( void *pNetIn, int *number, SeetaNet_InputOutputData **outputData ); 33 | void SeetaNetFreeAllFeatureMap( void *pNetIn, const SeetaNet_InputOutputData *outputData ); 34 | 35 | void *GetNetSharedParam( void *net ); 36 | 37 | void SeetaNetReleaseNet( void **pNetIn ); 38 | 39 | int SeetaNetReleaseSharedParam( void **shared_param ); 40 | 41 | void SeetaNetKeepBlob( struct SeetaNet_Net *net, const char *blob_name ); 42 | 43 | void SeetaNetKeepNoBlob( struct SeetaNet_Net *net ); 44 | 45 | void SeetaNetKeepAllBlob( struct SeetaNet_Net *net ); 46 | 47 | int SeetaNetHasKeptBlob( struct SeetaNet_Net *net, const char *blob_name ); 48 | 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/SeetaNetCommon.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_COMMON_H_ 2 | #define _SEETANET_COMMON_H_ 3 | 4 | 5 | struct SeetaNetDataSize 6 | { 7 | std::vector data_dim; 8 | SeetaNetDataSize() { 9 | data_dim.clear(); 10 | }; 11 | 12 | SeetaNetDataSize( const SeetaNetDataSize &a ) { 13 | data_dim = a.data_dim; 14 | }; 15 | }; 16 | 17 | #endif -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/SeetaNetFeatureMap.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_FEATURE_MAP_H_ 2 | #define _SEETANET_FEATURE_MAP_H_ 3 | 4 | #include "SeetaNetCommon.h" 5 | #include "SeetaNetResource.h" 6 | #include"SeetaNetBlobCpu.h" 7 | 8 | 9 | 10 | enum DATA_STORAGE_TYPE 11 | { 12 | DATA_INVALID = 0, 13 | DATA_CPU_WIDTH = 1, 14 | DATA_CPU_SLICE = 2, 15 | DATA_CPU_WIDTH_CHAR = 3, 16 | DATA_CPU_SLICE_CHAR = 4, 17 | DATA_GPU = 5 18 | }; 19 | 20 | template 21 | class SeetaNetFeatureMap { 22 | public: 23 | 24 | SeetaNetFeatureMap() {}; 25 | ~SeetaNetFeatureMap() {}; 26 | 27 | int TransFormDataIn(); 28 | std::string data_name; 29 | std::vector data_shape; 30 | int dwStorageType; 31 | SeetaNetResource *pNetResource; 32 | SeetaNetBlobCpu m_cpu; 33 | 34 | std::vector &shape() { 35 | return data_shape; 36 | } 37 | 38 | const std::vector &shape() const { 39 | return data_shape; 40 | } 41 | 42 | int &shape( size_t axis ) { 43 | return data_shape[axis]; 44 | } 45 | 46 | const int &shape( size_t axis ) const { 47 | return data_shape[axis]; 48 | } 49 | 50 | int count() const { 51 | int mul = 1; 52 | for( auto dim : data_shape ) mul *= dim; 53 | return mul; 54 | } 55 | 56 | T *cpu_ptr() { 57 | return m_cpu.dataMemoryPtr(); 58 | } 59 | }; 60 | 61 | template 62 | int SeetaNetFeatureMap::TransFormDataIn() 63 | { 64 | switch( dwStorageType ) 65 | { 66 | case DATA_CPU_WIDTH: 67 | { 68 | break; 69 | } 70 | case DATA_GPU: 71 | { 72 | break; 73 | } 74 | default: 75 | break; 76 | } 77 | return 0; 78 | } 79 | 80 | 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/SeetaNetIm2Col.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_IM2COL_H_ 2 | #define _SEETANET_IM2COL_H_ 3 | 4 | #include 5 | 6 | 7 | template 8 | void im2col_nd_cpu( const Dtype *data_im, const int num_spatial_axes, 9 | const int *im_shape, const int *col_shape, 10 | const int *kernel_shape, const int *pad, const int *stride, 11 | const int *dilation, Dtype *data_col ); 12 | 13 | template 14 | void im2col_cpu( const Dtype *data_im, const int channels, 15 | const int height, const int width, const int kernel_h, const int kernel_w, 16 | const int pad_h, const int pad_w, const int stride_h, 17 | const int stride_w, const int dilation_h, const int dilation_w, 18 | Dtype *data_col ); 19 | 20 | template 21 | void shift_im2col_cpu( const Dtype *data_im, const int channels, 22 | const int height, const int width, const int kernel_h, const int kernel_w, 23 | int pad_h, int pad_w, const int shift_h, const int shfit_w, 24 | const int stride_h, const int stride_w, const int dilation_h, const int dilation_w, 25 | Dtype *data_col ); 26 | 27 | template 28 | void col2im_nd_cpu( const Dtype *data_col, const int num_spatial_axes, 29 | const int *im_shape, const int *col_shape, 30 | const int *kernel_shape, const int *pad, const int *stride, 31 | const int *dilation, Dtype *data_im ); 32 | 33 | template 34 | void col2im_cpu( const Dtype *data_col, const int channels, 35 | const int height, const int width, const int kernel_h, const int kernel_w, 36 | const int pad_h, const int pad_w, const int stride_h, 37 | const int stride_w, const int dilation_h, const int dilation_w, 38 | Dtype *data_im ); 39 | 40 | 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/SeetaNetLayerType.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_LAYER_TYPE_H_ 2 | #define _SEETANET_LAYER_TYPE_H_ 3 | namespace seeta 4 | { 5 | 6 | 7 | enum Enum_SeetaNetLayerType 8 | { 9 | Enum_ConvolutionLayer = 0, 10 | Enum_EltwiseLayer = 1, 11 | Enum_ConcatLayer = 2, 12 | Enum_ExpLayer = 3, 13 | Enum_InnerProductLayer = 4, 14 | Enum_LRNLayer = 5, 15 | Enum_MemoryDataLayer = 6, 16 | Enum_PoolingLayer = 7, 17 | Enum_PowerLayer = 8, 18 | Enum_ReLULayer = 9, 19 | Enum_SoftmaxLayer = 10, 20 | Enum_SliceLayer = 11, 21 | Enum_BatchNormliseLayer = 13, 22 | Enum_ScaleLayer = 14, 23 | Enum_SplitLayer = 15, 24 | Enum_PreReLULayer = 16, 25 | Enum_DeconvolutionLayer = 17, 26 | Enum_CropLayer = 18, 27 | Enum_SigmoidLayer = 19, 28 | 29 | // tf convert operator 30 | Enum_SpaceToBatchNDLayer = 20, 31 | Enum_BatchToSpaceNDLayer = 21, 32 | 33 | // tf reshape 34 | Enum_ReshapeLayer = 22, 35 | Enum_RealMulLayer = 23, 36 | Enum_ShapeIndexPatchLayer = 31, 37 | Enum_FinallyLayer = 1001, 38 | }; 39 | }; 40 | 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/SeetaNetMacro.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_MACRO_H_ 2 | #define _SEETANET_MACRO_H_ 3 | 4 | 5 | #endif 6 | -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/SeetaNetMathCPU.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_MATH_CPU_H 2 | #define _SEETANET_MATH_CPU_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace seeta 11 | { 12 | namespace blas 13 | { 14 | enum Order 15 | { 16 | RowMajor = 101, 17 | ColMajor = 102 18 | }; 19 | enum Transpose 20 | { 21 | NoTrans = 111, 22 | Trans = 112 23 | }; 24 | } 25 | 26 | 27 | template 28 | inline bool near( T value1, T value2 ) 29 | { 30 | return ( value1 - value2 == 0 ); 31 | } 32 | 33 | template<> 34 | inline bool near( double value1, double value2 ) 35 | { 36 | return ( value1 > value2 ? value1 - value2 : value2 - value1 ) < DBL_EPSILON; 37 | } 38 | 39 | template<> 40 | inline bool near( float value1, float value2 ) 41 | { 42 | return ( value1 > value2 ? value1 - value2 : value2 - value1 ) < FLT_EPSILON; 43 | } 44 | 45 | 46 | template 47 | inline T abs( T value ) 48 | { 49 | return T( std::abs( value ) ); 50 | } 51 | 52 | template <> 53 | inline uint8_t abs( uint8_t value ) 54 | { 55 | return value; 56 | } 57 | 58 | template <> 59 | inline uint16_t abs( uint16_t value ) 60 | { 61 | return value; 62 | } 63 | 64 | template <> 65 | inline uint32_t abs( uint32_t value ) 66 | { 67 | return value; 68 | } 69 | 70 | template <> 71 | inline uint64_t abs( uint64_t value ) 72 | { 73 | return value; 74 | } 75 | 76 | template <> 77 | inline float abs( float value ) 78 | { 79 | using namespace std; 80 | return fabsf( value ); 81 | } 82 | 83 | template <> 84 | inline double abs( double value ) 85 | { 86 | return std::fabs( value ); 87 | } 88 | 89 | 90 | template 91 | class math { 92 | public: 93 | 94 | static T abs( T val ); 95 | 96 | static T dot( 97 | int N, 98 | const T *x, 99 | int incx, 100 | const T *y, 101 | int incy 102 | ); 103 | static T dot( int N, const T *x, const T *y ); 104 | 105 | static void gemm( 106 | blas::Order Order, 107 | blas::Transpose TransA, 108 | blas::Transpose TransB, 109 | int M, int N, int K, 110 | T alpha, 111 | const T *A, int lda, 112 | const T *B, int ldb, 113 | T beta, 114 | T *C, int ldc ); 115 | 116 | static void gemm( 117 | blas::Transpose TransA, 118 | blas::Transpose TransB, 119 | int M, int N, int K, 120 | T alpha, const T *A, const T *B, 121 | T beta, T *C ); 122 | 123 | static void gemm_pack( 124 | blas::Transpose TransA, 125 | blas::Transpose TransB, 126 | int M, int N, int K, 127 | T alpha, const T *A, const T *B, 128 | T beta, T *C); 129 | 130 | static T asum( 131 | int N, 132 | const T *x, 133 | int incx 134 | ); 135 | }; 136 | } 137 | 138 | extern template class seeta::math; 139 | extern template class seeta::math; 140 | 141 | 142 | #endif 143 | 144 | -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/SeetaNetMemoryModel.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_MEMORY_MODEL_H_ 2 | #define _SEETANET_MEMORY_MODEL_H_ 3 | 4 | #include "SeetaNetProto.h" 5 | #include 6 | 7 | struct MemoryModel 8 | { 9 | std::vector all_layer_params; 10 | 11 | std::vector vector_blob_names; 12 | std::vector vector_layer_names; 13 | 14 | std::mutex model_mtx; 15 | 16 | /* saving resized input */ 17 | int m_new_width = -1; 18 | int m_new_height = -1; 19 | }; 20 | 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/SeetaNetParseProto.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_PARSE_PROTO_HELPER_H 2 | #define _SEETANET_PARSE_PROTO_HELPER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using std::vector; 10 | using std::string; 11 | 12 | int read( const char *buf, int len, int32_t &value ); 13 | int read( const char *buf, int len, uint32_t &value ); 14 | int read( const char *buf, int len, bool &value ); 15 | int read( const char *buf, int len, float &value ); 16 | int read( const char *buf, int len, vector &value ); 17 | int read( const char *buf, int len, vector &value ); 18 | int read( const char *buf, int len, vector &value ); 19 | int read( const char *buf, int len, std::string &value ); 20 | int read( const char *buf, int len, vector &value ); 21 | 22 | int write( char *buf, int len, int32_t value ); 23 | int write( char *buf, int len, uint32_t value ); 24 | int write( char *buf, int len, bool value ); 25 | int write( char *buf, int len, float value ); 26 | int write( char *buf, int len, const vector &value ); 27 | int write( char *buf, int len, const vector &value ); 28 | int write( char *buf, int len, const vector &value ); 29 | 30 | int write( char *buf, int len, const std::string &value ); 31 | int write( char *buf, int len, const vector &value ); 32 | 33 | 34 | int WriteStringToFile( const std::string &input_string, std::fstream &outputfstream ); 35 | int WriteStringVectorToFile( const std::vector &vec, std::fstream &outputfstream ); 36 | 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/SeetaNetResource.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_RESOURCE_H_ 2 | #define _SEETANET_RESOURCE_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "SeetaNetMacro.h" 8 | #include "SeetaNetCommon.h" 9 | #include "SeetaNetBlobCpu.h" 10 | 11 | template 12 | struct SeetaNetShareParam 13 | { 14 | std::map > param_map; 15 | int m_refrence_counts = 0; 16 | int m_device; // type of SeetaNet_DEVICE_TYPE 17 | 18 | SeetaNetShareParam() { 19 | } 20 | 21 | ~SeetaNetShareParam() { 22 | 23 | } 24 | }; 25 | 26 | template 27 | struct SeetaNetResource 28 | { 29 | int max_batch_size; 30 | 31 | SeetaNetShareParam *m_shared_param; 32 | 33 | std::map blob_name_map; 34 | std::vector layer_type_vector; 35 | 36 | std::vector feature_vector_size; 37 | 38 | /* saving resized input */ 39 | int m_new_width = -1; 40 | int m_new_height = -1; 41 | 42 | SeetaNetBlobCpu col_buffer_; 43 | std::vector col_buffer_shape_; 44 | 45 | int process_device_type; 46 | int process_max_batch_size; 47 | 48 | int current_process_size; 49 | 50 | int colbuffer_memory_size; 51 | 52 | int CaculateMemorySize( std::vector shape_vector ) { 53 | int counts = 0; 54 | if( !shape_vector.empty() ) { 55 | counts = 1; 56 | for( int i = 0; i < shape_vector.size(); i++ ) { 57 | counts *= shape_vector[i]; 58 | } 59 | } 60 | 61 | return counts; 62 | }; 63 | 64 | int UpdateNetResourceMemory( std::vector shape_vector ) { 65 | int new_memory_size = CaculateMemorySize( shape_vector ); 66 | if( new_memory_size > colbuffer_memory_size ) { 67 | col_buffer_shape_ = shape_vector; 68 | colbuffer_memory_size = new_memory_size; 69 | 70 | col_buffer_.Reshape( shape_vector ); 71 | } 72 | 73 | 74 | return 0; 75 | }; 76 | 77 | }; 78 | 79 | 80 | 81 | 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/layers/SeetaNetBaseLayer.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_BASE_LAYER_ 2 | #define _SEETANET_BASE_LAYER_ 3 | 4 | #include 5 | #include "SeetaNetProto.h" 6 | #include "SeetaNetCommon.h" 7 | #include "SeetaNetFeatureMap.h" 8 | #include "SeetaNetResource.h" 9 | 10 | 11 | template 12 | class SeetaNetBaseLayer { 13 | public: 14 | SeetaNetBaseLayer() {}; 15 | virtual ~SeetaNetBaseLayer() {}; 16 | 17 | virtual int GetTopSize( std::vector &out_data_size ); 18 | virtual int Exit() { 19 | return 0; 20 | }; 21 | virtual int Init( seeta::SeetaNet_LayerParameter &inputparam, SeetaNetResource *pNetResource ) { 22 | m_layer_index = inputparam.layer_index; 23 | return 0; 24 | }; 25 | virtual int Process( std::vector*> input_data_map, std::vector*> &output_data_map ) { 26 | return 0; 27 | }; 28 | public: 29 | std::vector bottom_data_size; 30 | std::vector bottom_index; 31 | 32 | std::vector top_data_size; 33 | std::vector top_index; 34 | int m_layer_index; 35 | int m_layer_type; 36 | }; 37 | 38 | template 39 | int SeetaNetBaseLayer::GetTopSize( std::vector &out_data_size ) 40 | { 41 | out_data_size = this->top_data_size; 42 | return 0; 43 | } 44 | 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/layers/SeetaNetSigmoidCPU.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_SIGMOID_CPU_H_ 2 | #define _SEETANET_SIGMOID_CPU_H_ 3 | 4 | 5 | #include "SeetaNetBaseLayer.h" 6 | 7 | 8 | template 9 | class SeetaNetSigmoidCPU : public SeetaNetBaseLayer { 10 | public: 11 | SeetaNetSigmoidCPU(); 12 | ~SeetaNetSigmoidCPU(); 13 | 14 | int Init( seeta::SeetaNet_LayerParameter &inputparam, SeetaNetResource *pNetResource ); 15 | int Process( std::vector*> input_data_map, std::vector*> &output_data_map ); 16 | 17 | }; 18 | 19 | template 20 | SeetaNetSigmoidCPU::SeetaNetSigmoidCPU() 21 | { 22 | 23 | } 24 | 25 | 26 | template 27 | SeetaNetSigmoidCPU::~SeetaNetSigmoidCPU() 28 | { 29 | 30 | } 31 | 32 | 33 | template 34 | int SeetaNetSigmoidCPU::Init( seeta::SeetaNet_LayerParameter &inputparam, SeetaNetResource *pNetResource ) 35 | { 36 | int index = inputparam.bottom_index[0]; 37 | this->bottom_data_size.resize( 1 ); 38 | this->bottom_data_size[0] = pNetResource->feature_vector_size[index]; 39 | this->top_data_size.resize( 1 ); 40 | this->top_data_size[0] = this->bottom_data_size[0]; 41 | 42 | return 0; 43 | } 44 | 45 | template 46 | inline Dtype sigmoid_funtion( Dtype x ) 47 | { 48 | return Dtype(1) / ( Dtype(1) + Dtype(exp( -x )) ); 49 | } 50 | 51 | template 52 | static void sigmoid_each( T *arr, size_t size ) 53 | { 54 | auto gun = orz::ctx::lite::ptr(); 55 | if( gun == nullptr || gun->size() <= 1 ) 56 | { 57 | for( size_t i = 0; i < size; ++i ) 58 | { 59 | *arr = sigmoid_funtion( *arr ); 60 | ++arr; 61 | } 62 | } 63 | else 64 | { 65 | auto bins = orz::lsplit_bins( 0, size, gun->size() ); 66 | for( auto &bin : bins ) 67 | { 68 | gun->fire( [ &, bin]( int ) 69 | { 70 | auto local_arr = arr + bin.first; 71 | for( size_t i = bin.first; i < bin.second; ++i ) 72 | { 73 | *local_arr = sigmoid_funtion( *local_arr ); 74 | ++local_arr; 75 | } 76 | } ); 77 | } 78 | gun->join(); 79 | } 80 | } 81 | 82 | 83 | 84 | template 85 | int SeetaNetSigmoidCPU::Process( std::vector*> input_data_map, std::vector*> &output_data_map ) 86 | { 87 | input_data_map[0]->TransFormDataIn(); 88 | if( this->bottom_index[0] != this->top_index[0] ) 89 | { 90 | output_data_map[0]->dwStorageType = DATA_CPU_WIDTH; 91 | output_data_map[0]->data_shape[0] = input_data_map[0]->data_shape[0]; 92 | 93 | output_data_map[0]->data_shape[0] = input_data_map[0]->data_shape[0]; 94 | output_data_map[0]->data_shape[1] = input_data_map[0]->data_shape[1]; 95 | output_data_map[0]->data_shape[2] = input_data_map[0]->data_shape[2]; 96 | output_data_map[0]->data_shape[3] = input_data_map[0]->data_shape[3]; 97 | 98 | memcpy( output_data_map[0]->m_cpu.dataMemoryPtr(), input_data_map[0]->m_cpu.dataMemoryPtr(), sizeof( T )*output_data_map[0]->count() ); 99 | } 100 | 101 | sigmoid_each( output_data_map[0]->m_cpu.dataMemoryPtr(), output_data_map[0]->count() ); 102 | 103 | return 0; 104 | } 105 | 106 | #endif //!__SIGMOID_H__ 107 | -------------------------------------------------------------------------------- /SeetaNet/src/include_inner/layers/SeetaNetSplitCPU.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEETANET_SPLIT_CPU_H_ 2 | #define _SEETANET_SPLIT_CPU_H_ 3 | #include "SeetaNetBaseLayer.h" 4 | 5 | template 6 | class SeetaNetSplitCPU : public SeetaNetBaseLayer { 7 | public: 8 | SeetaNetSplitCPU(); 9 | ~SeetaNetSplitCPU(); 10 | 11 | int Init( seeta::SeetaNet_LayerParameter &inputparam, SeetaNetResource *pNetResource ); 12 | int Process( std::vector*> input_data_map, std::vector*> &output_data_map ); 13 | 14 | public: 15 | 16 | }; 17 | 18 | template 19 | SeetaNetSplitCPU::SeetaNetSplitCPU() 20 | { 21 | 22 | } 23 | 24 | 25 | template 26 | SeetaNetSplitCPU::~SeetaNetSplitCPU() 27 | { 28 | 29 | } 30 | 31 | 32 | template 33 | int SeetaNetSplitCPU::Init( seeta::SeetaNet_LayerParameter &inputparam, SeetaNetResource *pNetResource ) 34 | { 35 | int index = inputparam.bottom_index[0]; 36 | this->bottom_data_size.resize( 1 ); 37 | this->bottom_data_size[0] = pNetResource->feature_vector_size[index]; 38 | this->top_data_size.resize( inputparam.top_index.size() ); 39 | 40 | for( int i = 0; i < inputparam.top_index.size(); i++ ) 41 | { 42 | this->top_data_size[i] = this->bottom_data_size[0]; 43 | } 44 | 45 | return 0; 46 | } 47 | 48 | template 49 | int SeetaNetSplitCPU::Process( std::vector*> input_data_map, std::vector*> &output_data_map ) 50 | { 51 | input_data_map[0]->TransFormDataIn(); 52 | int all_size = 1; 53 | for( int i = 0; i < 4; i++ ) 54 | { 55 | all_size *= input_data_map[0]->data_shape[i]; 56 | } 57 | for( int i = 0; i < this->top_index.size(); i++ ) 58 | { 59 | memcpy( output_data_map[i]->m_cpu.dataMemoryPtr(), input_data_map[0]->m_cpu.dataMemoryPtr(), sizeof( T )*all_size ); 60 | output_data_map[i]->data_shape[0] = input_data_map[0]->data_shape[0]; 61 | output_data_map[i]->dwStorageType = DATA_CPU_WIDTH; 62 | 63 | output_data_map[i]->data_shape[0] = input_data_map[0]->data_shape[0]; 64 | output_data_map[i]->data_shape[1] = input_data_map[0]->data_shape[1]; 65 | output_data_map[i]->data_shape[2] = input_data_map[0]->data_shape[2]; 66 | output_data_map[i]->data_shape[3] = input_data_map[0]->data_shape[3]; 67 | } 68 | 69 | 70 | return 0; 71 | } 72 | 73 | #endif //!__SPLIT_H__ 74 | -------------------------------------------------------------------------------- /SeetaNet/src/orz/mem/pot.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Lby on 2017/8/12. 3 | // 4 | 5 | #include "pot.h" 6 | #include 7 | 8 | namespace seeta 9 | { 10 | 11 | namespace orz 12 | { 13 | 14 | static std::shared_ptr nolambda_template_allocator(size_t _size) 15 | { 16 | return std::shared_ptr(malloc(_size), free); 17 | } 18 | 19 | Pot::Pot() 20 | : Pot(nolambda_template_allocator) 21 | { 22 | } 23 | 24 | Pot::Pot(const allocator &ator) 25 | : m_allocator(ator), m_capacity(0), m_data() 26 | { 27 | 28 | } 29 | 30 | void *Pot::malloc(size_t _size) 31 | { 32 | if (_size > m_capacity) 33 | { 34 | m_data = m_allocator(_size); 35 | m_capacity = _size; 36 | } 37 | return m_data.get(); 38 | } 39 | 40 | void *Pot::relloc(size_t _size) 41 | { 42 | if (_size > m_capacity) 43 | { 44 | auto new_data = m_allocator(_size); 45 | #if _MSC_VER >= 1600 46 | memcpy_s(new_data.get(), _size, m_data.get(), m_capacity); 47 | #else 48 | memcpy(new_data.get(), m_data.get(), m_capacity); 49 | #endif 50 | m_data = new_data; 51 | m_capacity = _size; 52 | } 53 | return m_data.get(); 54 | } 55 | 56 | void *Pot::data() const 57 | { 58 | return m_data.get(); 59 | } 60 | 61 | size_t Pot::capacity() const 62 | { 63 | return m_capacity; 64 | } 65 | 66 | void Pot::dispose() 67 | { 68 | m_capacity = 0; 69 | m_data.reset(); 70 | } 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /SeetaNet/src/orz/mem/pot.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Lby on 2017/8/12. 3 | // 4 | 5 | #ifndef ORZ_MEM_POT_H 6 | #define ORZ_MEM_POT_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace seeta 13 | { 14 | 15 | namespace orz 16 | { 17 | 18 | class Pot { 19 | public: 20 | using allocator = std::function( size_t )>; 21 | 22 | Pot(); 23 | Pot( const allocator &ator ); 24 | 25 | void *malloc( size_t _size ); 26 | 27 | void *relloc( size_t _size ); 28 | 29 | template 30 | T *calloc( size_t _count, bool copy = false ) { 31 | if( copy ) 32 | return reinterpret_cast( this->relloc( sizeof( T ) * _count ) ); 33 | else 34 | return reinterpret_cast( this->malloc( sizeof( T ) * _count ) ); 35 | } 36 | 37 | void *data() const; 38 | 39 | size_t capacity() const; 40 | 41 | void dispose(); 42 | 43 | private: 44 | allocator m_allocator; 45 | 46 | private: 47 | size_t m_capacity; 48 | std::shared_ptr m_data; 49 | }; 50 | } 51 | 52 | } 53 | using namespace seeta; 54 | 55 | #endif //ORZ_MEM_POT_H 56 | -------------------------------------------------------------------------------- /SeetaNet/src/orz/mem/vat.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Lby on 2017/8/23. 3 | // 4 | 5 | #include "vat.h" 6 | #include 7 | 8 | #include "../tools/ctxmgr_lite_support.h" 9 | 10 | namespace seeta 11 | { 12 | 13 | namespace orz 14 | { 15 | 16 | Vat::Vat() 17 | { 18 | } 19 | 20 | void *Vat::malloc(size_t _size) 21 | { 22 | if (_size == 0) return nullptr; 23 | // find first small piece 24 | Pot pot; 25 | if (!m_heap.empty()) 26 | { 27 | size_t i = 0; 28 | for (; i < m_heap.size() - 1; ++i) 29 | { 30 | if (m_heap[i].capacity() >= _size) break; 31 | } 32 | pot = m_heap[i]; 33 | m_heap.erase(m_heap.begin() + i); 34 | } 35 | void *ptr = pot.malloc(_size); 36 | m_dict.insert(std::pair(ptr, pot)); 37 | 38 | return ptr; 39 | } 40 | 41 | void Vat::free(const void *ptr) 42 | { 43 | if (ptr == nullptr) return; 44 | auto key = const_cast(ptr); 45 | auto it = m_dict.find(key); 46 | if (it == m_dict.end()) 47 | { 48 | throw std::logic_error("Can not free this ptr"); 49 | } 50 | 51 | auto &pot = it->second; 52 | 53 | auto ind = m_heap.begin(); 54 | while (ind != m_heap.end() && ind->capacity() < pot.capacity()) ++ind; 55 | m_heap.insert(ind, pot); 56 | 57 | m_dict.erase(key); 58 | } 59 | 60 | void Vat::reset() 61 | { 62 | for (auto &pair : m_dict) 63 | { 64 | m_heap.push_back(pair.second); 65 | } 66 | m_dict.clear(); 67 | std::sort(m_heap.begin(), m_heap.end(), [](const orz::Pot &p1, const orz::Pot &p2) 68 | { 69 | return p1.capacity() < p2.capacity(); 70 | }); 71 | } 72 | 73 | void Vat::dispose() 74 | { 75 | m_dict.clear(); 76 | m_heap.clear(); 77 | } 78 | 79 | void Vat::swap(Vat &that) 80 | { 81 | this->m_heap.swap(that.m_heap); 82 | this->m_dict.swap(that.m_dict); 83 | } 84 | 85 | Vat::Vat(Vat &&that) 86 | { 87 | this->swap(that); 88 | } 89 | 90 | Vat &Vat::operator=(Vat &&that) 91 | { 92 | this->swap(that); 93 | return *this; 94 | } 95 | } 96 | 97 | ORZ_LITE_CONTEXT(orz::Vat) 98 | 99 | } 100 | -------------------------------------------------------------------------------- /SeetaNet/src/orz/mem/vat.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Lby on 2017/8/23. 3 | // 4 | 5 | #ifndef ORZ_MEM_VAT_H 6 | #define ORZ_MEM_VAT_H 7 | 8 | #include "pot.h" 9 | #include 10 | #include 11 | 12 | namespace seeta 13 | { 14 | 15 | namespace orz 16 | { 17 | 18 | class Vat { 19 | public: 20 | Vat(); 21 | 22 | void *malloc( size_t _size ); 23 | 24 | template 25 | T *calloc( size_t _count ) { 26 | return reinterpret_cast( this->malloc( sizeof( T ) * _count ) ); 27 | } 28 | 29 | template 30 | std::shared_ptr calloc_shared( size_t _count ) { 31 | return std::shared_ptr( calloc( _count ), [this]( T * ptr ) { 32 | this->free( ptr ); 33 | } ); 34 | } 35 | 36 | void free( const void *ptr ); 37 | 38 | /** 39 | * @brief doing like free all malloc ptrs 40 | */ 41 | void reset(); 42 | 43 | void dispose(); 44 | 45 | void swap( Vat &that ); 46 | 47 | Vat( Vat &&that ); 48 | 49 | Vat &operator=( Vat &&that ); 50 | 51 | private: 52 | Vat( const Vat &that ) = delete; 53 | 54 | Vat &operator=( const Vat &that ) = delete; 55 | 56 | // std::vector m_list; 57 | std::map m_dict; ///< save pair of pointer and index 58 | std::vector m_heap; ///< save all free memory, small fisrt sort 59 | }; 60 | 61 | } 62 | 63 | } 64 | using namespace seeta; 65 | 66 | #endif //ORZ_MEM_VAT_H 67 | -------------------------------------------------------------------------------- /SeetaNet/src/orz/sync/canyon.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Lby on 2017/8/11. 3 | // 4 | 5 | #include "canyon.h" 6 | 7 | namespace seeta 8 | { 9 | 10 | namespace orz 11 | { 12 | 13 | Canyon::Canyon( int size, Action act ) 14 | : _work( true ), _size( size ), _act( act ) 15 | { 16 | this->_core = std::thread( &Canyon::operating, this ); 17 | } 18 | 19 | Canyon::~Canyon() 20 | { 21 | this->join(); 22 | _work = false; 23 | _cond.notify_all(); 24 | _core.join(); 25 | } 26 | 27 | void Canyon::join() const 28 | { 29 | std::unique_lock _locker( _mutex ); 30 | while( _task.size() ) _cond.wait( _locker ); 31 | } 32 | 33 | void Canyon::push( const VoidOperator &op ) const 34 | { 35 | std::unique_lock _locker( _mutex ); 36 | while( _size > 0 && _task.size() >= static_cast( _size ) ) 37 | { 38 | switch( _act ) 39 | { 40 | case WAITING: 41 | _cond.wait( _locker ); 42 | break; 43 | case DISCARD: 44 | return; 45 | } 46 | } 47 | _task.push( op ); 48 | _cond.notify_all(); 49 | } 50 | 51 | void Canyon::operating() const 52 | { 53 | std::unique_lock _locker( _mutex ); 54 | while( _work ) 55 | { 56 | while( _work && _task.size() == 0 ) _cond.wait( _locker ); 57 | if( !_work ) break; 58 | auto func = _task.front(); 59 | _task.pop(); 60 | func(); 61 | _cond.notify_all(); 62 | } 63 | } 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /SeetaNet/src/orz/sync/canyon.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Lby on 2017/8/11. 3 | // 4 | 5 | #ifndef ORZ_SYNC_CANYON_H 6 | #define ORZ_SYNC_CANYON_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "../tools/void_bind.h" 17 | 18 | namespace seeta 19 | { 20 | 21 | namespace orz 22 | { 23 | 24 | class Canyon { 25 | public: 26 | enum Action 27 | { 28 | DISCARD, 29 | WAITING 30 | }; 31 | 32 | explicit Canyon( int size = -1, Action act = WAITING ); 33 | 34 | ~Canyon(); 35 | 36 | template 37 | void operator()( FUNC func ) const { 38 | auto op = [ = ]() -> void { func(); }; 39 | this->push( void_bind( func ) ); 40 | } 41 | 42 | template 43 | void operator()( FUNC func, Args &&... args ) const { 44 | this->push( void_bind( func, std::forward( args )... ) ); 45 | } 46 | 47 | void join() const; 48 | 49 | private: 50 | Canyon( const Canyon &that ) = delete; 51 | 52 | const Canyon &operator=( const Canyon &that ) = delete; 53 | 54 | void push( const VoidOperator &op ) const; 55 | 56 | void operating() const; 57 | 58 | mutable std::queue _task; 59 | mutable std::mutex _mutex; 60 | mutable std::condition_variable _cond; 61 | std::atomic _work; 62 | int _size; 63 | Action _act; 64 | 65 | std::thread _core; 66 | }; 67 | 68 | } 69 | 70 | } 71 | using namespace seeta; 72 | 73 | #endif //ORZ_SYNC_CANYON_H 74 | -------------------------------------------------------------------------------- /SeetaNet/src/orz/sync/cartridge.cpp: -------------------------------------------------------------------------------- 1 | #include "cartridge.h" 2 | 3 | namespace seeta 4 | { 5 | 6 | namespace orz 7 | { 8 | 9 | Cartridge::Cartridge() 10 | : dry( true ), bullet( nullptr ), shell( nullptr ) 11 | { 12 | this->powder = std::thread( &Cartridge::operating, this ); 13 | } 14 | 15 | Cartridge::~Cartridge() 16 | { 17 | dry = false; 18 | fire_cond.notify_all(); 19 | powder.join(); 20 | } 21 | 22 | void Cartridge::fire( int signet, const Cartridge::bullet_type &bullet, const Cartridge::shell_type &shell ) 23 | { 24 | std::unique_lock locker( fire_mutex ); 25 | this->signet = signet; 26 | this->bullet = bullet; 27 | this->shell = shell; 28 | fire_cond.notify_all(); 29 | } 30 | 31 | bool Cartridge::busy() 32 | { 33 | if( !fire_mutex.try_lock() ) return false; 34 | bool is_busy = bullet != nullptr; 35 | fire_mutex.unlock(); 36 | return is_busy; 37 | } 38 | 39 | void Cartridge::join() 40 | { 41 | std::unique_lock locker( fire_mutex ); 42 | while( bullet ) fire_cond.wait( locker ); 43 | } 44 | 45 | void Cartridge::operating() 46 | { 47 | std::unique_lock locker( fire_mutex ); 48 | while( dry ) 49 | { 50 | while( dry && !bullet ) fire_cond.wait( locker ); 51 | if( !dry ) break; 52 | bullet( signet ); 53 | if( shell ) shell( signet ); 54 | bullet = nullptr; 55 | shell = nullptr; 56 | fire_cond.notify_all(); 57 | } 58 | } 59 | 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /SeetaNet/src/orz/sync/cartridge.h: -------------------------------------------------------------------------------- 1 | #ifndef ORZ_SYNC_BULLET_H 2 | #define ORZ_SYNC_BULLET_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace seeta 11 | { 12 | 13 | namespace orz 14 | { 15 | 16 | class Cartridge { 17 | public: 18 | Cartridge(); 19 | 20 | ~Cartridge(); 21 | 22 | using bullet_type = std::function; 23 | using shell_type = std::function; 24 | 25 | /** 26 | * @brief fire Asynchronous build and fire bullet, first calls the bullet, then calls the shell. 27 | * @param signet the index to call `bullet(signet)` and `shell(signet)` 28 | * @param bullet the function call in thread 29 | * @param shell call it after bullet called 30 | */ 31 | void fire( int signet, const bullet_type &bullet, const shell_type &shell = nullptr ); 32 | 33 | bool busy(); 34 | 35 | void join(); 36 | 37 | private: 38 | Cartridge( const Cartridge &that ) = delete; 39 | const Cartridge &operator=( const Cartridge &that ) = delete; 40 | 41 | void operating(); 42 | 43 | std::mutex fire_mutex; ///< mutex control each fire 44 | std::condition_variable fire_cond; ///< condition to tell if fire finished 45 | std::atomic dry; ///< object only work when dry is true 46 | 47 | int signet; ///< the argument to call `bullet(signet)` and `shell(signet)` 48 | bullet_type bullet = nullptr; ///< main function call in thread 49 | shell_type shell = nullptr; ///< side function call after `bullet` called 50 | 51 | std::thread powder; ///< working thread 52 | 53 | }; 54 | 55 | } 56 | 57 | } 58 | using namespace seeta; 59 | 60 | #endif // ORZ_SYNC_BULLET_H 61 | -------------------------------------------------------------------------------- /SeetaNet/src/orz/sync/shotgun.cpp: -------------------------------------------------------------------------------- 1 | #include "shotgun.h" 2 | 3 | #include "../tools/ctxmgr_lite_support.h" 4 | 5 | namespace seeta 6 | { 7 | 8 | namespace orz 9 | { 10 | Shotgun::Shotgun( size_t clip_size ) 11 | : clip( clip_size ) 12 | { 13 | for( int i = 0; i < static_cast( clip_size ); ++i ) 14 | { 15 | clip[i] = new Cartridge(); 16 | chest.push_back( i ); // push all cartridge into chest 17 | } 18 | } 19 | 20 | Shotgun::~Shotgun() 21 | { 22 | for( int i = 0; i < static_cast( clip.size() ); ++i ) 23 | { 24 | delete clip[i]; 25 | } 26 | } 27 | 28 | Cartridge *Shotgun::fire( const Cartridge::bullet_type &bullet ) 29 | { 30 | if( clip.size() == 0 ) 31 | { 32 | bullet( 0 ); 33 | return nullptr; 34 | } 35 | else 36 | { 37 | int signet = load(); 38 | Cartridge *cart = this->clip[signet]; 39 | cart->fire( signet, bullet, 40 | Cartridge::shell_type( std::bind( &Shotgun::recycling_cartridge, this, std::placeholders::_1 ) ) ); 41 | return cart; 42 | } 43 | 44 | } 45 | 46 | Cartridge *Shotgun::fire( const Cartridge::bullet_type &bullet, const Cartridge::shell_type &shell ) 47 | { 48 | if( clip.size() == 0 ) 49 | { 50 | bullet( 0 ); 51 | return nullptr; 52 | } 53 | else 54 | { 55 | int signet = load(); 56 | Cartridge *cart = this->clip[signet]; 57 | cart->fire( signet, bullet, [this, shell]( int id ) -> void 58 | { 59 | shell( id ); 60 | this->recycling_cartridge( id ); 61 | } ); 62 | return cart; 63 | } 64 | 65 | } 66 | 67 | int Shotgun::load() 68 | { 69 | std::unique_lock locker( chest_mutex ); 70 | while( this->chest.empty() ) chest_cond.wait( locker ); 71 | int signet = this->chest.front(); 72 | this->chest.pop_front(); 73 | return signet; 74 | } 75 | 76 | void Shotgun::join() 77 | { 78 | std::unique_lock locker( chest_mutex ); 79 | while( this->chest.size() != this->clip.size() ) chest_cond.wait( locker ); 80 | } 81 | 82 | bool Shotgun::busy() 83 | { 84 | if( !chest_mutex.try_lock() ) return false; 85 | bool is_busy = this->chest.size() != this->clip.size(); 86 | chest_mutex.unlock(); 87 | return is_busy; 88 | } 89 | 90 | size_t Shotgun::size() const 91 | { 92 | return clip.size(); 93 | } 94 | 95 | void Shotgun::recycling_cartridge( int signet ) 96 | { 97 | std::unique_lock locker( chest_mutex ); 98 | this->chest.push_back( signet ); 99 | chest_cond.notify_all(); 100 | } 101 | 102 | } 103 | 104 | ORZ_LITE_CONTEXT( orz::Shotgun ) 105 | 106 | } 107 | -------------------------------------------------------------------------------- /SeetaNet/src/orz/sync/shotgun.h: -------------------------------------------------------------------------------- 1 | #ifndef ORZ_SYNC_SHOTGUN_H 2 | #define ORZ_SYNC_SHOTGUN_H 3 | 4 | #include "cartridge.h" 5 | 6 | #include 7 | #include 8 | 9 | namespace seeta 10 | { 11 | 12 | namespace orz 13 | { 14 | 15 | /** 16 | * @brief The Shotgun class the thread pool 17 | */ 18 | class Shotgun { 19 | public: 20 | /** 21 | * @brief Shotgun 22 | * @param clip_size The cartridge number in clip. Number of threads 23 | */ 24 | Shotgun( size_t clip_size ); 25 | 26 | ~Shotgun(); 27 | 28 | /** 29 | * @brief fire Find ready cartridge, build bullet and fire. 30 | * @param bullet the work ready to run 31 | * @return The cartridge running bullet 32 | */ 33 | Cartridge *fire( const Cartridge::bullet_type &bullet ); 34 | 35 | /** 36 | * @brief fire Find ready cartridge, build bullet and fire. 37 | * @param bullet the work ready to run 38 | * @param shell the work after bullet finished 39 | * @return The cartridge running bullet 40 | */ 41 | Cartridge *fire( const Cartridge::bullet_type &bullet, const Cartridge::shell_type &shell ); 42 | 43 | /** 44 | * @brief join Wait all cartridge working finish. 45 | */ 46 | void join(); 47 | 48 | /** 49 | * @brief busy Return if there are work running in thread 50 | * @return True if busy 51 | */ 52 | bool busy(); 53 | 54 | /** 55 | * @brief size Get number of threads 56 | * @return Number of threads 57 | */ 58 | size_t size() const; 59 | 60 | private: 61 | Shotgun( const Shotgun &that ) = delete; 62 | const Shotgun &operator=( const Shotgun &that ) = delete; 63 | 64 | /** 65 | * @brief load Get cartridge ready to fire 66 | * @return Get ready cartridge 67 | */ 68 | int load(); 69 | 70 | /** 71 | * @brief recycling_cartridge Recycle cartridge 72 | * @param signet cartridge index 73 | */ 74 | void recycling_cartridge( int signet ); 75 | 76 | std::vector clip; ///< all cartridges 77 | 78 | std::mutex chest_mutex; ///< mutex to get cartridges 79 | std::condition_variable chest_cond; ///< active when cartridge pushed in chest 80 | std::deque chest; ///< save all cartridge ready to fire 81 | }; 82 | 83 | } 84 | 85 | } 86 | using namespace seeta; 87 | 88 | #endif // ORZ_SYNC_SHOTGUN_H 89 | -------------------------------------------------------------------------------- /SeetaNet/src/orz/tools/box.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by kier on 2018/10/31. 3 | // 4 | 5 | #ifndef ORZ_TOOLS_BOX_H 6 | #define ORZ_TOOLS_BOX_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace seeta 14 | { 15 | 16 | namespace orz 17 | { 18 | using time_point = decltype( std::chrono::system_clock::now() ); 19 | 20 | /** 21 | * get edit distance of edit lhs to rhs 22 | * @param lhs original string 23 | * @param rhs wanted string 24 | * @return edit distance, 0 for `lhs == rhs` 25 | */ 26 | int edit_distance( const std::string &lhs, const std::string &rhs ); 27 | 28 | /** 29 | * get `bins` bins split set [first, second) 30 | * @param first min number 31 | * @param second max number 32 | * @param bins number of bins 33 | * @return A list contains splited bins 34 | * @note Example input(0, 10, 3) returns [(0, 4), (4, 8), (8, 10)] 35 | */ 36 | std::vector> split_bins( int first, int second, int bins ); 37 | 38 | /** 39 | * get `bins` bins split set [first, second) 40 | * @param first min number 41 | * @param second max number 42 | * @param bins number of bins 43 | * @return A list contains splited bins 44 | * @note Example input(0, 10, 3) returns [(0, 4), (4, 8), (8, 10)] 45 | */ 46 | std::vector> lsplit_bins( size_t first, size_t second, size_t bins ); 47 | 48 | std::string to_string( time_point tp, const std::string &format = "%Y-%m-%d %H:%M:%S" ); 49 | 50 | /** 51 | * return format now time string 52 | * @param format same as strftime 53 | * @return string contains now time 54 | * @see strftime 55 | */ 56 | std::string now_time( const std::string &format = "%Y-%m-%d %H:%M:%S" ); 57 | } 58 | 59 | } 60 | using namespace seeta; 61 | 62 | 63 | #endif //ORZ_TOOLS_BOX_H 64 | -------------------------------------------------------------------------------- /SeetaNet/src/orz/tools/ctxmgr_lite_support.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by kier on 2018/11/11. 3 | // 4 | 5 | #ifndef ORZ_TOOLS_CTXMGR_LITE_SUPPORT_HPP 6 | #define ORZ_TOOLS_CTXMGR_LITE_SUPPORT_HPP 7 | 8 | #include "ctxmgr_lite.h" 9 | 10 | namespace seeta 11 | { 12 | 13 | namespace orz 14 | { 15 | 16 | template 17 | ORZ_LITE_THREAD_LOCAL 18 | typename __thread_local_lite_context::context 19 | __thread_local_lite_context::m_ctx = nullptr; 20 | 21 | template 22 | typename __thread_local_lite_context::context 23 | __thread_local_lite_context::swap( typename __thread_local_lite_context::context ctx ) 24 | { 25 | auto pre_ctx = m_ctx; 26 | m_ctx = ctx; 27 | return pre_ctx; 28 | } 29 | 30 | template 31 | void __thread_local_lite_context::set( typename __thread_local_lite_context::context ctx ) 32 | { 33 | m_ctx = ctx; 34 | } 35 | 36 | template 37 | typename __thread_local_lite_context::context const __thread_local_lite_context::get() 38 | { 39 | if( m_ctx == nullptr ) throw NoLiteContextException(); 40 | return m_ctx; 41 | } 42 | 43 | template 44 | typename __thread_local_lite_context::context const __thread_local_lite_context::try_get() 45 | { 46 | return m_ctx; 47 | } 48 | 49 | template 50 | __lite_context::__lite_context( typename __lite_context::context ctx ) 51 | { 52 | this->m_now_ctx = ctx; 53 | this->m_pre_ctx = __thread_local_lite_context::swap( ctx ); 54 | } 55 | 56 | template 57 | __lite_context::~__lite_context() 58 | { 59 | __thread_local_lite_context::set( this->m_pre_ctx ); 60 | } 61 | 62 | template 63 | void __lite_context::set( typename __lite_context::context ctx ) 64 | { 65 | __thread_local_lite_context::set( ctx ); 66 | } 67 | 68 | template 69 | typename __lite_context::context __lite_context::get() 70 | { 71 | return __thread_local_lite_context::get(); 72 | } 73 | 74 | template 75 | typename __lite_context::context __lite_context::try_get() 76 | { 77 | return __thread_local_lite_context::try_get(); 78 | } 79 | 80 | template 81 | typename __lite_context::context __lite_context::ctx() 82 | { 83 | return m_now_ctx; 84 | } 85 | 86 | template 87 | typename __lite_context::context const __lite_context::ctx() const 88 | { 89 | return m_now_ctx; 90 | } 91 | } 92 | 93 | } 94 | 95 | #define ORZ_LITE_CONTEXT(T) \ 96 | template class orz::__thread_local_lite_context; \ 97 | template class orz::__lite_context; 98 | 99 | #endif // ORZ_TOOLS_CTXMGR_LITE_SUPPORT_HPP -------------------------------------------------------------------------------- /SeetaNet/src/orz/tools/void_bind.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by lby on 2018/1/23. 3 | // 4 | 5 | #ifndef ORZ_TOOLS_VOID_BIND_H 6 | #define ORZ_TOOLS_VOID_BIND_H 7 | 8 | #include 9 | 10 | namespace seeta 11 | { 12 | 13 | namespace orz 14 | { 15 | using VoidOperator = std::function; 16 | 17 | // for error C3848 in MSVC 18 | 19 | template 20 | class _Operator { 21 | public: 22 | static VoidOperator bind( FUNC func ) { 23 | return [func]() -> void 24 | { 25 | // for error C3848 in MSVC 26 | FUNC non_const_func = func; 27 | non_const_func(); 28 | }; 29 | } 30 | }; 31 | 32 | template 33 | class _Operator { 34 | public: 35 | static VoidOperator bind( FUNC func ) { 36 | return func; 37 | } 38 | }; 39 | 40 | template 41 | inline VoidOperator void_bind( FUNC func, Args &&... args ) 42 | { 43 | auto inner_func = std::bind( func, std::forward( args )... ); 44 | using Ret = decltype( inner_func() ); 45 | using RetOperator = _Operator; 46 | return RetOperator::bind( inner_func ); 47 | } 48 | 49 | template 50 | inline void void_call( FUNC func, Args &&... args ) 51 | { 52 | std::bind( func, std::forward( args )... )(); 53 | }; 54 | } 55 | 56 | } 57 | using namespace seeta; 58 | 59 | #endif //ORZ_TOOLS_VOID_BIND_H 60 | -------------------------------------------------------------------------------- /asserts/QR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seetafaceengine/SeetaFace2/a587833fef746e4dbc850f4bd0c62c1b5e7e2b52/asserts/QR.png -------------------------------------------------------------------------------- /asserts/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seetafaceengine/SeetaFace2/a587833fef746e4dbc850f4bd0c62c1b5e7e2b52/asserts/grid.png -------------------------------------------------------------------------------- /asserts/pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seetafaceengine/SeetaFace2/a587833fef746e4dbc850f4bd0c62c1b5e7e2b52/asserts/pipeline.png -------------------------------------------------------------------------------- /build_android.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -n "$1" ]; then 4 | ANDROID_NDK=$1 5 | fi 6 | if [ -z "${ANDROID_NDK}" ]; then 7 | echo "$0 ANDROID_NDK" 8 | exit -1 9 | fi 10 | 11 | if [ -z "${ANDROID_STL}" ]; then 12 | ANDROID_STL=c++_static 13 | fi 14 | 15 | if [ ! -d build ]; then 16 | mkdir -p build 17 | fi 18 | cd build 19 | 20 | cmake .. -G"Unix Makefiles" -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_VERBOSE_MAKEFILE=TRUE -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake -DANDROID_ABI="armeabi-v7a with NEON" -DANDROID_PLATFORM=android-18 -DANDROID_STL=${ANDROID_STL} -DBUILD_EXAMPLE=OFF # 如果有OpenCV,则设置为ON 21 | 22 | cmake --build . --config MinSizeRel -- -j`cat /proc/cpuinfo |grep 'cpu cores' |wc -l` 23 | 24 | cmake --build . --config MinSizeRel --target install/strip -- -j`cat /proc/cpuinfo |grep 'cpu cores' |wc -l` 25 | 26 | cd .. 27 | -------------------------------------------------------------------------------- /change.log: -------------------------------------------------------------------------------- 1 | [2019-8-22] 2 | - Remove FMA instructions by default. Use `-DSEETA_USE_FMA` to enable it. 3 | 4 | [2019-8-22] 5 | - Support IOS compilation, see `README.md` and `ios/cmake.sh` for more details. 6 | 7 | [2019-8-21] 8 | - Support ARM linux compilation, by adding PLATFORM option like `-DPLARTORM=ARM` 9 | -------------------------------------------------------------------------------- /ci/build-install-tools-windows.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #下载工具 3 | 4 | set -ev 5 | 6 | SOURCE_DIR="`pwd`" 7 | echo $SOURCE_DIR 8 | TOOLS_DIR=${SOURCE_DIR}/Tools 9 | echo ${TOOLS_DIR} 10 | 11 | if [ "$BUILD_TARGERT" = "android" ]; then 12 | export ANDROID_SDK_ROOT=${TOOLS_DIR}/android-sdk 13 | export ANDROID_NDK_ROOT=${TOOLS_DIR}/android-ndk 14 | export JAVA_HOME="/C/Program Files (x86)/Java/jdk1.8.0" 15 | export PATH=${TOOLS_DIR}/apache-ant/bin:$JAVA_HOME:$PATH 16 | else 17 | exit 0 18 | fi 19 | 20 | if [ ! -d "${TOOLS_DIR}" ]; then 21 | mkdir ${TOOLS_DIR} 22 | fi 23 | 24 | cd ${TOOLS_DIR} 25 | 26 | #下载ANT 27 | wget -c -nv http://apache.fayea.com//ant/binaries/apache-ant-1.10.1-bin.tar.gz 28 | tar xzf apache-ant-1.10.1-bin.tar.gz 29 | rm -f apache-ant-1.10.1-bin.tar.gz 30 | mv apache-ant-1.10.1 apache-ant 31 | 32 | #Download android sdk 33 | if [ ! -d "${TOOLS_DIR}/android-sdk" ]; then 34 | wget -c -nv https://dl.google.com/android/android-sdk_r24.4.1-windows.zip 35 | unzip -q android-sdk_r24.4.1-windows.zip 36 | mv android-sdk-windows android-sdk 37 | rm android-sdk_r24.4.1-windows.zip 38 | (sleep 5 ; while true ; do sleep 1 ; printf 'y\r\n' ; done ) \ 39 | | android-sdk/tools/android.bat update sdk -u -t tool,android-18,android-24,extra,platform,platform-tools,build-tools-24.0.1 40 | fi 41 | 42 | #下载android ndk 43 | if [ ! -d "${TOOLS_DIR}/android-ndk" ]; then 44 | wget -c -nv http://dl.google.com/android/ndk/android-ndk-r10e-windows-x86.exe 45 | ./android-ndk-r10e-windows-x86.exe > /dev/null 46 | mv android-ndk-r10e android-ndk 47 | rm android-ndk-r10e-windows-x86.exe 48 | fi 49 | 50 | cd ${SOURCE_DIR} 51 | -------------------------------------------------------------------------------- /ci/build-install-tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #下载工具 3 | 4 | set -e 5 | SOURCE_DIR="`pwd`" 6 | echo $SOURCE_DIR 7 | TOOLS_DIR=${SOURCE_DIR}/Tools 8 | 9 | function function_install_yasm() 10 | { 11 | #安装 yasm 12 | mkdir -p ${SOURCE_DIR}/Tools/src 13 | cd ${SOURCE_DIR}/Tools/src 14 | wget -c -nv http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz 15 | tar xzf yasm-1.3.0.tar.gz 16 | cd yasm-1.3.0/ 17 | ./configure > /dev/null && sudo make install -j2 > /dev/null 18 | cd ${SOURCE_DIR} 19 | } 20 | 21 | function function_common() 22 | { 23 | cd ${SOURCE_DIR}/Tools 24 | #下载最新cmake程序 25 | if [ "cmake" = "${QMAKE}" ]; then 26 | if [ ! -d "`pwd`/cmake" ]; then 27 | wget -nv --no-check-certificate http://www.cmake.org/files/v3.6/cmake-3.6.1-Linux-x86_64.tar.gz 28 | tar xzf cmake-3.6.1-Linux-x86_64.tar.gz 29 | mv cmake-3.6.1-Linux-x86_64 cmake 30 | fi 31 | fi 32 | } 33 | 34 | function function_android() 35 | { 36 | cd ${SOURCE_DIR}/Tools 37 | 38 | # install oracle jdk 39 | #sudo add-apt-repository ppa:linuxuprising/java -y 40 | #sudo apt update 41 | #(sleep 5 ; while true ; do sleep 1 ; printf '\r\n' ; done ) | sudo apt install oracle-java11-installer -qq -y 42 | 43 | #sudo apt install oracle-java11-set-default -qq -y 44 | 45 | #下载android ndk 46 | if [ ! -d "`pwd`/android-ndk" ]; then 47 | if [ "$QT_VERSION_DIR" = "5.9" ]; then 48 | wget -c -nv http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin 49 | chmod u+x android-ndk-r10e-linux-x86_64.bin 50 | ./android-ndk-r10e-linux-x86_64.bin > /dev/null 51 | mv android-ndk-r10e android-ndk 52 | rm android-ndk-r10e-linux-x86_64.bin 53 | else 54 | NDK_VERSION=r20 55 | wget -c -nv https://dl.google.com/android/repository/android-ndk-${NDK_VERSION}-linux-x86_64.zip 56 | unzip android-ndk-${NDK_VERSION}-linux-x86_64.zip 57 | mv android-ndk-${NDK_VERSION} android-ndk 58 | rm android-ndk-${NDK_VERSION}-linux-x86_64.zip 59 | fi 60 | fi 61 | 62 | cd ${SOURCE_DIR}/Tools 63 | 64 | #Download android sdk 65 | if [ ! -d "`pwd`/android-sdk" ]; then 66 | wget -c -nv https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz 67 | tar xf android-sdk_r24.4.1-linux.tgz 68 | mv android-sdk-linux android-sdk 69 | rm android-sdk_r24.4.1-linux.tgz 70 | (sleep 5 ; while true ; do sleep 1 ; printf 'y\r\n' ; done ) \ 71 | | android-sdk/tools/android update sdk -u #-t tool,android-18,android-24,extra,platform,platform-tools,build-tools-28.0.3 72 | fi 73 | 74 | sudo apt-get install ant -qq -y 75 | sudo apt-get install libicu-dev -qq -y 76 | 77 | function_common 78 | cd ${SOURCE_DIR} 79 | } 80 | 81 | function function_unix() 82 | { 83 | #汇编工具yasm 84 | #function_install_yasm 85 | 86 | sudo apt-get update -y -qq 87 | sudo apt-get install debhelper fakeroot -y -qq 88 | sudo apt-get install -y -qq libglu1-mesa-dev \ 89 | libxkbcommon-x11-dev \ 90 | libpulse-mainloop-glib0 \ 91 | libopencv-dev 92 | 93 | function_common 94 | 95 | cd ${SOURCE_DIR} 96 | } 97 | 98 | function function_mingw() 99 | { 100 | #汇编工具yasm 101 | #function_install_yasm 102 | 103 | cd ${SOURCE_DIR} 104 | if [ "true" == "$RABBITIM_BUILD_THIRDLIBRARY" ]; then 105 | export RABBITIM_BUILD_CROSS_HOST=i686-w64-mingw32 #i586-mingw32msvc 106 | fi 107 | 108 | function_common 109 | cd ${SOURCE_DIR} 110 | } 111 | 112 | case ${BUILD_TARGERT} in 113 | android) 114 | function_android 115 | ;; 116 | unix) 117 | function_unix 118 | ;; 119 | windows_mingw) 120 | function_mingw 121 | ;; 122 | *) 123 | echo "There aren't ${BUILD_TARGERT}" 124 | ;; 125 | esac 126 | 127 | cd ${SOURCE_DIR} 128 | -------------------------------------------------------------------------------- /ci/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | SOURCE_DIR=`pwd` 5 | if [ -n "$1" ]; then 6 | SOURCE_DIR=$1 7 | fi 8 | 9 | cd ${SOURCE_DIR} 10 | 11 | if [ "$BUILD_TARGERT" = "android" ]; then 12 | export ANDROID_SDK_ROOT=${SOURCE_DIR}/Tools/android-sdk 13 | export ANDROID_NDK_ROOT=${SOURCE_DIR}/Tools/android-ndk 14 | export ANDROID_SDK=${ANDROID_SDK_ROOT} 15 | export ANDROID_NDK=${ANDROID_NDK_ROOT} 16 | if [ -n "$APPVEYOR" ]; then 17 | export JAVA_HOME="/C/Program Files (x86)/Java/jdk1.8.0" 18 | fi 19 | if [ "$TRAVIS" = "true" ]; then 20 | export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 21 | fi 22 | export PATH=${SOURCE_DIR}/Tools/apache-ant/bin:$JAVA_HOME:$PATH 23 | fi 24 | 25 | cd ${SOURCE_DIR} 26 | 27 | if [ "$BUILD_TARGERT" != "windows_msvc" ]; then 28 | RABBIT_MAKE_JOB_PARA="-j`cat /proc/cpuinfo |grep 'cpu cores' |wc -l`" #make 同时工作进程参数 29 | if [ "$RABBIT_MAKE_JOB_PARA" = "-j1" ];then 30 | RABBIT_MAKE_JOB_PARA="-j2" 31 | fi 32 | fi 33 | 34 | if [ "$BUILD_TARGERT" = "windows_mingw" \ 35 | -a -n "$APPVEYOR" ]; then 36 | export PATH=/C/Qt/Tools/mingw${TOOLCHAIN_VERSION}/bin:$PATH 37 | fi 38 | TARGET_OS=`uname -s` 39 | case $TARGET_OS in 40 | MINGW* | CYGWIN* | MSYS*) 41 | export PKG_CONFIG=/c/msys64/mingw32/bin/pkg-config.exe 42 | ;; 43 | Linux* | Unix*) 44 | ;; 45 | *) 46 | ;; 47 | esac 48 | 49 | export PATH=${QT_ROOT}/bin:$PATH 50 | echo "PATH:$PATH" 51 | echo "PKG_CONFIG:$PKG_CONFIG" 52 | cd ${SOURCE_DIR} 53 | 54 | mkdir -p build_${BUILD_TARGERT} 55 | cd build_${BUILD_TARGERT} 56 | 57 | case ${BUILD_TARGERT} in 58 | windows_msvc) 59 | MAKE=nmake 60 | CONFIG_PARA="${CONFIG_PARA} -DBUILD_EXAMPLE=OFF" 61 | ;; 62 | windows_mingw) 63 | if [ "${RABBIT_BUILD_HOST}"="windows" ]; then 64 | MAKE="mingw32-make ${RABBIT_MAKE_JOB_PARA}" 65 | CONFIG_PARA="${CONFIG_PARA} -DBUILD_EXAMPLE=OFF" 66 | fi 67 | ;; 68 | *) 69 | MAKE="make ${RABBIT_MAKE_JOB_PARA}" 70 | ;; 71 | esac 72 | 73 | if [ -n "${BUILD_SHARED_LIBS}" ]; then 74 | CONFIG_PARA="${CONFIG_PARA} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}" 75 | fi 76 | 77 | if [ -n "${ANDROID_ARM_NEON}" ]; then 78 | CONFIG_PARA="${CONFIG_PARA} -DANDROID_ARM_NEON=${ANDROID_ARM_NEON}" 79 | fi 80 | echo "PWD:`pwd`" 81 | if [ "${BUILD_TARGERT}" = "android" ]; then 82 | TAR_FILE="SeetaFace_${BUILD_TARGERT}_${BUILD_ARCH}_${ANDROID_API}.tar.gz" 83 | cmake -G"${GENERATORS}" ${SOURCE_DIR} ${CONFIG_PARA} \ 84 | -DBUILD_EXAMPLE=OFF \ 85 | -DCMAKE_INSTALL_PREFIX=`pwd`/install \ 86 | -DCMAKE_VERBOSE=ON \ 87 | -DCMAKE_BUILD_TYPE=Release \ 88 | -DANDROID_PLATFORM=${ANDROID_API} -DANDROID_ABI="${BUILD_ARCH}" \ 89 | -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake 90 | 91 | else 92 | cmake -G"${GENERATORS}" ${SOURCE_DIR} ${CONFIG_PARA} \ 93 | -DCMAKE_INSTALL_PREFIX=`pwd`/install \ 94 | -DCMAKE_VERBOSE=ON \ 95 | -DCMAKE_BUILD_TYPE=Release 96 | fi 97 | cmake --build . --config Release --target install -- ${RABBIT_MAKE_JOB_PARA} 98 | 99 | if [ "${BUILD_TARGERT}" = "unix" -a "ON" = "${BUILD_SHARED_LIBS}" ]; then 100 | # configure C compiler 101 | export compiler=$(which gcc) 102 | # get version code 103 | MAJOR=$(echo __GNUC__ | $compiler -E -xc - | tail -n 1) 104 | MINOR=$(echo __GNUC_MINOR__ | $compiler -E -xc - | tail -n 1) 105 | PATCHLEVEL=$(echo __GNUC_PATCHLEVEL__ | $compiler -E -xc - | tail -n 1) 106 | TAR_FILE="SeetaFace_${BUILD_TARGERT}_gcc${MAJOR}.${MINOR}.${PATCHLEVEL}.tar.gz" 107 | fi 108 | if [ -n "${TAR_FILE}" -a "$TRAVIS_TAG" != "" ]; then 109 | TAR_FILE=`echo "${TAR_FILE}" | sed 's/[ ][ ]*/_/g'` 110 | cd `pwd`/install 111 | tar czf "${TAR_FILE}" * 112 | wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh 113 | chmod u+x upload.sh 114 | ./upload.sh "${TAR_FILE}" 115 | fi 116 | -------------------------------------------------------------------------------- /cmake/SeetaFaceConfig.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find SeetaFace 2 | # 3 | # Usage from an external project: 4 | # In your CMakeLists.txt, add these lines: 5 | # 6 | # find_package(SeetaFace) 7 | # target_link_libraries(MY_TARGET_NAME ${SeetaFace_LIBRARIES}) 8 | # 9 | # This file will define the following variables: 10 | # SeetaFace_FOUND: True if find SeetaFace, other false 11 | # SeetaFace_LIBRARIES: The list of all imported targets for SeetaFace components 12 | # 13 | # Author: Kang Lin 14 | 15 | include(FindPackageHandleStandardArgs) 16 | 17 | if (NOT SeetaFace_FIND_COMPONENTS) 18 | set(SeetaFace_FIND_COMPONENTS 19 | SeetaNet 20 | SeetaFaceDetector 21 | SeetaFaceLandmarker 22 | SeetaFaceRecognizer 23 | SeetaFaceTracker 24 | SeetaQualityAssessor 25 | ) 26 | endif() 27 | 28 | get_filename_component(_SeetaFace_module_paths "${CMAKE_CURRENT_LIST_DIR}" ABSOLUTE) 29 | 30 | set(_SeetaFace_FIND_PARTS_REQUIRED) 31 | if (SeetaFace_FIND_REQUIRED) 32 | set(_SeetaFace_FIND_PARTS_REQUIRED REQUIRED) 33 | endif() 34 | set(_SeetaFace_FIND_PARTS_QUIET) 35 | if (SeetaFace_FIND_QUIETLY) 36 | set(_SeetaFace_FIND_PARTS_QUIET QUIET) 37 | endif() 38 | 39 | foreach(module ${SeetaFace_FIND_COMPONENTS}) 40 | find_package(${module} 41 | ${_SeetaFace_FIND_PARTS_QUIET} 42 | ${_SeetaFace_FIND_PARTS_REQUIRED} 43 | PATHS ${_SeetaFace_module_paths} NO_DEFAULT_PATH 44 | ) 45 | if(${module}_FOUND) 46 | list(APPEND SeetaFace_LIBRARIES SeetaFace::${module}) 47 | endif() 48 | list(APPEND required "${module}_FOUND") 49 | endforeach() 50 | 51 | # Run checks via find_package_handle_standard_args 52 | find_package_handle_standard_args(SeetaFace 53 | FOUND_VAR SeetaFace_FOUND 54 | REQUIRED_VARS ${required}) 55 | -------------------------------------------------------------------------------- /cmake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | 2 | IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 3 | MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") 4 | ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 5 | 6 | FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 7 | STRING(REGEX REPLACE "\n" ";" files "${files}") 8 | FOREACH(file ${files}) 9 | MESSAGE(STATUS "Uninstalling \"${file}\"") 10 | IF(EXISTS "${file}") 11 | EXEC_PROGRAM( 12 | "@CMAKE_COMMAND@" ARGS "-E remove \"${file}\"" 13 | OUTPUT_VARIABLE rm_out 14 | RETURN_VALUE rm_retval 15 | ) 16 | IF("${rm_retval}" STREQUAL 0) 17 | ELSE("${rm_retval}" STREQUAL 0) 18 | MESSAGE(FATAL_ERROR "Problem when removing \"${file}\"") 19 | ENDIF("${rm_retval}" STREQUAL 0) 20 | ELSE(EXISTS "${file}") 21 | MESSAGE(STATUS "File \"${file}\" does not exist.") 22 | ENDIF(EXISTS "${file}") 23 | ENDFOREACH(file) 24 | -------------------------------------------------------------------------------- /documents/FaceDetector.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seetafaceengine/SeetaFace2/a587833fef746e4dbc850f4bd0c62c1b5e7e2b52/documents/FaceDetector.pdf -------------------------------------------------------------------------------- /documents/FaceLandmarks.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seetafaceengine/SeetaFace2/a587833fef746e4dbc850f4bd0c62c1b5e7e2b52/documents/FaceLandmarks.pdf -------------------------------------------------------------------------------- /documents/FaceRecognizer.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seetafaceengine/SeetaFace2/a587833fef746e4dbc850f4bd0c62c1b5e7e2b52/documents/FaceRecognizer.pdf -------------------------------------------------------------------------------- /example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Author: Kang Lin 3 | # Date : 2019-08-20 4 | # 5 | 6 | cmake_minimum_required(VERSION 2.8) 7 | project(Example) 8 | 9 | add_subdirectory(points81) 10 | add_subdirectory(search) 11 | add_subdirectory(tracking) 12 | add_subdirectory(crop_face) 13 | -------------------------------------------------------------------------------- /example/SeetaExample/SeetaExample.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "search", "..\search\search.vcxproj", "{F80B6DEF-BB9E-49BD-8AD0-C5A62EA752CB}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "points81", "..\points81\points81.vcxproj", "{A7981234-190A-4F36-AB6B-EFF228BF0D6C}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {F80B6DEF-BB9E-49BD-8AD0-C5A62EA752CB}.Debug|x64.ActiveCfg = Debug|x64 19 | {F80B6DEF-BB9E-49BD-8AD0-C5A62EA752CB}.Debug|x64.Build.0 = Debug|x64 20 | {F80B6DEF-BB9E-49BD-8AD0-C5A62EA752CB}.Debug|x86.ActiveCfg = Debug|Win32 21 | {F80B6DEF-BB9E-49BD-8AD0-C5A62EA752CB}.Debug|x86.Build.0 = Debug|Win32 22 | {F80B6DEF-BB9E-49BD-8AD0-C5A62EA752CB}.Release|x64.ActiveCfg = Release|x64 23 | {F80B6DEF-BB9E-49BD-8AD0-C5A62EA752CB}.Release|x64.Build.0 = Release|x64 24 | {F80B6DEF-BB9E-49BD-8AD0-C5A62EA752CB}.Release|x86.ActiveCfg = Release|Win32 25 | {F80B6DEF-BB9E-49BD-8AD0-C5A62EA752CB}.Release|x86.Build.0 = Release|Win32 26 | {A7981234-190A-4F36-AB6B-EFF228BF0D6C}.Debug|x64.ActiveCfg = Debug|x64 27 | {A7981234-190A-4F36-AB6B-EFF228BF0D6C}.Debug|x64.Build.0 = Debug|x64 28 | {A7981234-190A-4F36-AB6B-EFF228BF0D6C}.Debug|x86.ActiveCfg = Debug|Win32 29 | {A7981234-190A-4F36-AB6B-EFF228BF0D6C}.Debug|x86.Build.0 = Debug|Win32 30 | {A7981234-190A-4F36-AB6B-EFF228BF0D6C}.Release|x64.ActiveCfg = Release|x64 31 | {A7981234-190A-4F36-AB6B-EFF228BF0D6C}.Release|x64.Build.0 = Release|x64 32 | {A7981234-190A-4F36-AB6B-EFF228BF0D6C}.Release|x86.ActiveCfg = Release|Win32 33 | {A7981234-190A-4F36-AB6B-EFF228BF0D6C}.Release|x86.Build.0 = Release|Win32 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /example/crop_face/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Author: Kang Lin 3 | # Date : 2019-08-20 4 | # 5 | 6 | cmake_minimum_required(VERSION 2.8) 7 | 8 | project(crop_face) 9 | 10 | if(UNIX) 11 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") 12 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") 13 | endif() 14 | 15 | find_package(OpenCV REQUIRED) 16 | 17 | # add library 18 | add_executable(${PROJECT_NAME} example.cpp) 19 | target_include_directories(${PROJECT_NAME} PRIVATE 20 | ${CMAKE_CURRENT_SOURCE_DIR} 21 | ${CMAKE_SOURCE_DIR}/FaceDetector/include 22 | ${CMAKE_SOURCE_DIR}/FaceLandmarker/include 23 | ${CMAKE_SOURCE_DIR}/FaceRecognizer/include 24 | ${CMAKE_BINARY_DIR} 25 | ) 26 | target_include_directories(${PROJECT_NAME} PRIVATE 27 | ${OpenCV_INCLUDE_DIRS} 28 | ) 29 | 30 | target_link_libraries(${PROJECT_NAME} PRIVATE 31 | SeetaNet SeetaFaceDetector SeetaFaceLandmarker SeetaFaceRecognizer) 32 | target_link_libraries(${PROJECT_NAME} PRIVATE ${OpenCV_LIBS}) 33 | 34 | set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 35 | set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${BUILD_VERSION}) 36 | if(UNIX AND NOT ANDROID) 37 | set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_NAME ${PROJECT_NAME}) 38 | endif() 39 | INSTALL(TARGETS ${PROJECT_NAME} 40 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 41 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 42 | ) 43 | 44 | # Find user and system name 45 | # SET(SYSTEM_NAME $ENV{USERDOMAIN} CACHE STRING SystemName) 46 | # SET(USER_NAME $ENV{USERNAME} CACHE STRING UserName) 47 | 48 | if (MSVC_IDE) 49 | # Configure the template file 50 | SET(_CMAKE_LocalDebuggerEnvironment "PATH=${CMAKE_BINARY_DIR}/bin/$(Configuration);${CMAKE_BINARY_DIR}/lib/$(Configuration);${OpenCV_LIB_PATH}/../bin;%PATH%") 51 | SET(USER_FILE ${PROJECT_NAME}.vcxproj.user) 52 | SET(OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${USER_FILE}) 53 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/UserTemplate.xml ${USER_FILE} @ONLY) 54 | 55 | UNSET(USER_FILE) 56 | UNSET(OUTPUT_PATH) 57 | UNSET(_CMAKE_LocalDebuggerEnvironment) 58 | endif() 59 | -------------------------------------------------------------------------------- /example/crop_face/UserTemplate.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @_CMAKE_LocalDebuggerEnvironment@ $(LocalDebuggerEnvironment) 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/crop_face/example.cpp: -------------------------------------------------------------------------------- 1 | #pragma warning(disable: 4819) 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | seeta::ImageData crop_face( 17 | const seeta::FaceDetector &FD, 18 | const seeta::FaceLandmarker &PD, 19 | seeta::FaceRecognizer &FR, 20 | const SeetaImageData &original_image) { 21 | // detect face 22 | // detect points 23 | // crop face 24 | seeta::ImageData face(0, 0, 0); 25 | auto faces = FD.detect(original_image); 26 | if (faces.size == 0) return face; 27 | auto points = PD.mark(original_image, faces.data[0].pos); 28 | face = FR.CropFace(original_image, points.data()); 29 | return face; 30 | } 31 | 32 | int main() 33 | { 34 | seeta::ModelSetting::Device device = seeta::ModelSetting::CPU; 35 | int id = 0; 36 | seeta::ModelSetting FD_model( "./model/fd_2_00.dat", device, id ); 37 | seeta::ModelSetting PD_model( "./model/pd_2_00_pts5.dat", device, id ); 38 | 39 | std::string test_image = "1.jpg"; 40 | std::string crop_image_name = "crop_face.png"; 41 | 42 | seeta::FaceDetector FD(FD_model); 43 | seeta::FaceLandmarker PD(PD_model); 44 | // construct FR with on model, only for crop face. 45 | seeta::FaceRecognizer FR; 46 | 47 | FD.set(seeta::FaceDetector::PROPERTY_MIN_FACE_SIZE, 80); 48 | 49 | seeta::cv::ImageData image = cv::imread(test_image); 50 | if (image.empty()) { 51 | std::cerr << "Can not open image: " << test_image << std::endl; 52 | return 1; 53 | } 54 | 55 | auto face = crop_face(FD, PD, FR, image); 56 | 57 | if (face.width == 0 || face.height == 0) { 58 | std::cerr << "Can not detect any faces in image: " << test_image << std::endl; 59 | return 2; 60 | } 61 | 62 | seeta::cv::ImageData cv_face = face; 63 | 64 | cv::imwrite(crop_image_name, cv_face.toMat()); 65 | std::cout << "Save cropped image: " << crop_image_name << std::endl; 66 | 67 | return EXIT_SUCCESS; 68 | } 69 | -------------------------------------------------------------------------------- /example/crop_face/seeta/Struct_cv.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace seeta 8 | { 9 | namespace cv 10 | { 11 | // using namespace ::cv; 12 | class ImageData : public SeetaImageData { 13 | public: 14 | ImageData( const ::cv::Mat &mat ) 15 | : cv_mat( mat.clone() ) { 16 | this->width = cv_mat.cols; 17 | this->height = cv_mat.rows; 18 | this->channels = cv_mat.channels(); 19 | this->data = cv_mat.data; 20 | } 21 | 22 | ImageData( int width, int height, int channels = 3 ) 23 | : cv_mat( height, width, CV_8UC( channels ) ) { 24 | this->width = cv_mat.cols; 25 | this->height = cv_mat.rows; 26 | this->channels = cv_mat.channels(); 27 | this->data = cv_mat.data; 28 | } 29 | ImageData( const SeetaImageData &img ) 30 | : cv_mat( img.height, img.width, CV_8UC( img.channels ), img.data ) { 31 | this->width = cv_mat.cols; 32 | this->height = cv_mat.rows; 33 | this->channels = cv_mat.channels(); 34 | this->data = cv_mat.data; 35 | } 36 | ImageData() 37 | : cv_mat() { 38 | this->width = cv_mat.cols; 39 | this->height = cv_mat.rows; 40 | this->channels = cv_mat.channels(); 41 | this->data = cv_mat.data; 42 | } 43 | bool empty() const { 44 | return cv_mat.empty(); 45 | } 46 | operator ::cv::Mat() const { 47 | return cv_mat.clone(); 48 | } 49 | ::cv::Mat toMat() const { 50 | return cv_mat.clone(); 51 | } 52 | private: 53 | ::cv::Mat cv_mat; 54 | }; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /example/points81/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seetafaceengine/SeetaFace2/a587833fef746e4dbc850f4bd0c62c1b5e7e2b52/example/points81/1.jpg -------------------------------------------------------------------------------- /example/points81/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Author: Kang Lin 3 | # Date : 2019-08-20 4 | # 5 | 6 | cmake_minimum_required(VERSION 2.8) 7 | 8 | project("points81") 9 | 10 | if(UNIX) 11 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") 12 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") 13 | endif() 14 | 15 | find_package(OpenCV REQUIRED) 16 | 17 | # add library 18 | add_executable(${PROJECT_NAME} example.cpp) 19 | target_include_directories(${PROJECT_NAME} PRIVATE 20 | ${CMAKE_CURRENT_SOURCE_DIR} 21 | ${CMAKE_SOURCE_DIR}/SeetaNet/include 22 | ${CMAKE_SOURCE_DIR}/FaceDetector/include 23 | ${CMAKE_SOURCE_DIR}/FaceLandmarker/include 24 | ${CMAKE_BINARY_DIR} 25 | ) 26 | target_include_directories(${PROJECT_NAME} PRIVATE 27 | ${OpenCV_INCLUDE_DIRS} 28 | ) 29 | 30 | target_link_libraries(${PROJECT_NAME} PRIVATE 31 | SeetaNet SeetaFaceDetector SeetaFaceLandmarker) 32 | target_link_libraries(${PROJECT_NAME} PRIVATE ${OpenCV_LIBS}) 33 | 34 | set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 35 | set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${BUILD_VERSION}) 36 | if(UNIX AND NOT ANDROID) 37 | set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_NAME ${PROJECT_NAME}) 38 | endif() 39 | 40 | INSTALL(TARGETS ${PROJECT_NAME} 41 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 42 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 43 | ) 44 | 45 | # Find user and system name 46 | # SET(SYSTEM_NAME $ENV{USERDOMAIN} CACHE STRING SystemName) 47 | # SET(USER_NAME $ENV{USERNAME} CACHE STRING UserName) 48 | 49 | if (MSVC_IDE) 50 | # Configure the template file 51 | SET(_CMAKE_LocalDebuggerEnvironment "PATH=${CMAKE_BINARY_DIR}/bin/$(Configuration);${CMAKE_BINARY_DIR}/lib/$(Configuration);${OpenCV_LIB_PATH}/../bin;%PATH%") 52 | SET(USER_FILE ${PROJECT_NAME}.vcxproj.user) 53 | SET(OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${USER_FILE}) 54 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/UserTemplate.xml ${USER_FILE} @ONLY) 55 | 56 | UNSET(USER_FILE) 57 | UNSET(OUTPUT_PATH) 58 | UNSET(_CMAKE_LocalDebuggerEnvironment) 59 | endif() 60 | -------------------------------------------------------------------------------- /example/points81/UserTemplate.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @_CMAKE_LocalDebuggerEnvironment@ $(LocalDebuggerEnvironment) 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/points81/example.cpp: -------------------------------------------------------------------------------- 1 | #pragma warning(disable: 4819) 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | int test_image(seeta::FaceDetector &FD, seeta::FaceLandmarker &FL) 16 | { 17 | std::string image_path = "1.jpg"; 18 | std::cout << "Loading image: " << image_path << std::endl; 19 | auto frame = cv::imread(image_path); 20 | seeta::cv::ImageData simage = frame; 21 | 22 | if (simage.empty()) { 23 | std::cerr << "Can not open image: " << image_path << std::endl; 24 | return EXIT_FAILURE; 25 | } 26 | 27 | 28 | auto faces = FD.detect(simage); 29 | 30 | for (int i = 0; i < faces.size; ++i) 31 | { 32 | auto &face = faces.data[i]; 33 | auto points = FL.mark(simage, face.pos); 34 | 35 | cv::rectangle(frame, cv::Rect(face.pos.x, face.pos.y, face.pos.width, face.pos.height), CV_RGB(128, 128, 255), 3); 36 | for (auto &point : points) 37 | { 38 | cv::circle(frame, cv::Point(point.x, point.y), 3, CV_RGB(128, 255, 128), -1); 39 | } 40 | } 41 | 42 | auto output_path = image_path + ".pts81.png"; 43 | cv::imwrite(output_path, frame); 44 | std::cerr << "Saving result into: " << output_path << std::endl; 45 | 46 | return EXIT_SUCCESS; 47 | } 48 | 49 | int main() 50 | { 51 | seeta::ModelSetting::Device device = seeta::ModelSetting::CPU; 52 | int id = 0; 53 | seeta::ModelSetting FD_model( "./model/fd_2_00.dat", device, id ); 54 | seeta::ModelSetting FL_model( "./model/pd_2_00_pts81.dat", device, id ); 55 | 56 | seeta::FaceDetector FD(FD_model); 57 | seeta::FaceLandmarker FL(FL_model); 58 | 59 | FD.set(seeta::FaceDetector::PROPERTY_VIDEO_STABLE, 1); 60 | 61 | int camera_id = 0; 62 | cv::VideoCapture capture(camera_id); 63 | if (!capture.isOpened()) 64 | { 65 | std::cerr << "Can not open camera(" << camera_id << "), testing image..." << std::endl; 66 | return test_image(FD, FL); 67 | } 68 | 69 | // auto video_width = capture.get(cv::CAP_PROP_FRAME_WIDTH); 70 | // auto video_height = capture.get(cv::CAP_PROP_FRAME_HEIGHT); 71 | 72 | std::cout << "Open camera(" << camera_id << ")" << std::endl; 73 | 74 | cv::Mat frame; 75 | while (capture.isOpened()) 76 | { 77 | capture.grab(); 78 | capture.retrieve(frame); 79 | 80 | if (frame.empty()) break; 81 | 82 | seeta::cv::ImageData simage = frame; 83 | 84 | auto faces = FD.detect(simage); 85 | 86 | for (int i = 0; i < faces.size; ++i) 87 | { 88 | auto &face = faces.data[i]; 89 | auto points = FL.mark(simage, face.pos); 90 | 91 | cv::rectangle(frame, cv::Rect(face.pos.x, face.pos.y, face.pos.width, face.pos.height), CV_RGB(128, 128, 255), 3); 92 | for (auto &point : points) 93 | { 94 | cv::circle(frame, cv::Point(point.x, point.y), 2, CV_RGB(128, 255, 128), -1); 95 | } 96 | } 97 | 98 | cv::imshow("Frame", frame); 99 | auto key = cv::waitKey(20); 100 | if (key == 27) 101 | { 102 | break; 103 | } 104 | } 105 | 106 | return EXIT_SUCCESS; 107 | } 108 | -------------------------------------------------------------------------------- /example/points81/seeta/Struct_cv.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace seeta 8 | { 9 | namespace cv 10 | { 11 | // using namespace ::cv; 12 | class ImageData : public SeetaImageData { 13 | public: 14 | ImageData( const ::cv::Mat &mat ) 15 | : cv_mat( mat.clone() ) { 16 | this->width = cv_mat.cols; 17 | this->height = cv_mat.rows; 18 | this->channels = cv_mat.channels(); 19 | this->data = cv_mat.data; 20 | } 21 | 22 | ImageData( int width, int height, int channels = 3 ) 23 | : cv_mat( height, width, CV_8UC( channels ) ) { 24 | this->width = cv_mat.cols; 25 | this->height = cv_mat.rows; 26 | this->channels = cv_mat.channels(); 27 | this->data = cv_mat.data; 28 | } 29 | ImageData( const SeetaImageData &img ) 30 | : cv_mat( img.height, img.width, CV_8UC( img.channels ), img.data ) { 31 | this->width = cv_mat.cols; 32 | this->height = cv_mat.rows; 33 | this->channels = cv_mat.channels(); 34 | this->data = cv_mat.data; 35 | } 36 | ImageData() 37 | : cv_mat() { 38 | this->width = cv_mat.cols; 39 | this->height = cv_mat.rows; 40 | this->channels = cv_mat.channels(); 41 | this->data = cv_mat.data; 42 | } 43 | bool empty() const { 44 | return cv_mat.empty(); 45 | } 46 | operator ::cv::Mat() const { 47 | return cv_mat.clone(); 48 | } 49 | ::cv::Mat toMat() const { 50 | return cv_mat.clone(); 51 | } 52 | private: 53 | ::cv::Mat cv_mat; 54 | }; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /example/props/OpenCV3.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | $(OPENCV3_HOME) 6 | 310 7 | 8 | 9 | 10 | $(OpenCV3Home) 11 | 12 | 13 | $(OpenCV3Version) 14 | 15 | 16 | 17 | 18 | $(OpenCV3Home)\include;%(AdditionalIncludeDirectories) 19 | 20 | 21 | 22 | 23 | $(OpenCV3Home)\$(PlatformTarget)\vc12\lib;%(AdditionalLibraryDirectories) 24 | opencv_world$(OpenCV3Version)d.lib;%(AdditionalDependencies) 25 | 26 | 27 | %(Command) 28 | copy /Y "$(OpenCV3Home)\$(PlatformTarget)\vc12\bin\opencv_world$(OpenCV3Version)d.dll" "$(OutDir)" 29 | copy /Y "$(OpenCV3Home)\$(PlatformTarget)\vc12\bin\opencv_ffmpeg$(OpenCV3Version).dll" "$(OutDir)" 30 | 31 | 32 | 33 | 34 | 35 | $(OpenCV3Home)\$(PlatformTarget)\vc12\lib;%(AdditionalLibraryDirectories) 36 | opencv_world$(OpenCV3Version)d.lib;%(AdditionalDependencies) 37 | 38 | 39 | %(Command) 40 | copy /Y "$(OpenCV3Home)\$(PlatformTarget)\vc12\bin\opencv_world$(OpenCV3Version)d.dll" "$(OutDir)" 41 | copy /Y "$(OpenCV3Home)\$(PlatformTarget)\vc12\bin\opencv_ffmpeg$(OpenCV3Version)_64.dll" "$(OutDir)" 42 | 43 | 44 | 45 | 46 | 47 | $(OpenCV3Home)\$(PlatformTarget)\vc12\lib;%(AdditionalLibraryDirectories) 48 | opencv_world$(OpenCV3Version).lib;%(AdditionalDependencies) 49 | 50 | 51 | %(Command) 52 | copy /Y "$(OpenCV3Home)\$(PlatformTarget)\vc12\bin\opencv_world$(OpenCV3Version).dll" "$(OutDir)" 53 | copy /Y "$(OpenCV3Home)\$(PlatformTarget)\vc12\bin\opencv_ffmpeg$(OpenCV3Version).dll" "$(OutDir)" 54 | 55 | 56 | 57 | 58 | 59 | $(OpenCV3Home)\$(PlatformTarget)\vc12\lib;%(AdditionalLibraryDirectories) 60 | opencv_world$(OpenCV3Version).lib;%(AdditionalDependencies) 61 | 62 | 63 | %(Command) 64 | copy /Y "$(OpenCV3Home)\$(PlatformTarget)\vc12\bin\opencv_world$(OpenCV3Version).dll" "$(OutDir)" 65 | copy /Y "$(OpenCV3Home)\$(PlatformTarget)\vc12\bin\opencv_ffmpeg$(OpenCV3Version)_64.dll" "$(OutDir)" 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /example/props/SeetaFaceDetector.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | ../../craft/windows 6 | SeetaFaceDetector 7 | 2 8 | d 9 | true 10 | true 11 | 12 | 13 | 14 | $(FaceDetectorHome) 15 | 16 | 17 | $(FaceDetectorName) 18 | 19 | 20 | $(FaceDetectorVersion) 21 | 22 | 23 | $(FaceDetectorDebugFuffix) 24 | 25 | 26 | $(FaceDetectorLink) 27 | 28 | 29 | $(FaceDetectorCopy) 30 | 31 | 32 | 33 | 34 | $(FaceDetectorHome)\include;%(AdditionalIncludeDirectories) 35 | 36 | 37 | 38 | 39 | $(FaceDetectorHome)\lib\$(PlatformTarget);%(AdditionalLibraryDirectories) 40 | $(FaceDetectorName)$(FaceDetectorVersion)$(FaceDetectorDebugFuffix).lib;%(AdditionalDependencies) 41 | 42 | 43 | 44 | 45 | $(FaceDetectorHome)\lib\$(PlatformTarget);%(AdditionalLibraryDirectories) 46 | $(FaceDetectorName)$(FaceDetectorVersion).lib;%(AdditionalDependencies) 47 | 48 | 49 | 50 | 51 | %(Command) 52 | copy /Y "$(FaceDetectorHome)\lib\$(PlatformTarget)\$(FaceDetectorName)$(FaceDetectorVersion)$(FaceDetectorDebugFuffix).dll" "$(OutDir)" 53 | 54 | 55 | 56 | 57 | 58 | %(Command) 59 | copy /Y "$(FaceDetectorHome)\lib\$(PlatformTarget)\$(FaceDetectorName)$(FaceDetectorVersion).dll" "$(OutDir)" 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /example/props/SeetaFaceLandmarker.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | ../../craft/windows 6 | SeetaFaceLandmarker 7 | 2 8 | d 9 | true 10 | true 11 | 12 | 13 | 14 | $(PointDetectorHome) 15 | 16 | 17 | $(PointDetectorName) 18 | 19 | 20 | $(PointDetectorVersion) 21 | 22 | 23 | $(PointDetectorDebugFuffix) 24 | 25 | 26 | $(PointDetectorLink) 27 | 28 | 29 | $(PointDetectorCopy) 30 | 31 | 32 | 33 | 34 | $(PointDetectorHome)\include;%(AdditionalIncludeDirectories) 35 | 36 | 37 | 38 | 39 | $(PointDetectorHome)\lib\$(PlatformTarget);%(AdditionalLibraryDirectories) 40 | $(PointDetectorName)$(PointDetectorVersion)$(PointDetectorDebugFuffix).lib;%(AdditionalDependencies) 41 | 42 | 43 | 44 | 45 | $(PointDetectorHome)\lib\$(PlatformTarget);%(AdditionalLibraryDirectories) 46 | $(PointDetectorName)$(PointDetectorVersion).lib;%(AdditionalDependencies) 47 | 48 | 49 | 50 | 51 | %(Command) 52 | copy /Y "$(PointDetectorHome)\lib\$(PlatformTarget)\$(PointDetectorName)$(PointDetectorVersion)$(PointDetectorDebugFuffix).dll" "$(OutDir)" 53 | 54 | 55 | 56 | 57 | 58 | %(Command) 59 | copy /Y "$(PointDetectorHome)\lib\$(PlatformTarget)\$(PointDetectorName)$(PointDetectorVersion).dll" "$(OutDir)" 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /example/props/SeetaFaceRecognizer.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | ../../craft/windows 6 | SeetaFaceRecognizer 7 | 2 8 | d 9 | true 10 | true 11 | 12 | 13 | 14 | $(FaceRecognizerHome) 15 | 16 | 17 | $(FaceRecognizerName) 18 | 19 | 20 | $(FaceRecognizerVersion) 21 | 22 | 23 | $(FaceRecognizerDebugFuffix) 24 | 25 | 26 | $(FaceRecognizerLink) 27 | 28 | 29 | $(FaceRecognizerCopy) 30 | 31 | 32 | 33 | 34 | $(FaceRecognizerHome)\include;%(AdditionalIncludeDirectories) 35 | 36 | 37 | 38 | 39 | $(FaceRecognizerHome)\lib\$(PlatformTarget);%(AdditionalLibraryDirectories) 40 | $(FaceRecognizerName)$(FaceRecognizerVersion)$(FaceRecognizerDebugFuffix).lib;%(AdditionalDependencies) 41 | 42 | 43 | 44 | 45 | $(FaceRecognizerHome)\lib\$(PlatformTarget);%(AdditionalLibraryDirectories) 46 | $(FaceRecognizerName)$(FaceRecognizerVersion).lib;%(AdditionalDependencies) 47 | 48 | 49 | 50 | 51 | %(Command) 52 | copy /Y "$(FaceRecognizerHome)\lib\$(PlatformTarget)\$(FaceRecognizerName)$(FaceRecognizerVersion)$(FaceRecognizerDebugFuffix).dll" "$(OutDir)" 53 | 54 | 55 | 56 | 57 | 58 | %(Command) 59 | copy /Y "$(FaceRecognizerHome)\lib\$(PlatformTarget)\$(FaceRecognizerName)$(FaceRecognizerVersion).dll" "$(OutDir)" 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /example/props/SeetaNet.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | ../../craft/windows 6 | false 7 | true 8 | 9 | 10 | 11 | $(SeetaNetHome) 12 | 13 | 14 | $(SeetaNetLink) 15 | 16 | 17 | $(SeetaNetCopy) 18 | 19 | 20 | 21 | 22 | $(SeetaNetHome)\include;%(AdditionalIncludeDirectories) 23 | 24 | 25 | 26 | 27 | $(SeetaNetHome)\lib\$(PlatformTarget);%(AdditionalLibraryDirectories) 28 | seetanet2d.lib;%(AdditionalDependencies) 29 | 30 | 31 | 32 | 33 | $(SeetaNetHome)\lib\$(PlatformTarget);%(AdditionalLibraryDirectories) 34 | seetanet2d.lib;%(AdditionalDependencies) 35 | 36 | 37 | 38 | 39 | $(SeetaNetHome)\lib\$(PlatformTarget);%(AdditionalLibraryDirectories) 40 | seetanet2.lib;%(AdditionalDependencies) 41 | 42 | 43 | 44 | 45 | $(SeetaNetHome)\lib\$(PlatformTarget);%(AdditionalLibraryDirectories) 46 | seetanet2.lib;%(AdditionalDependencies) 47 | 48 | 49 | 50 | 51 | %(Command) 52 | copy /Y "$(SeetaNetHome)\lib\$(PlatformTarget)\seetanet2d.dll" "$(OutDir)" 53 | 54 | 55 | 56 | 57 | 58 | %(Command) 59 | copy /Y "$(SeetaNetHome)\lib\$(PlatformTarget)\seetanet2d.dll" "$(OutDir)" 60 | 61 | 62 | 63 | 64 | 65 | %(Command) 66 | copy /Y "$(SeetaNetHome)\lib\$(PlatformTarget)\seetanet2.dll" "$(OutDir)" 67 | 68 | 69 | 70 | 71 | 72 | %(Command) 73 | copy /Y "$(SeetaNetHome)\lib\$(PlatformTarget)\seetanet2.dll" "$(OutDir)" 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /example/search/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seetafaceengine/SeetaFace2/a587833fef746e4dbc850f4bd0c62c1b5e7e2b52/example/search/1.jpg -------------------------------------------------------------------------------- /example/search/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Author: Kang Lin 3 | # Date : 2019-08-20 4 | # 5 | 6 | cmake_minimum_required(VERSION 2.8) 7 | 8 | project(search) 9 | 10 | if(UNIX) 11 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") 12 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") 13 | endif() 14 | 15 | find_package(OpenCV REQUIRED) 16 | 17 | # add library 18 | add_executable(${PROJECT_NAME} example.cpp) 19 | target_include_directories(${PROJECT_NAME} PRIVATE 20 | ${CMAKE_CURRENT_SOURCE_DIR} 21 | ${CMAKE_SOURCE_DIR}/SeetaNet/include 22 | ${CMAKE_SOURCE_DIR}/FaceDetector/include 23 | ${CMAKE_SOURCE_DIR}/FaceLandmarker/include 24 | ${CMAKE_SOURCE_DIR}/FaceRecognizer/include 25 | ${CMAKE_SOURCE_DIR}/QualityAssessor/include 26 | ${CMAKE_BINARY_DIR} 27 | ) 28 | target_include_directories(${PROJECT_NAME} PRIVATE 29 | ${OpenCV_INCLUDE_DIRS} 30 | ) 31 | 32 | target_link_libraries(${PROJECT_NAME} PRIVATE 33 | SeetaNet SeetaFaceDetector SeetaFaceLandmarker SeetaFaceRecognizer SeetaQualityAssessor) 34 | target_link_libraries(${PROJECT_NAME} PRIVATE ${OpenCV_LIBS}) 35 | 36 | set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 37 | set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${BUILD_VERSION}) 38 | if(UNIX AND NOT ANDROID) 39 | set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_NAME ${PROJECT_NAME}) 40 | endif() 41 | INSTALL(TARGETS ${PROJECT_NAME} 42 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 43 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 44 | ) 45 | 46 | # Find user and system name 47 | # SET(SYSTEM_NAME $ENV{USERDOMAIN} CACHE STRING SystemName) 48 | # SET(USER_NAME $ENV{USERNAME} CACHE STRING UserName) 49 | 50 | if (MSVC_IDE) 51 | # Configure the template file 52 | SET(_CMAKE_LocalDebuggerEnvironment "PATH=${CMAKE_BINARY_DIR}/bin/$(Configuration);${CMAKE_BINARY_DIR}/lib/$(Configuration);${OpenCV_LIB_PATH}/../bin;%PATH%") 53 | SET(USER_FILE ${PROJECT_NAME}.vcxproj.user) 54 | SET(OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${USER_FILE}) 55 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/UserTemplate.xml ${USER_FILE} @ONLY) 56 | 57 | UNSET(USER_FILE) 58 | UNSET(OUTPUT_PATH) 59 | UNSET(_CMAKE_LocalDebuggerEnvironment) 60 | endif() 61 | -------------------------------------------------------------------------------- /example/search/UserTemplate.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @_CMAKE_LocalDebuggerEnvironment@ $(LocalDebuggerEnvironment) 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/search/seeta/Struct_cv.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace seeta 8 | { 9 | namespace cv 10 | { 11 | // using namespace ::cv; 12 | class ImageData : public SeetaImageData { 13 | public: 14 | ImageData( const ::cv::Mat &mat ) 15 | : cv_mat( mat.clone() ) { 16 | this->width = cv_mat.cols; 17 | this->height = cv_mat.rows; 18 | this->channels = cv_mat.channels(); 19 | this->data = cv_mat.data; 20 | } 21 | 22 | ImageData( int width, int height, int channels = 3 ) 23 | : cv_mat( height, width, CV_8UC( channels ) ) { 24 | this->width = cv_mat.cols; 25 | this->height = cv_mat.rows; 26 | this->channels = cv_mat.channels(); 27 | this->data = cv_mat.data; 28 | } 29 | ImageData( const SeetaImageData &img ) 30 | : cv_mat( img.height, img.width, CV_8UC( img.channels ), img.data ) { 31 | this->width = cv_mat.cols; 32 | this->height = cv_mat.rows; 33 | this->channels = cv_mat.channels(); 34 | this->data = cv_mat.data; 35 | } 36 | ImageData() 37 | : cv_mat() { 38 | this->width = cv_mat.cols; 39 | this->height = cv_mat.rows; 40 | this->channels = cv_mat.channels(); 41 | this->data = cv_mat.data; 42 | } 43 | bool empty() const { 44 | return cv_mat.empty(); 45 | } 46 | operator ::cv::Mat() const { 47 | return cv_mat.clone(); 48 | } 49 | ::cv::Mat toMat() const { 50 | return cv_mat.clone(); 51 | } 52 | private: 53 | ::cv::Mat cv_mat; 54 | }; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /example/tracking/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Author: Kang Lin 3 | # Date : 2019-08-20 4 | # 5 | 6 | cmake_minimum_required(VERSION 2.8) 7 | 8 | project("tracking") 9 | 10 | if(UNIX) 11 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") 12 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") 13 | endif() 14 | 15 | find_package(OpenCV REQUIRED) 16 | 17 | # add library 18 | add_executable(${PROJECT_NAME} example.cpp) 19 | target_include_directories(${PROJECT_NAME} PRIVATE 20 | ${CMAKE_CURRENT_SOURCE_DIR} 21 | ${CMAKE_SOURCE_DIR}/SeetaNet/include 22 | ${CMAKE_SOURCE_DIR}/FaceTracker/include 23 | ) 24 | target_include_directories(${PROJECT_NAME} PRIVATE 25 | ${OpenCV_INCLUDE_DIRS} 26 | ) 27 | 28 | target_link_libraries(${PROJECT_NAME} PRIVATE 29 | SeetaNet SeetaFaceTracker) 30 | target_link_libraries(${PROJECT_NAME} PRIVATE ${OpenCV_LIBS}) 31 | 32 | set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 33 | set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${BUILD_VERSION}) 34 | if(UNIX AND NOT ANDROID) 35 | set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_NAME ${PROJECT_NAME}) 36 | endif() 37 | INSTALL(TARGETS ${PROJECT_NAME} 38 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 39 | LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" 40 | ) 41 | 42 | # Find user and system name 43 | # SET(SYSTEM_NAME $ENV{USERDOMAIN} CACHE STRING SystemName) 44 | # SET(USER_NAME $ENV{USERNAME} CACHE STRING UserName) 45 | 46 | if (MSVC_IDE) 47 | # Configure the template file 48 | SET(_CMAKE_LocalDebuggerEnvironment "PATH=${CMAKE_BINARY_DIR}/bin/$(Configuration);${CMAKE_BINARY_DIR}/lib/$(Configuration);${OpenCV_LIB_PATH}/../bin;%PATH%") 49 | SET(USER_FILE ${PROJECT_NAME}.vcxproj.user) 50 | SET(OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${USER_FILE}) 51 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/UserTemplate.xml ${USER_FILE} @ONLY) 52 | 53 | UNSET(USER_FILE) 54 | UNSET(OUTPUT_PATH) 55 | UNSET(_CMAKE_LocalDebuggerEnvironment) 56 | endif() 57 | -------------------------------------------------------------------------------- /example/tracking/UserTemplate.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @_CMAKE_LocalDebuggerEnvironment@ $(LocalDebuggerEnvironment) 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/tracking/example.cpp: -------------------------------------------------------------------------------- 1 | #pragma warning(disable: 4819) 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | int main() 14 | { 15 | seeta::ModelSetting::Device device = seeta::ModelSetting::CPU; 16 | int id = 0; 17 | seeta::ModelSetting FD_model( "./model/fd_2_00.dat", device, id ); 18 | 19 | seeta::FaceTracker FD(FD_model); 20 | 21 | FD.set(seeta::FaceTracker::PROPERTY_VIDEO_STABLE, 1); 22 | 23 | int camera_id = 0; 24 | cv::VideoCapture capture(camera_id); 25 | if (!capture.isOpened()) 26 | { 27 | std::cerr << "Can not open camera(" << camera_id << ")" << std::endl; 28 | return -1; 29 | } 30 | 31 | // auto video_width = capture.get(cv::CAP_PROP_FRAME_WIDTH); 32 | // auto video_height = capture.get(cv::CAP_PROP_FRAME_HEIGHT); 33 | 34 | std::cout << "Open camera(" << camera_id << ")" << std::endl; 35 | 36 | cv::Mat frame; 37 | while (capture.isOpened()) 38 | { 39 | capture.grab(); 40 | capture.retrieve(frame); 41 | 42 | if (frame.empty()) break; 43 | 44 | seeta::cv::ImageData simage = frame; 45 | 46 | auto faces = FD.track(simage); 47 | 48 | for (int i = 0; i < faces.size; ++i) { 49 | auto &face = faces.data[i]; 50 | 51 | cv::rectangle(frame, cv::Rect(face.pos.x, face.pos.y, face.pos.width, face.pos.height), 52 | CV_RGB(128, 128, 255), 3); 53 | cv::putText(frame, std::to_string(face.PID), cv::Point(face.pos.x, face.pos.y - 5), 3, 1, 54 | CV_RGB(255, 128, 128)); 55 | } 56 | 57 | cv::imshow("Frame", frame); 58 | auto key = cv::waitKey(20); 59 | if (key == 27) 60 | { 61 | break; 62 | } 63 | } 64 | 65 | return EXIT_SUCCESS; 66 | } 67 | -------------------------------------------------------------------------------- /example/tracking/seeta/Struct_cv.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace seeta 8 | { 9 | namespace cv 10 | { 11 | // using namespace ::cv; 12 | class ImageData : public SeetaImageData { 13 | public: 14 | ImageData( const ::cv::Mat &mat ) 15 | : cv_mat( mat.clone() ) { 16 | this->width = cv_mat.cols; 17 | this->height = cv_mat.rows; 18 | this->channels = cv_mat.channels(); 19 | this->data = cv_mat.data; 20 | } 21 | 22 | ImageData( int width, int height, int channels = 3 ) 23 | : cv_mat( height, width, CV_8UC( channels ) ) { 24 | this->width = cv_mat.cols; 25 | this->height = cv_mat.rows; 26 | this->channels = cv_mat.channels(); 27 | this->data = cv_mat.data; 28 | } 29 | ImageData( const SeetaImageData &img ) 30 | : cv_mat( img.height, img.width, CV_8UC( img.channels ), img.data ) { 31 | this->width = cv_mat.cols; 32 | this->height = cv_mat.rows; 33 | this->channels = cv_mat.channels(); 34 | this->data = cv_mat.data; 35 | } 36 | ImageData() 37 | : cv_mat() { 38 | this->width = cv_mat.cols; 39 | this->height = cv_mat.rows; 40 | this->channels = cv_mat.channels(); 41 | this->data = cv_mat.data; 42 | } 43 | bool empty() const { 44 | return cv_mat.empty(); 45 | } 46 | operator ::cv::Mat() const { 47 | return cv_mat.clone(); 48 | } 49 | ::cv::Mat toMat() const { 50 | return cv_mat.clone(); 51 | } 52 | private: 53 | ::cv::Mat cv_mat; 54 | }; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ios/cmake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | BASE=$(cd `dirname $0`; pwd) 4 | ROOT=$BASE/.. 5 | 6 | cmake "$ROOT" -DCMAKE_TOOLCHAIN_FILE="$BASE"/iOS.cmake \ 7 | -DPLATFORM=ARM \ 8 | -DBUILD_EXAMPLE=OFF \ 9 | -DBUILD_SHARED_LIBS=OFF \ 10 | -DCMAKE_BUILD_TYPE=Release \ 11 | -DCMAKE_INSTALL_PREFIX=/usr/local \ 12 | -DIOS_DEPLOYMENT_TARGET=9 \ 13 | $@ 14 | 15 | # -DIOS_PLATFORM=OS 16 | # -DIOS_PLATFORM=SIMULATOR64 17 | 18 | --------------------------------------------------------------------------------