Skip to content

Commit 8060ac9

Browse files
committed
release FaceAlginment
1 parent 657cd4e commit 8060ac9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+5745
-5207
lines changed

.vscode/c_cpp_properties.json

+2
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616
"${workspaceFolder}/FaceAlgorithm/lib",
1717
"${workspaceFolder}/FaceAlgorithm/face_detect_yolov5face",
1818
"${workspaceFolder}/FaceAlgorithm/face_detect_yolov7face",
19+
"${workspaceFolder}/FaceAlgorithm/face_detect_yolov8face",
1920
"${workspaceFolder}/FaceAlgorithm/face_recognition",
2021
"${workspaceFolder}/FaceAlgorithm/gender_age_recognition",
2122
"${workspaceFolder}/FaceAlgorithm/mask_recognition",
2223
"${workspaceFolder}/FaceAlgorithm/silent_face_anti_spoofing",
24+
"${workspaceFolder}/FaceAlgorithm/face_alignment",
2325
"${workspaceFolder}/common/*",
2426
"${workspaceFolder}/include/*",
2527
"${workspaceFolder}/include/Eigen"

.vscode/launch.json

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"type": "cppdbg",
77
"request": "launch",
88
"program":"${workspaceFolder}/build/FaceAlgorithm_Test/FaceRecognition_Test",
9+
//"program":"${workspaceFolder}/build/FaceAlgorithm/face_alignment/FaceAlginment_Test",
910
"args": [],
1011
"stopAtEntry": false,
1112
"cwd": "${fileDirname}",

FaceAlgorithm/CMakeLists.txt

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
cmake_minimum_required (VERSION 3.8)
2-
add_subdirectory ("face_detect")
3-
add_subdirectory ("face_detect_yolov5face")
4-
add_subdirectory ("face_detect_yolov7face")
5-
add_subdirectory ("face_detect_yolov8face")
6-
add_subdirectory ("face_recognition")
7-
add_subdirectory ("mask_recognition")
8-
add_subdirectory ("gender_age_recognition")
9-
add_subdirectory ("silent_face_anti_spoofing")
10-
add_subdirectory("lib")
11-
1+
cmake_minimum_required (VERSION 3.8)
2+
add_subdirectory ("face_detect")
3+
add_subdirectory ("face_detect_yolov5face")
4+
add_subdirectory ("face_detect_yolov7face")
5+
add_subdirectory ("face_detect_yolov8face")
6+
add_subdirectory ("face_recognition")
7+
add_subdirectory ("mask_recognition")
8+
add_subdirectory ("gender_age_recognition")
9+
add_subdirectory ("silent_face_anti_spoofing")
10+
add_subdirectory ("face_alignment")
11+
add_subdirectory("lib")
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
cmake_minimum_required(VERSION 3.8)
2+
3+
project(FaceAlignment)
4+
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -O0 -g -rdynamic -g2 -ggdb")
5+
find_package(CUDA REQUIRED)
6+
7+
SET(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/FaceAlgorithm/face_alignment/lib)
8+
9+
include_directories(${CMAKE_SOURCE_DIR}/include)
10+
include_directories(${CMAKE_SOURCE_DIR}/common)
11+
12+
#file(GLOB lib_header "${CMAKE_CURRENT_SOURCE_DIR}/*.h")
13+
file(GLOB common_header "${CMAKE_SOURCE_DIR}/common/*.h")
14+
15+
#file(GLOB lib_src "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
16+
file(GLOB common_src "${CMAKE_SOURCE_DIR}/common/*.cpp")
17+
18+
if (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
19+
message("embed_platform on")
20+
include_directories(/usr/local/cuda/targets/aarch64-linux/include)
21+
link_directories(/usr/local/cuda/targets/aarch64-linux/lib)
22+
else()
23+
message("embed_platform off")
24+
include_directories(/usr/local/cuda/include)
25+
link_directories(/usr/local/cuda/lib64)
26+
endif()
27+
28+
include_directories(${TensorRT_INCLUDE})
29+
link_directories(${TensorRT_LIB})
30+
find_package(OpenCV)
31+
include_directories(${OpenCV_INCLUDE_DIRS})
32+
33+
cuda_add_library(${PROJECT_NAME} SHARED Face_Alignment.cpp ${common_src})
34+
35+
if (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
36+
target_link_libraries(${PROJECT_NAME} "/usr/local/cuda/targets/aarch64-linux/lib/libcudart.so")
37+
else()
38+
target_link_libraries(${PROJECT_NAME} "/usr/local/cuda/lib64/libcudart.so")
39+
endif()
40+
target_link_libraries(${PROJECT_NAME} "${TensorRT_LIB}/libnvinfer.so")
41+
target_link_libraries(${PROJECT_NAME} "${TensorRT_LIB}/libnvonnxparser.so")
42+
target_link_libraries(${PROJECT_NAME} "${TensorRT_LIB}/libnvinfer_plugin.so")
43+
target_link_libraries(${PROJECT_NAME} "${TensorRT_LIB}/libcudnn.so")
44+
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
45+
target_link_libraries(${PROJECT_NAME} pthread)
46+
47+
add_executable(FaceAlginment_Test main.cpp)
48+
target_link_libraries(FaceAlginment_Test FaceAlignment)
49+
target_link_libraries(FaceAlginment_Test ${OpenCV_LIBS})
50+
51+
52+
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#include "Face_Alignment.h"
2+
3+
Face_Alignment::Face_Alignment()
4+
{
5+
}
6+
7+
Face_Alignment::~Face_Alignment()
8+
{
9+
}
10+
HZFLAG Face_Alignment::Face_AlignmentInit(Config&config)
11+
{
12+
Face_Alignment_INPUT_BLOB_NAME = "data";
13+
Face_Alignment_OUTPUT_BLOB_NAME = "fc1";
14+
Face_Alignment_INPUT_H = 192;
15+
Face_Alignment_INPUT_W = 192;
16+
Face_Alignment_OUTPUT_SIZE = 212;
17+
cudaSetDevice(config.gpu_id);
18+
char *trtModelStream{nullptr};
19+
size_t size{0};
20+
std::string directory;
21+
const size_t last_slash_idx = config.FaceAlignmentModelPath.rfind(".onnx");
22+
if (std::string::npos != last_slash_idx)
23+
{
24+
directory = config.FaceAlignmentModelPath.substr(0, last_slash_idx);
25+
}
26+
std::string out_engine = directory +"_batch="+ std::to_string(config.FaceAlignment_bs) + ".engine";
27+
bool enginemodel = Face_Alignment_model_exists(out_engine);
28+
if (!enginemodel)
29+
{
30+
std::cout << "Building engine, please wait for a while..." << std::endl;
31+
bool wts_model = Face_Alignment_model_exists(config.FaceAlignmentModelPath);
32+
if (!wts_model)
33+
{
34+
std::cout << "ONNX file is not Exist!Please Check!" << std::endl;
35+
return HZ_ERROR;
36+
}
37+
Onnx2Ttr onnx2trt;
38+
onnx2trt.onnxToTRTModel(Face_Alignment_gLogger,config.FaceAlignmentModelPath.c_str(),config.FaceAlignment_bs,out_engine.c_str());//config.classs_path
39+
}
40+
std::ifstream file(out_engine, std::ios::binary);
41+
if (file.good())
42+
{
43+
file.seekg(0, file.end);
44+
size = file.tellg();
45+
file.seekg(0, file.beg);
46+
trtModelStream = new char[size];
47+
assert(trtModelStream);
48+
file.read(trtModelStream, size);
49+
file.close();
50+
}
51+
Face_Alignment_runtime = createInferRuntime(Face_Alignment_gLogger);
52+
assert(Face_Alignment_runtime != nullptr);
53+
Face_Alignment_engine = Face_Alignment_runtime->deserializeCudaEngine(trtModelStream, size);
54+
assert(Face_Alignment_engine != nullptr);
55+
Face_Alignment_context =Face_Alignment_engine->createExecutionContext();
56+
assert(Face_Alignment_context != nullptr);
57+
delete[] trtModelStream;
58+
59+
Face_Alignment_data = new float[3 * Face_Alignment_INPUT_H * Face_Alignment_INPUT_W];
60+
Face_Alignment_prob = new float[Face_Alignment_OUTPUT_SIZE];
61+
62+
return HZ_SUCCESS;
63+
}
64+
HZFLAG Face_Alignment::Face_AlignmentRun(cv::Mat&img, AlignmentFace&alignmentface)
65+
{
66+
if (img.empty())
67+
{
68+
std::cout<<"Face_AlignmentRun image is empty"<<std::endl;
69+
return HZ_IMGEMPTY;
70+
}
71+
cv::Mat pr_img;
72+
cv::resize(img,pr_img, cv::Size(Face_Alignment_INPUT_H, Face_Alignment_INPUT_W));
73+
int i = 0;
74+
for (int row = 0; row < Face_Alignment_INPUT_H; ++row)
75+
{
76+
uchar* uc_pixel = pr_img.data + row * pr_img.step;
77+
for (int col = 0; col < Face_Alignment_INPUT_W; ++col)
78+
{
79+
Face_Alignment_data[i] = (float)uc_pixel[2];
80+
Face_Alignment_data[i + Face_Alignment_INPUT_H * Face_Alignment_INPUT_W] = (float)uc_pixel[1];
81+
Face_Alignment_data[i + 2 * Face_Alignment_INPUT_H * Face_Alignment_INPUT_W] = (float)uc_pixel[0];
82+
uc_pixel += 3;
83+
++i;
84+
}
85+
}
86+
// Run inference
87+
auto start = std::chrono::system_clock::now();
88+
Face_Alignment_doInference(*Face_Alignment_context,Face_Alignment_data,Face_Alignment_prob, 1);
89+
auto end = std::chrono::system_clock::now();
90+
for (int start = 0; start < 212; start += 2)
91+
{
92+
alignmentface.landmarks[start]=int((Face_Alignment_prob[start]+1)*img.cols / 2);
93+
alignmentface.landmarks[start+1]=int((Face_Alignment_prob[start+1]+1)*img.cols / 2);
94+
//cv::circle(img, cv::Point(alignmentface.landmarks[start], alignmentface.landmarks[start+1]), 1, cv::Scalar(200, 160, 75), -1, cv::LINE_8, 0);
95+
}
96+
//106 keypoint
97+
return HZ_SUCCESS;
98+
}
99+
HZFLAG Face_Alignment::Face_AlignmentRelease()
100+
{
101+
Face_Alignment_context->destroy();
102+
Face_Alignment_engine->destroy();
103+
Face_Alignment_runtime->destroy();
104+
delete[]Face_Alignment_data;
105+
delete[]Face_Alignment_prob;
106+
Face_Alignment_data = NULL;
107+
Face_Alignment_prob = NULL;
108+
return HZ_SUCCESS;
109+
}
110+
void Face_Alignment::Face_Alignment_doInference(IExecutionContext& context, float* input, float* output, int batchSize)
111+
{
112+
const ICudaEngine& engine = context.getEngine();
113+
114+
// Pointers to input and output device buffers to pass to engine.
115+
// Engine requires exactly IEngine::getNbBindings() number of buffers.
116+
assert(engine.getNbBindings() == 2);
117+
void* buffers[2];
118+
119+
// In order to bind the buffers, we need to know the names of the input and output tensors.
120+
// Note that indices are guaranteed to be less than IEngine::getNbBindings()
121+
const int inputIndex = engine.getBindingIndex(Face_Alignment_INPUT_BLOB_NAME);
122+
const int outputIndex = engine.getBindingIndex(Face_Alignment_OUTPUT_BLOB_NAME);
123+
124+
// Create GPU buffers on device
125+
CHECK(cudaMalloc(&buffers[inputIndex], batchSize * 3 * Face_Alignment_INPUT_H * Face_Alignment_INPUT_W * sizeof(float)));
126+
CHECK(cudaMalloc(&buffers[outputIndex], batchSize * Face_Alignment_OUTPUT_SIZE * sizeof(float)));
127+
128+
// Create stream
129+
cudaStream_t stream;
130+
CHECK(cudaStreamCreate(&stream));
131+
132+
// DMA input batch data to device, infer on the batch asynchronously, and DMA output back to host
133+
CHECK(cudaMemcpyAsync(buffers[inputIndex], input, batchSize * 3 * Face_Alignment_INPUT_H * Face_Alignment_INPUT_W * sizeof(float), cudaMemcpyHostToDevice, stream));
134+
context.enqueue(batchSize, buffers, stream, nullptr);
135+
CHECK(cudaMemcpyAsync(output, buffers[outputIndex], batchSize * Face_Alignment_OUTPUT_SIZE * sizeof(float), cudaMemcpyDeviceToHost, stream));
136+
cudaStreamSynchronize(stream);
137+
138+
// Release stream and buffers
139+
cudaStreamDestroy(stream);
140+
CHECK(cudaFree(buffers[inputIndex]));
141+
CHECK(cudaFree(buffers[outputIndex]));
142+
}
143+
bool Face_Alignment::Face_Alignment_model_exists(const std::string& name)
144+
{
145+
std::ifstream f(name.c_str());
146+
return f.good();
147+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#pragma once
2+
#include <iostream>
3+
#include <opencv2/opencv.hpp>
4+
#include <math.h>
5+
#include <fstream>
6+
#include <iostream>
7+
#include <map>
8+
#include <sstream>
9+
#include <vector>
10+
#include <chrono>
11+
#include "logging.h"
12+
#include "dirent.h"
13+
#include "NvInfer.h"
14+
#include "NvInferPlugin.h"
15+
#include "cuda_runtime_api.h"
16+
#include "ONNX2TRT.h"
17+
#include "DataTypes_Face.h"
18+
using namespace nvinfer1;
19+
#define CHECK(status) \
20+
do\
21+
{\
22+
auto ret = (status);\
23+
if (ret != 0)\
24+
{\
25+
std::cerr << "Cuda failure: " << ret << std::endl;\
26+
abort();\
27+
}\
28+
} while (0)
29+
30+
31+
class Face_Alignment
32+
{
33+
public:
34+
Face_Alignment();
35+
~Face_Alignment();
36+
HZFLAG Face_AlignmentInit(Config&config);
37+
HZFLAG Face_AlignmentRun(cv::Mat&img, AlignmentFace&alignmentface);
38+
HZFLAG Face_AlignmentRelease();
39+
private:
40+
char* Face_Alignment_INPUT_BLOB_NAME;
41+
char* Face_Alignment_OUTPUT_BLOB_NAME;
42+
int Face_Alignment_INPUT_H;
43+
int Face_Alignment_INPUT_W;
44+
int Face_Alignment_OUTPUT_SIZE; //class num
45+
float *Face_Alignment_data ;
46+
float *Face_Alignment_prob;
47+
Logger Face_Alignment_gLogger;
48+
IRuntime* Face_Alignment_runtime;
49+
ICudaEngine* Face_Alignment_engine;
50+
IExecutionContext* Face_Alignment_context;
51+
52+
private:
53+
void Face_Alignment_doInference(IExecutionContext& context, float* input, float* output, int batchSize);
54+
bool Face_Alignment_model_exists(const std::string& name);
55+
};
56+
57+
6.97 KB
Loading
Binary file not shown.

FaceAlgorithm/face_alignment/main.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include <iostream>
2+
#include <opencv2/opencv.hpp>
3+
#include "Face_Alignment.h"
4+
5+
int main()
6+
{
7+
//人脸检测的bbox可以按照中心点左右上下外扩1.2(左右上下各1.1)
8+
std::string data_model_path="/home/pcb/FaceRecognition_Linux_Release/FaceAlgorithm/";
9+
cv::Mat facealigenmentMat=cv::imread(data_model_path+"test5.jpg");
10+
Config config;
11+
config.FaceAlignment_bs=1;
12+
config.FaceAlignmentModelPath=data_model_path+"2d106det_bs=1.onnx";
13+
14+
15+
Face_Alignment face_alignment;
16+
face_alignment.Face_AlignmentInit(config);
17+
18+
AlignmentFace alignmentface;
19+
face_alignment.Face_AlignmentRun(facealigenmentMat,alignmentface);
20+
for (size_t k = 0; k < 212; k+=2)
21+
{
22+
cv::circle(facealigenmentMat, cv::Point(alignmentface.landmarks[k], alignmentface.landmarks[k+1]), 1, cv::Scalar(200, 160, 75), -1, cv::LINE_8,0);
23+
}
24+
cv::imwrite("FaceAlignment_result.jpg",facealigenmentMat);
25+
std::cout<<"facealigenment test finash!"<<std::endl;
26+
face_alignment.Face_AlignmentRelease();
27+
return 0;
28+
}

0 commit comments

Comments
 (0)