feat(pose): add utralight posenet

This commit is contained in:
Syd Xu
2021-10-27 18:00:58 +08:00
parent 5d0fc1244f
commit 92025ffdc8
47 changed files with 423 additions and 181 deletions

View File

@@ -50,6 +50,12 @@ var (
Message: "detect head pose failed",
}
}
DetectPoseError = func(code int) Error {
return Error{
Code: code,
Message: "detect pose failed",
}
}
RealsrError = func(code int) Error {
return Error{
Code: code,

View File

@@ -27,7 +27,7 @@ type Detecter interface {
func LoadModel(d Detecter, modelPath string) error {
cpath := C.CString(modelPath)
defer C.free(unsafe.Pointer(cpath))
retCode := C.detecter_load_model(d.Handler(), cpath)
retCode := C.load_model((C.IEstimator)(unsafe.Pointer(d.Handler())), cpath)
if retCode != 0 {
return openvision.LoadModelError(int(retCode))
}
@@ -36,7 +36,7 @@ func LoadModel(d Detecter, modelPath string) error {
// Destroy a detecter
func Destroy(d Detecter) {
C.destroy_detecter(d.Handler())
C.destroy_estimator((C.IEstimator)(unsafe.Pointer(d.Handler())))
}
// DetectFace detect face useing detecter

View File

@@ -25,7 +25,7 @@ func NewRetinaFace() *RetinaFace {
// Destroy free detecter
func (d *RetinaFace) Destroy() {
C.destroy_detecter(d.d)
Destroy(d)
}
func (d *RetinaFace) Handler() C.IDetecter {

View File

@@ -65,7 +65,7 @@ func (f FaceInfo) CFaceInfo() *C.FaceInfo {
// NewCFaceInfoVector returns C.FaceInfoVector pointer
func NewCFaceInfoVector() *C.FaceInfoVector {
return (*C.FaceInfoVector)(C.malloc(C.sizeof_FaceInfo))
return (*C.FaceInfoVector)(C.malloc(C.sizeof_FaceInfoVector))
}
// GoFaceInfoVector conver c FaceInfoVector to go FaceInfo slice

View File

@@ -1,2 +1,2 @@
// Package hopenet head pose detecter
// Package hopenet include head pose estimation
package hopenet

View File

@@ -3,7 +3,6 @@ package hopenet
/*
#include <stdlib.h>
#include <stdbool.h>
#include "openvision/face/common.h"
#include "openvision/face/hopenet.h"
*/
import "C"
@@ -17,7 +16,7 @@ import (
// Hopenet represents Hopenet detecter
type Hopenet struct {
d C.IHopeNet
d C.IHopenet
}
// NewHopenet returns a new Hopenet
@@ -27,22 +26,23 @@ func NewHopenet() *Hopenet {
}
}
// Destroy destroy C.IHopeNet
func (h *Hopenet) Destroy() {
C.destroy_hopenet(h.d)
}
// LoadModel load detecter model
func (h *Hopenet) LoadModel(modelPath string) error {
cpath := C.CString(modelPath)
defer C.free(unsafe.Pointer(cpath))
retCode := C.hopenet_load_model(h.d, cpath)
retCode := C.load_model((C.IEstimator)(unsafe.Pointer(h.d)), cpath)
if retCode != 0 {
return openvision.LoadModelError(int(retCode))
}
return nil
}
// Detect
// Destroy destroy C.IHopeNet
func (h *Hopenet) Destroy() {
C.destroy_estimator((C.IEstimator)(unsafe.Pointer(h.d)))
}
// Detect head pose
func (h *Hopenet) Detect(img *common.Image, faceRect common.Rectangle) (face.HeadPose, error) {
imgWidth := img.WidthF64()
imgHeight := img.HeightF64()

View File

@@ -26,7 +26,7 @@ type Landmarker interface {
func LoadModel(d Landmarker, modelPath string) error {
cpath := C.CString(modelPath)
defer C.free(unsafe.Pointer(cpath))
retCode := C.landmarker_load_model(d.Handler(), cpath)
retCode := C.load_model((C.IEstimator)(unsafe.Pointer(d.Handler())), cpath)
if retCode != 0 {
return openvision.LoadModelError(int(retCode))
}
@@ -35,7 +35,7 @@ func LoadModel(d Landmarker, modelPath string) error {
// Destroy a landmarker
func Destroy(d Landmarker) {
C.destroy_landmarker(d.Handler())
C.destroy_estimator((C.IEstimator)(unsafe.Pointer(d.Handler())))
}
// ExtractKeypoints extract keypoints using landmarker
@@ -50,7 +50,7 @@ func ExtractKeypoints(d Landmarker, img *common.Image, faceRect common.Rectangle
CPoints := common.NewCPoint2fVector()
defer common.FreeCPoint2fVector(CPoints)
CRect := faceRect.CRect()
errCode := C.extract_keypoints(
errCode := C.extract_face_keypoints(
d.Handler(),
(*C.uchar)(unsafe.Pointer(&data[0])),
C.int(imgWidth), C.int(imgHeight),

View File

@@ -26,7 +26,7 @@ type Recognizer interface {
func LoadModel(r Recognizer, modelPath string) error {
cpath := C.CString(modelPath)
defer C.free(unsafe.Pointer(cpath))
retCode := C.recognizer_load_model(r.Handler(), cpath)
retCode := C.load_model((C.IEstimator)(unsafe.Pointer(r.Handler())), cpath)
if retCode != 0 {
return openvision.LoadModelError(int(retCode))
}
@@ -35,7 +35,7 @@ func LoadModel(r Recognizer, modelPath string) error {
// Destroy a recognizer
func Destroy(r Recognizer) {
C.destroy_recognizer(r.Handler())
C.destroy_estimator((C.IEstimator)(unsafe.Pointer(r.Handler())))
}
// ExtractFeatures extract features using recognizer

View File

@@ -26,7 +26,7 @@ func GoTrackedFaceInfo(cInfo *C.TrackedFaceInfo, w float64, h float64) TrackedFa
// NewCTrackedFaceInfoVector returns C.TrackedFaceInfoVector pointer
func NewCTrackedFaceInfoVector() *C.TrackedFaceInfoVector {
return (*C.TrackedFaceInfoVector)(C.malloc(C.sizeof_TrackedFaceInfo))
return (*C.TrackedFaceInfoVector)(C.malloc(C.sizeof_TrackedFaceInfoVector))
}
// GoTrackedFaceInfoVector conver c TrackedFaceInfoVector to go TrackedFaceInfo slice

11
go/pose/cgo.go Normal file
View File

@@ -0,0 +1,11 @@
// +build !vulkan
package pose
/*
#cgo CXXFLAGS: --std=c++11 -fopenmp
#cgo CPPFLAGS: -I ${SRCDIR}/../../include -I /usr/local/include
#cgo LDFLAGS: -lstdc++ -lncnn -lomp -lopenvision
#cgo LDFLAGS: -L /usr/local/lib -L ${SRCDIR}/../../lib
*/
import "C"

11
go/pose/cgo_vulkan.go Normal file
View File

@@ -0,0 +1,11 @@
// +build vulkan
package pose
/*
#cgo CXXFLAGS: --std=c++11 -fopenmp
#cgo CPPFLAGS: -I ${SRCDIR}/../../include -I /usr/local/include
#cgo LDFLAGS: -lstdc++ -lncnn -lomp -lopenvision -lglslang -lvulkan -lSPIRV -lOGLCompiler -lMachineIndependent -lGenericCodeGen -lOSDependent
#cgo LDFLAGS: -L /usr/local/lib -L ${SRCDIR}/../../lib
*/
import "C"

11
go/pose/detecter/cgo.go Normal file
View File

@@ -0,0 +1,11 @@
// +build !vulkan
package detecter
/*
#cgo CXXFLAGS: --std=c++11 -fopenmp
#cgo CPPFLAGS: -I ${SRCDIR}/../../../include -I /usr/local/include
#cgo LDFLAGS: -lstdc++ -lncnn -lomp -lopenvision
#cgo LDFLAGS: -L /usr/local/lib -L ${SRCDIR}/../../../lib
*/
import "C"

View File

@@ -0,0 +1,11 @@
// +build vulkan
package detecter
/*
#cgo CXXFLAGS: --std=c++11 -fopenmp
#cgo CPPFLAGS: -I ${SRCDIR}/../../../include -I /usr/local/include
#cgo LDFLAGS: -lstdc++ -lncnn -lomp -lopenvision -lglslang -lvulkan -lSPIRV -lOGLCompiler -lMachineIndependent -lGenericCodeGen -lOSDependent
#cgo LDFLAGS: -L /usr/local/lib -L ${SRCDIR}/../../../lib
*/
import "C"

View File

@@ -0,0 +1,86 @@
package detecter
/*
#include <stdlib.h>
#include <stdbool.h>
#include "openvision/pose/common.h"
#include "openvision/pose/detecter.h"
*/
import "C"
import (
"unsafe"
openvision "github.com/bububa/openvision/go"
"github.com/bububa/openvision/go/common"
"github.com/bububa/openvision/go/pose"
)
// Detecter represents deteter interface
type Detecter interface {
Handler() C.IDetecter
LoadModel(modelPath string) error
ExtractKeypoints(img *common.Image) ([]pose.ROI, error)
Destroy()
}
// LoadModel load detecter model
func LoadModel(d Detecter, modelPath string) error {
cpath := C.CString(modelPath)
defer C.free(unsafe.Pointer(cpath))
retCode := C.load_model((C.IEstimator)(unsafe.Pointer(d.Handler())), cpath)
if retCode != 0 {
return openvision.LoadModelError(int(retCode))
}
return nil
}
// Destroy a detecter
func Destroy(d Detecter) {
C.destroy_estimator((C.IEstimator)(unsafe.Pointer(d.Handler())))
}
// ExtractKeypoints detect pose keypoints using detecter
func ExtractKeypoints(d Detecter, img *common.Image) ([]pose.ROI, error) {
imgWidth := img.WidthF64()
imgHeight := img.HeightF64()
data := img.Bytes()
cROIs := pose.NewCROIVector()
defer pose.FreeCROIVector(cROIs)
errCode := C.extract_pose_rois(
d.Handler(),
(*C.uchar)(unsafe.Pointer(&data[0])),
C.int(imgWidth),
C.int(imgHeight),
(*C.PoseROIVector)(unsafe.Pointer(cROIs)))
if errCode != 0 {
return nil, openvision.DetectPoseError(int(errCode))
}
totalROIs := pose.CROIVectiorLength(cROIs)
rois := make([]pose.ROI, 0, totalROIs)
ptr := unsafe.Pointer(cROIs)
for i := 0; i < totalROIs; i++ {
cKeypoints := pose.NewCKeypointVector()
defer pose.FreeCKeypointVector(cKeypoints)
cROI := (*C.PoseROI)(unsafe.Pointer(uintptr(ptr) + uintptr(C.sizeof_PoseROI*C.int(i))))
errCode := C.extract_pose_keypoints(
d.Handler(),
cROI,
(*C.PoseKeypointVector)(unsafe.Pointer(cKeypoints)))
if errCode != 0 {
return nil, openvision.DetectPoseError(int(errCode))
}
keypoints := pose.GoKeypointVector(cKeypoints, imgWidth, imgHeight)
rois = append(rois, pose.ROI{
Keypoints: keypoints,
Rect: common.Rect(
float64(cROI.rect.x)/imgWidth,
float64(cROI.rect.y)/imgHeight,
float64(cROI.rect.width)/imgWidth,
float64(cROI.rect.height)/imgHeight,
),
Score: float32(cROI.score),
})
}
return rois, nil
}

2
go/pose/detecter/doc.go Normal file
View File

@@ -0,0 +1,2 @@
// Package detecter pose detecter
package detecter

View File

@@ -0,0 +1,44 @@
package detecter
/*
#include <stdlib.h>
#include <stdbool.h>
#include "openvision/pose/detecter.h"
*/
import "C"
import (
"github.com/bububa/openvision/go/common"
"github.com/bububa/openvision/go/pose"
)
// Ultralight represents utralight detecter
type Ultralight struct {
d C.IDetecter
}
// NewUltralight returns a new Utralight
func NewUltralight() *Ultralight {
return &Ultralight{
d: C.new_ultralight(),
}
}
// Destroy free detecter
func (d *Ultralight) Destroy() {
Destroy(d)
}
// Handler returns C.IDetecter
func (d *Ultralight) Handler() C.IDetecter {
return d.d
}
// LoadModel load model for detecter
func (d *Ultralight) LoadModel(modelPath string) error {
return LoadModel(d, modelPath)
}
// ExtractKeypoints implement Detecter interface
func (d *Ultralight) ExtractKeypoints(img *common.Image) ([]pose.ROI, error) {
return ExtractKeypoints(d, img)
}

2
go/pose/doc.go Normal file
View File

@@ -0,0 +1,2 @@
// Package pose include pose estimation
package pose

63
go/pose/keypoint.go Normal file
View File

@@ -0,0 +1,63 @@
package pose
/*
#include <stdlib.h>
#include <stdbool.h>
#include "openvision/pose/common.h"
*/
import "C"
import (
"unsafe"
"github.com/bububa/openvision/go/common"
)
// Keypoint represents detected body keypoint
type Keypoint struct {
// Point keypoint location
Point common.Point
// Score keypoint prob
Score float32
}
// GoKeypoint convert C.PoseKeypoint to go type
func GoKeypoint(c *C.PoseKeypoint, w float64, h float64) Keypoint {
return Keypoint{
Point: common.Pt(float64(c.p.x)/w, float64(c.p.y)/h),
Score: float32(c.prob),
}
}
// Convert Keypoint to C.Keypoint pointer
func (k Keypoint) CKeypoint() *C.PoseKeypoint {
ret := (*C.PoseKeypoint)(C.malloc(C.sizeof_PoseKeypoint))
ret.prob = C.float(k.Score)
ret.p = C.Point2f{
C.float(k.Point.X),
C.float(k.Point.Y),
}
return ret
}
// NewCKeypointVector returns *C.PoseKeypointVector
func NewCKeypointVector() *C.PoseKeypointVector {
return (*C.PoseKeypointVector)(C.malloc(C.sizeof_PoseKeypointVector))
}
// FreeCKeypointVector release *C.PoseKeypointVector memory
func FreeCKeypointVector(points *C.PoseKeypointVector) {
C.FreePoseKeypointVector(points)
C.free(unsafe.Pointer(points))
}
// GoKeypointVector convert *C.PoseKeypointVector to Keypoint slice
func GoKeypointVector(c *C.PoseKeypointVector, w float64, h float64) []Keypoint {
l := int(c.length)
ret := make([]Keypoint, 0, l)
ptr := unsafe.Pointer(c.points)
for i := 0; i < l; i++ {
cKeypoint := (*C.PoseKeypoint)(unsafe.Pointer(uintptr(ptr) + uintptr(C.sizeof_PoseKeypoint*C.int(i))))
ret = append(ret, GoKeypoint(cKeypoint, w, h))
}
return ret
}

38
go/pose/roi.go Normal file
View File

@@ -0,0 +1,38 @@
package pose
/*
#include <stdlib.h>
#include <stdbool.h>
#include "openvision/pose/common.h"
*/
import "C"
import (
"unsafe"
"github.com/bububa/openvision/go/common"
)
// ROI represents detected person roi
type ROI struct {
// Score detected score
Score float32
// Rect roi location
Rect common.Rectangle
// Keypoints
Keypoints []Keypoint
}
// NewROIVector returns *C.PoseROIVector
func NewCROIVector() *C.PoseROIVector {
return (*C.PoseROIVector)(C.malloc(C.sizeof_PoseROIVector))
}
// FreeCROIVector release *C.PoseROIVectore memory
func FreeCROIVector(p *C.PoseROIVector) {
C.FreePoseROIVector(p)
C.free(unsafe.Pointer(p))
}
func CROIVectiorLength(c *C.PoseROIVector) int {
return int(c.length)
}

View File

@@ -30,14 +30,14 @@ func NewRealERSGAN(gpuid int, ttaMode bool) *RealESRGAN {
// Destroy a detecter
func (d *RealESRGAN) Destroy() {
C.destroy_realesrgan(d.d)
C.destroy_estimator((C.IEstimator)(unsafe.Pointer(d.d)))
}
// LoadModel load processer model
func (d *RealESRGAN) LoadModel(modelPath string) error {
cpath := C.CString(modelPath)
defer C.free(unsafe.Pointer(cpath))
retCode := C.realesrgan_load_model(d.d, cpath)
retCode := C.load_model((C.IEstimator)(unsafe.Pointer(d.d)), cpath)
if retCode != 0 {
return openvision.LoadModelError(int(retCode))
}

View File

@@ -122,7 +122,14 @@ target_include_directories(openvision
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/face/recognizer>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/face/recognizer/mobilefacenet>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/face/tracker>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/face/hopenet>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/face/pose>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/face/pose/common>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/face/pose/detecter>
)
#install(TARGETS openvision EXPORT openvision ARCHIVE DESTINATION ${LIBRARY_OUTPUT_PATH})

View File

@@ -27,6 +27,14 @@ void destroy_gpu_instance() {
#endif // OV_VULKAN
}
int load_model(IEstimator d, const char *root_path) {
return static_cast<ov::Estimator*>(d)->LoadModel(root_path);
}
void destroy_estimator(IEstimator d) {
delete static_cast<ov::Estimator*>(d);
}
void FreePoint2fVector(Point2fVector* p) {
if (p->points != NULL) {
free(p->points);

View File

@@ -42,9 +42,13 @@ typedef struct Rect {
#endif
typedef void* IEstimator;
int get_gpu_count();
int create_gpu_instance();
void destroy_gpu_instance();
int load_model(IEstimator e, const char* root_path);
void destroy_estimator(IEstimator e);
typedef struct Point2fVector {
Point2f* points;

View File

@@ -11,6 +11,12 @@
namespace ov {
const int threads_num = 2;
class Estimator {
public:
virtual ~Estimator(){};
virtual int LoadModel(const char* root_path) = 0;
};
// Wrapper for an individual cv::cvSize
typedef struct Size {
int width;

View File

@@ -12,8 +12,6 @@ extern "C" {
IDetecter new_centerface();
IDetecter new_mtcnn();
IDetecter new_anticonv();
void destroy_detecter(IDetecter d);
int detecter_load_model(IDetecter d, const char* root_path);
int detect_face(IDetecter d, const unsigned char* rgbdata, int img_width, int img_height, FaceInfoVector* faces);
#ifdef __cplusplus
}

View File

@@ -20,14 +20,6 @@ IDetecter new_anticonv() {
return new ov::AntiConv();
}
void destroy_detecter(IDetecter d) {
delete static_cast<ov::Detecter*>(d);
}
int detecter_load_model(IDetecter d, const char *root_path){
return static_cast<ov::Detecter*>(d)->LoadModel(root_path);
}
int detect_face(IDetecter d, const unsigned char* rgbdata, int img_width, int img_height, FaceInfoVector* faces) {
std::vector<FaceInfo> detected;
int ret = static_cast<ov::Detecter*>(d)->DetectFace(rgbdata, img_width, img_height, &detected);

View File

@@ -5,10 +5,9 @@
namespace ov {
// 抽象类
class Detecter {
class Detecter: public Estimator {
public:
virtual ~Detecter() {};
virtual int LoadModel(const char* root_path) = 0;
virtual int DetectFace(const unsigned char* rgbdata,
int img_width, int img_height,
std::vector<FaceInfo>* faces) = 0;
@@ -19,7 +18,7 @@ public:
class DetecterFactory {
public:
virtual Detecter* CreateDetecter() = 0;
virtual ~DetecterFactory() {};
virtual ~DetecterFactory() {}
};
// 不同人脸检测器

View File

@@ -1,5 +1,5 @@
#ifndef _ROS_NCNN_HOPENET_C_H_
#define _ROS_NCNN_HOPENET_C_H_
#ifndef _FACE_HOPENET_C_H_
#define _FACE_HOPENET_C_H_
#include "common.h"
@@ -7,12 +7,10 @@
#include "hopenet/hopenet.hpp"
extern "C" {
#endif
typedef void* IHopeNet;
IHopeNet new_hopenet();
void destroy_hopenet(IHopeNet h);
int hopenet_load_model(IHopeNet h, const char* root_path);
int hopenet_detect(IHopeNet h, const unsigned char* rgbdata, int img_width, int img_height, const Rect* roi, HeadPose* euler_angles);
typedef void* IHopenet;
IHopenet new_hopenet();
int hopenet_detect(IHopenet d, const unsigned char* rgbdata, int img_width, int img_height, const Rect* roi, HeadPose* euler_angles);
#ifdef __cplusplus
}
#endif
#endif
#endif // !_FACE_HOPENET_C_H_

View File

@@ -7,27 +7,21 @@
#include "gpu.h"
#endif // OV_VULKAN
#define NEAR_0 1e-10
#define ODIM 66
IHopeNet new_hopenet() {
return new ov::HopeNet();
IHopenet new_hopenet() {
return new ov::Hopenet();
}
void destroy_hopenet(IHopeNet h) {
delete static_cast<ov::HopeNet*>(h);
}
int hopenet_load_model(IHopeNet h, const char* root_path) {
return static_cast<ov::HopeNet*>(h)->LoadModel(root_path);
}
int hopenet_detect(IHopeNet h, const unsigned char* rgbdata, int img_width, int img_height, const Rect* roi, HeadPose* euler_angles) {
return static_cast<ov::HopeNet*>(h)->Detect(rgbdata, img_width, img_height, *roi, static_cast<ov::HeadPose*>(euler_angles));
int hopenet_detect(IHopenet h, const unsigned char* rgbdata, int img_width, int img_height, const Rect* roi, HeadPose* euler_angles) {
return static_cast<ov::Hopenet*>(h)->Detect(rgbdata, img_width, img_height, *roi, static_cast<ov::HeadPose*>(euler_angles));
}
namespace ov {
HopeNet::HopeNet():
#define NEAR_0 1e-10
#define ODIM 66
Hopenet::Hopenet():
net_(new ncnn::Net()),
initialized_(false) {
#ifdef OV_VULKAN
@@ -35,13 +29,13 @@ HopeNet::HopeNet():
#endif // OV_VULKAN
}
HopeNet::~HopeNet() {
Hopenet::~Hopenet() {
if (net_) {
net_->clear();
}
}
int HopeNet::LoadModel(const char * root_path) {
int Hopenet::LoadModel(const char * root_path) {
std::string param_file = std::string(root_path) + "/param";
std::string bin_file = std::string(root_path) + "/bin";
if (net_->load_param(param_file.c_str()) == -1 ||
@@ -55,7 +49,7 @@ int HopeNet::LoadModel(const char * root_path) {
}
int HopeNet::Detect(const unsigned char* rgbdata,
int Hopenet::Detect(const unsigned char* rgbdata,
int img_width, int img_height,
Rect roi, HeadPose* head_angles) {
float diff = fabs(roi.height-roi.width);
@@ -101,7 +95,7 @@ int HopeNet::Detect(const unsigned char* rgbdata,
return 0;
}
void HopeNet::softmax(float* z, size_t el) {
void Hopenet::softmax(float* z, size_t el) {
double zmax = -INFINITY;
double zsum = 0;
for (size_t i = 0; i < el; i++) if (z[i] > zmax) zmax=z[i];
@@ -110,7 +104,7 @@ void HopeNet::softmax(float* z, size_t el) {
for (size_t i=0; i<el; i++) z[i] = (z[i]/zsum)+NEAR_0;
}
double HopeNet::getAngle(float* prediction, size_t len) {
double Hopenet::getAngle(float* prediction, size_t len) {
double expectation[len];
for (uint i=0; i<len; i++) expectation[i]=idx_tensor[i]*prediction[i];
double angle = std::accumulate(expectation, expectation+len, 0.0) * 3 - 99;

View File

@@ -1,15 +1,14 @@
#ifndef _ROS_NCNN_HOPENET_H_
#define _ROS_NCNN_HOPENET_H_
#ifndef _HEAD_HOPENET_H_
#define _HEAD_HOPENET_H_
#include "../common/common.hpp"
#include "net.h"
namespace ov {
class HopeNet {
class Hopenet : public Estimator {
public:
HopeNet();
~HopeNet();
Hopenet();
~Hopenet();
int LoadModel(const char* root_path);
int Detect(const unsigned char* rgbdata,
int img_width, int img_height,
@@ -23,7 +22,5 @@ private:
double getAngle(float* prediction, size_t len);
};
}
#endif
#endif // !_HEAD_HOPENET_H_

View File

@@ -10,9 +10,7 @@ extern "C" {
typedef void* ILandmarker;
ILandmarker new_insightface();
ILandmarker new_zq();
void destroy_landmarker(ILandmarker m);
int landmarker_load_model(ILandmarker m, const char* root_path);
int extract_keypoints(ILandmarker m, const unsigned char* rgbdata, int img_width, int img_height, const Rect* face, Point2fVector* keypoints);
int extract_face_keypoints(ILandmarker m, const unsigned char* rgbdata, int img_width, int img_height, const Rect* face, Point2fVector* keypoints);
#ifdef __cplusplus
}
#endif

View File

@@ -10,15 +10,7 @@ ILandmarker new_insightface() {
return new ov::InsightfaceLandmarker();
}
void destroy_landmarker(ILandmarker m) {
delete static_cast<ov::Landmarker*>(m);
}
int landmarker_load_model(ILandmarker m, const char *root_path) {
return static_cast<ov::Landmarker*>(m)->LoadModel(root_path);
}
int extract_keypoints(
int extract_face_keypoints(
ILandmarker m,
const unsigned char* rgbdata,
int img_width,

View File

@@ -5,10 +5,9 @@
namespace ov{
// 抽象类
class Landmarker {
class Landmarker: public Estimator {
public:
virtual ~Landmarker() {};
virtual int LoadModel(const char* root_path) = 0;
virtual int ExtractKeypoints(const unsigned char* rgbdata,
int img_width, int img_height,
const Rect& face, std::vector<Point2f>* keypoints) = 0;

View File

@@ -9,8 +9,6 @@ extern "C" {
#endif
typedef void* IRecognizer;
IRecognizer new_mobilefacenet();
void destroy_recognizer(IRecognizer r);
int recognizer_load_model(IRecognizer r, const char* root_path);
int extract_feature(IRecognizer r, const unsigned char* rgbdata, int img_width, int img_height, const Rect* face, FloatVector* feature);
#ifdef __cplusplus
}

View File

@@ -5,14 +5,6 @@ IRecognizer new_mobilefacenet() {
return new ov::Mobilefacenet();
}
void destroy_recognizer(IRecognizer r) {
delete static_cast<ov::Recognizer*>(r);
}
int recognizer_load_model(IRecognizer r, const char* root_path) {
return static_cast<ov::Recognizer*>(r)->LoadModel(root_path);
}
int extract_feature(IRecognizer r, const unsigned char* rgbdata, int img_width, int img_height, const Rect* face, FloatVector* feature) {
std::vector<float>features;
int ret = static_cast<ov::Recognizer*>(r)->ExtractFeature(rgbdata, img_width, img_height, *face, &features);

View File

@@ -5,10 +5,9 @@
#include "../common/common.hpp"
namespace ov {
class Recognizer {
class Recognizer: public Estimator {
public:
virtual ~Recognizer() {};
virtual int LoadModel(const char* root_path) = 0;
virtual int ExtractFeature(const unsigned char* rgbdata,
int img_width, int img_height,
const Rect& face,

View File

@@ -7,33 +7,33 @@
extern "C" {
#endif
#ifdef __cplusplus
typedef ov::Keypoint Keypoint;
typedef ov::ROI ROI;
typedef ov::PoseKeypoint PoseKeypoint;
typedef ov::PoseROI PoseROI;
#else
typedef struct Keypoint {
typedef struct PoseKeypoint {
Point2f p;
float prob;
} Keypoint;
} PoseKeypoint;
typedef struct ROI {
typedef struct PoseROI {
Rect rect;
unsigned char *data;
float score;
} ROI;
} PoseROI;
#endif
typedef struct ROIVector {
ROI* items;
typedef struct PoseROIVector {
PoseROI* items;
int length;
} ROIVector;
} PoseROIVector;
typedef struct KeypointVector {
Keypoint* points;
typedef struct PoseKeypointVector {
PoseKeypoint* points;
int length;
} KeypointVector;
} PoseKeypointVector;
void FreeKeypointVector(KeypointVector *p);
void FreeROIVector(ROIVector *p);
void FreePoseKeypointVector(PoseKeypointVector *p);
void FreePoseROIVector(PoseROIVector *p);
#ifdef __cplusplus
}
#endif

View File

@@ -1,13 +1,13 @@
#include "../common.h"
void FreeKeypointVector(KeypointVector *p) {
void FreePoseKeypointVector(PoseKeypointVector *p) {
if (p->points != NULL) {
free(p->points);
p->points = NULL;
}
}
void FreeROIVector(ROIVector *p) {
void FreePoseROIVector(PoseROIVector *p) {
if (p->items!= NULL) {
free(p->items);
p->items= NULL;

View File

@@ -4,12 +4,12 @@
#include "../../common/common.h"
namespace ov {
struct Keypoint {
struct PoseKeypoint {
Point2f p;
float prob;
};
struct ROI {
struct PoseROI {
Rect rect;
unsigned char *data;
float score;

View File

@@ -9,12 +9,10 @@ extern "C" {
#endif
typedef void* IDetecter;
IDetecter new_ultralight();
void destroy_detecter(IDetecter d);
int detecter_load_model(IDetecter d, const char* root_path);
int extract_rois(IDetecter d, const unsigned char* rgbdata,
int extract_pose_rois(IDetecter d, const unsigned char* rgbdata,
int img_width, int img_height,
ROIVector* rois);
int extract_keypoints(IDetecter d, const ROI* roi,KeypointVector* keypoints);
PoseROIVector* rois);
int extract_pose_keypoints(IDetecter d, const PoseROI* roi, PoseKeypointVector* keypoints);
#ifdef __cplusplus
}
#endif

View File

@@ -1,41 +1,33 @@
#include "../detecter.h"
#include "utralight/utralight.hpp"
#include "ultralight/ultralight.hpp"
IDetecter new_utralight() {
return new ov::Utralight();
IDetecter new_ultralight() {
return new ov::Ultralight();
}
void destroy_detecter(IDetecter d) {
delete static_cast<ov::Detecter*>(d);
}
int detecter_load_model(IDetecter d, const char *root_path){
return static_cast<ov::Detecter*>(d)->LoadModel(root_path);
}
int extract_rois(IDetecter d, const unsigned char* rgbdata, int img_width, int img_height, ROIVector* rois) {
std::vector<ROI> detected;
int extract_pose_rois(IDetecter d, const unsigned char* rgbdata, int img_width, int img_height, PoseROIVector* rois) {
std::vector<PoseROI> detected;
int ret = static_cast<ov::Detecter*>(d)->ExtractROIs(rgbdata, img_width, img_height, &detected);
if (ret != 0) {
return ret;
}
rois->length = detected.size();
rois->items = (ROI*)malloc(rois->length * sizeof(ROI));
rois->items = (PoseROI*)malloc(rois->length * sizeof(PoseROI));
for (size_t i = 0; i < detected.size(); ++i) {
rois->items[i] = detected[i];
}
return 0;
}
int extract_keypoints(IDetecter d, const ROI* roi, KeypointVector* keypoints) {
std::vector<Keypoint> points;
int extract_pose_keypoints(IDetecter d, const PoseROI* roi, PoseKeypointVector* keypoints) {
std::vector<PoseKeypoint> points;
int ret = static_cast<ov::Detecter*>(d)->ExtractKeypoints(*roi, &points);
if (ret != 0) {
return ret;
}
keypoints->length = points.size();
keypoints->points = (Keypoint*)malloc(keypoints->length * sizeof(Keypoint));
keypoints->points = (PoseKeypoint*)malloc(keypoints->length * sizeof(PoseKeypoint));
for (size_t i = 0; i < points.size(); ++i) {
keypoints->points[i] = points[i];
}
@@ -43,7 +35,7 @@ int extract_keypoints(IDetecter d, const ROI* roi, KeypointVector* keypoints) {
}
namespace ov{
Detecter* UtralightFactory::CreateDetecter() {
return new Utralight();
Detecter* UltralightFactory::CreateDetecter() {
return new Ultralight();
}
}

View File

@@ -5,14 +5,13 @@
#include <vector>
namespace ov {
class Detecter {
class Detecter: Estimator {
public:
virtual ~Detecter(){};
virtual int LoadModel(const char* root_path) = 0;
virtual int ExtractROIs(const unsigned char* rgbadata,
int img_width, int img_height,
std::vector<ROI>* rois) = 0;
virtual int ExtractKeypoints(const ROI& roi, std::vector<Keypoint>* keypoints) = 0;
std::vector<PoseROI>* rois) = 0;
virtual int ExtractKeypoints(const PoseROI& roi, std::vector<PoseKeypoint>* keypoints) = 0;
};
class DetecterFactory {
@@ -21,10 +20,10 @@ public:
virtual ~DetecterFactory() {};
};
class UtralightFactory: public DetecterFactory {
class UltralightFactory: public DetecterFactory {
public:
UtralightFactory() {}
~UtralightFactory() {}
UltralightFactory() {}
~UltralightFactory() {}
Detecter* CreateDetecter();
};
}

View File

@@ -1,4 +1,4 @@
#include "utralight.hpp"
#include "ultralight.hpp"
#include <string>
#ifdef OV_VULKAN
@@ -6,7 +6,7 @@
#endif // OV_VULKAN
namespace ov {
Utralight::Utralight() {
Ultralight::Ultralight() {
roi_net_ = new ncnn::Net();
pose_net_ = new ncnn::Net();
initialized_ = false;
@@ -16,12 +16,12 @@ Utralight::Utralight() {
#endif // OV_VULKAN
}
Utralight::~Utralight() {
Ultralight::~Ultralight() {
roi_net_->clear();
pose_net_->clear();
}
int Utralight::LoadModel(const char * root_path) {
int Ultralight::LoadModel(const char * root_path) {
std::string roi_param_file = std::string(root_path) + "/roi.param";
std::string roi_bin_file = std::string(root_path) + "/roi.bin";
if (roi_net_->load_param(roi_param_file.c_str()) == -1 ||
@@ -40,9 +40,9 @@ int Utralight::LoadModel(const char * root_path) {
return 0;
}
int Utralight::ExtractROIs(const unsigned char* rgbdata,
int Ultralight::ExtractROIs(const unsigned char* rgbdata,
int img_width, int img_height,
std::vector<ROI>* rois) {
std::vector<PoseROI>* rois) {
if (!initialized_) {
return 10000;
}
@@ -64,7 +64,6 @@ int Utralight::ExtractROIs(const unsigned char* rgbdata,
for (int i = 0; i < out.h; i++)
{
printf("==================================\n");
float x1, y1, x2, y2, score, label;
float pw,ph,cx,cy;
const float* values = out.row(i);
@@ -108,7 +107,7 @@ int Utralight::ExtractROIs(const unsigned char* rgbdata,
unsigned char* dstCursor = cropdata + i * rect.width * 3;
memcpy(dstCursor, srcCursor, sizeof(unsigned char) * 3 * rect.width);
}
ROI roi;
PoseROI roi;
roi.rect = rect;
roi.data = cropdata;
roi.score = score;
@@ -118,7 +117,7 @@ int Utralight::ExtractROIs(const unsigned char* rgbdata,
return 0;
}
int Utralight::ExtractKeypoints(const ROI& roi, std::vector<Keypoint>* keypoints) {
int Ultralight::ExtractKeypoints(const PoseROI& roi, std::vector<PoseKeypoint>* keypoints) {
keypoints->clear();
int w = roi.rect.width;
int h = roi.rect.height;
@@ -155,7 +154,7 @@ int Utralight::ExtractKeypoints(const ROI& roi, std::vector<Keypoint>* keypoints
}
}
Keypoint keypoint;
PoseKeypoint keypoint;
keypoint.p = Point2f(max_x * w / (float)out.w+roi.rect.x, max_y * h / (float)out.h+roi.rect.y);
keypoint.prob = max_prob;
keypoints->push_back(keypoint);

View File

@@ -1,5 +1,5 @@
#ifndef _POSE_UTRALIGHT_H_
#define _POSE_UTRALIGHT_H_
#ifndef _POSE_ULTRALIGHT_H_
#define _POSE_ULTRALIGHT_H_
#include "../detecter.hpp"
#include <vector>
@@ -7,17 +7,17 @@
namespace ov {
class Utralight : public Detecter {
class Ultralight : public Detecter {
public:
Utralight();
~Utralight();
Ultralight();
~Ultralight();
int LoadModel(const char* root_path);
int ExtractROIs(const unsigned char* rgbadata,
int img_width, int img_height,
std::vector<ROI>* rois);
int ExtractKeypoints(const ROI& roi,
std::vector<Keypoint>* keypoints);
std::vector<PoseROI>* rois);
int ExtractKeypoints(const PoseROI& roi,
std::vector<PoseKeypoint>* keypoints);
private:
ncnn::Net* roi_net_;
@@ -27,5 +27,5 @@ private:
}
#endif // !_POSE_MOBILEFACENET_H_
#endif // !_POSE_ULTRALIGHT_H_

View File

@@ -54,14 +54,6 @@ RealEsrgan new_realesrgan(int gpuid, bool _tta_model) {
return new ov::RealESRGAN(gpuid, _tta_model);
}
void destroy_realesrgan(RealEsrgan r) {
delete static_cast<ov::RealESRGAN*>(r);
}
int realesrgan_load_model(RealEsrgan r, const char* root_path) {
return static_cast<ov::RealESRGAN*>(r)->LoadModel(root_path);
}
int realesrgan_process(RealEsrgan r, const unsigned char* rgbdata, int img_width, int img_height, int scale, Bytes* output) {
size_t total_size = img_width * img_height * scale * scale * 3;
#ifdef OV_VULKAN

View File

@@ -9,8 +9,6 @@ extern "C" {
#endif
typedef void* RealEsrgan;
RealEsrgan new_realesrgan(int gpuid, bool _ttad_model);
void destroy_realesrgan(RealEsrgan r);
int realesrgan_load_model(RealEsrgan r, const char* root_path);
int realesrgan_process(RealEsrgan r, const unsigned char* rgbdata, int img_width, int img_height, int scale, Bytes* output);
#ifdef __cplusplus
}

View File

@@ -1,6 +1,7 @@
#ifndef _REALESRGAN_H
#define _REALESRGAN_H
#include "../common/common.hpp"
// ncnn
#include "net.h"
#include "layer.h"
@@ -10,14 +11,11 @@
namespace ov {
class RealESRGAN
{
class RealESRGAN: public Estimator {
public:
RealESRGAN(int gpuid, bool tta_mode = false);
~RealESRGAN();
int LoadModel(const char* root_path);
int LoadModel(const char* root_path);
int process(const ncnn::Mat& inimage, ncnn::Mat& outimage) const;
public: