From 51d771fb2e66ba310c7d873aa1224314046f4b83 Mon Sep 17 00:00:00 2001 From: wusj Date: Fri, 27 Oct 2023 15:30:12 +0800 Subject: [PATCH] facemark support --- .gitignore | 1 + contrib/facemarkLBF.cpp | 23 +++++++++++++++ contrib/facemarkLBF.go | 57 +++++++++++++++++++++++++++++++++++++ contrib/facemarkLBF.h | 32 +++++++++++++++++++++ contrib/facemarkLBF_test.go | 21 ++++++++++++++ 5 files changed, 134 insertions(+) create mode 100644 contrib/facemarkLBF.cpp create mode 100644 contrib/facemarkLBF.go create mode 100644 contrib/facemarkLBF.h create mode 100644 contrib/facemarkLBF_test.go diff --git a/.gitignore b/.gitignore index adf29f1c..cf94e5be 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ count.out .idea/ contrib/data.yaml contrib/testOilPainting.png +lbfmodel.yaml \ No newline at end of file diff --git a/contrib/facemarkLBF.cpp b/contrib/facemarkLBF.cpp new file mode 100644 index 00000000..9ab4305b --- /dev/null +++ b/contrib/facemarkLBF.cpp @@ -0,0 +1,23 @@ +#include "facemarkLBF.h" + +LBPHFaceMark CreateLBPHFaceMark() { + return new cv::Ptr(cv::face::FacemarkLBF::create()); +} + +void LBPHFaceMark_LoadModel(LBPHFaceMark fm, const char* model) { + (*fm)->loadModel(model); +} + +bool LBPHFaceMark_Fit(LBPHFaceMark fm, Mat frame, struct Rects faces, Points2fVector landmarks) { + std::vector _faces; + + for (int i = 0; i < faces.length; ++i) { + _faces.push_back(cv::Rect( + faces.rects[i].x, + faces.rects[i].y, + faces.rects[i].width, + faces.rects[i].height + )); + } + return (*fm)->fit(*frame, _faces, *landmarks); +} \ No newline at end of file diff --git a/contrib/facemarkLBF.go b/contrib/facemarkLBF.go new file mode 100644 index 00000000..4c944253 --- /dev/null +++ b/contrib/facemarkLBF.go @@ -0,0 +1,57 @@ +package contrib + +/* +#include +#include "facemarkLBF.h" +#include "../core.h" +*/ +import "C" +import ( + "gocv.io/x/gocv" + "image" + "unsafe" +) + +type LBPHFaceMark struct { + p C.LBPHFaceMark +} + +func NewLBPHFaceMark() *LBPHFaceMark { + return &LBPHFaceMark{p: C.CreateLBPHFaceMark()} +} + +func (mark *LBPHFaceMark) LoadModel(model string) { + cName := C.CString(model) + defer C.free(unsafe.Pointer(cName)) + C.LBPHFaceMark_LoadModel(mark.p, cName) +} + +// LBPHFaceMark_Fit(LBPHFaceMark fm, Mat frame, struct Rects faces, Points2fVector landmarks) +func (mark *LBPHFaceMark) Fit(img gocv.Mat, faceBox []image.Rectangle) (bool, [][]gocv.Point2f) { + + bboxesRectArr := []C.struct_Rect{} + for _, v := range faceBox { + bbox := C.struct_Rect{ + x: C.int(v.Min.X), + y: C.int(v.Min.Y), + width: C.int(v.Size().X), + height: C.int(v.Size().Y), + } + bboxesRectArr = append(bboxesRectArr, bbox) + } + + bboxesRects := C.Rects{ + rects: (*C.Rect)(&bboxesRectArr[0]), + length: C.int(len(faceBox)), + } + + points2fVector := gocv.NewPoints2fVector() + result := bool(C.LBPHFaceMark_Fit( + mark.p, + C.Mat(img.Ptr()), + bboxesRects, + C.Points2fVector(points2fVector.P()), + )) + + return result, points2fVector.ToPoints() +} diff --git a/contrib/facemarkLBF.h b/contrib/facemarkLBF.h new file mode 100644 index 00000000..23196421 --- /dev/null +++ b/contrib/facemarkLBF.h @@ -0,0 +1,32 @@ +#ifndef _OPENCV3_FACE_H_ +#define _OPENCV3_FACE_H_ + +#ifdef __cplusplus +#include +#include + +extern "C" { +#endif + +#include "../core.h" + +#ifdef __cplusplus +typedef cv::Ptr* LBPHFaceMark; +#else +typedef void* LBPHFaceMark; +#endif + +struct PredictResponse { + int label; + double confidence; +}; + +LBPHFaceMark CreateLBPHFaceMark(); +void LBPHFaceMark_LoadModel(LBPHFaceMark fm, const char* model); //Points2fVector +bool LBPHFaceMark_Fit(LBPHFaceMark fm, Mat frame, struct Rects faces, Points2fVector landmarks); + +#ifdef __cplusplus +} +#endif + +#endif //_OPENCV3_FACE_H_ \ No newline at end of file diff --git a/contrib/facemarkLBF_test.go b/contrib/facemarkLBF_test.go new file mode 100644 index 00000000..1aab4dcf --- /dev/null +++ b/contrib/facemarkLBF_test.go @@ -0,0 +1,21 @@ +package contrib + +import ( + "log" + "testing" +) + +func TestNewLBPHFaceMark(t *testing.T) { + mark := NewLBPHFaceMark() + log.Println(mark) +} + +func TestLBPHFaceMark_LoadModel(t *testing.T) { + mark := NewLBPHFaceMark() + log.Println(mark) + mark.LoadModel("/Users/wushaojie/Documents/project/golang/go-opencv/lbfmodel.yaml") + log.Println("success") +} + +func TestLBPHFaceMark_Fit(t *testing.T) { +}