Mtcnn 是 啥? ncnn 应该知道吧.. 这里不做解释了..
贴出 mtcnn.cpp 关键代码 :
#ifdef __cplusplus
extern "C"{
MTCNN* MTCNN_new(const char* path){
std::string model_path(path);
return new MTCNN(model_path);
}
void c_detect(MTCNN* m,cv::Mat& frame,std::vector<Bbox>& finalBbox){
ncnn::Mat ncnn_img = ncnn::Mat::from_pixels(frame.data, ncnn::Mat::PIXEL_BGR2RGB, frame.cols, frame.rows);
m->detect(ncnn_img,finalBbox);
}
Bbox c_detect_2(MTCNN* m,unsigned char* data,int cols,int rows){
std::vector<Bbox> finalBbox;
Bbox face_rect= {0};
#ifdef LINUX_C_DEBUG
printf("__ face detect begin __ , cols : %d ,rows : %d \n",cols,rows);
printf("__ FILE : %s , LINE : %d , mtcnn object address :%p \n",__FILE__,__LINE__,m);
#endif
ncnn::Mat ncnn_img = ncnn::Mat::from_pixels(data, ncnn::Mat::PIXEL_BGR2RGB, cols, rows);//PIXEL_BGR2RGB
if(ncnn_img.empty()){
#ifdef LINUX_C_DEBUG
printf("-------img convert done 1---\n");
#endif
}
m->detect(ncnn_img,finalBbox);
if(finalBbox.size() > 0){
#ifdef LINUX_C_DEBUG
printf("-------face detect has done ---\n");
#endif
face_rect = finalBbox.at(0);
return face_rect;
}
return face_rect;
}
void c_setMinface(MTCNN* m,int minsize){
m->SetMinFace(minsize);
}
void c_setNumber(MTCNN* m,int numThreads){
m->SetNumThreads(numThreads);
}
}
#endif
python 代码处 :
#!/usr/bin python3
# -*- coding: utf-8 -*-
import sys
import ctypes
from ctypes import cdll
import cv2
import numpy as np
class Context(ctypes.Structure):
pass
ContextPtr = ctypes.POINTER(Context)
c_float_array10 = ctypes.c_float*10
c_float_array4 = ctypes.c_float*4
class Box(ctypes.Structure):
_fields_ = [('score', ctypes.c_float),
('x1', ctypes.c_int),
('x2', ctypes.c_int),
('y1', ctypes.c_int),
('y2', ctypes.c_int),
('area', ctypes.c_float),
('ppoint', c_float_array10),
('regreCoord', c_float_array4),
]
class FaceDetector:
def __init__(self):
self.load_lib_path = str("./libMtcnn.so")
self.lib_ptr = cdll.LoadLibrary(self.load_lib_path)
# 创建字符串
self.path = ctypes.create_string_buffer(b"models")
self.c_object = self.lib_ptr.MTCNN_new
# 指定必需的参数类型(函数原型)
self.c_object.argtypes = [ctypes.c_char_p]
self.c_object.restype = ContextPtr
self.c_object_ptr = self.c_object(self.path)
# 探测函数
self.c_object_function_detect = self.lib_ptr.c_detect_2
# 设置线程
self.c_object_function_setThread = self.lib_ptr.c_setNumber
# 人脸
self.c_object_function_setMinFace = self.lib_ptr.c_setMinface
# print(dir(self.c_object))
# 调用构造函数,传参
self.c_object_function_detect.argtypes = [ContextPtr,
ctypes.c_char_p,
ctypes.c_int,
ctypes.c_int
]
self.c_object_function_setThread.argtypes = [ContextPtr, ctypes.c_int]
self.c_object_function_detect.restype = Box
pass
def detect(self, face, width, height):
return self.c_object_function_detect(self.c_object_ptr, face, width, height)
pass
def set_thread_num(self, thread_num=2):
self.c_object_function_setThread(self.c_object_ptr, thread_num)
pass
def set_min_face(self, min_face_size):
self.c_object_function_setMinFace(self.c_object_ptr, min_face_size)
pass