Skip to content

Commit

Permalink
added face recognizer interface (#1211)
Browse files Browse the repository at this point in the history
contrib/face: added face recognizer interface. refactored LBPHFaceRecognizer
  • Loading branch information
diegohce authored Sep 1, 2024
1 parent 96d84eb commit 8fe0d8b
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 90 deletions.
52 changes: 24 additions & 28 deletions contrib/face.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include "face.h"

LBPHFaceRecognizer CreateLBPHFaceRecognizer() {
return new cv::Ptr<cv::face::LBPHFaceRecognizer>(cv::face::LBPHFaceRecognizer::create());
bool FaceRecognizer_Empty(FaceRecognizer fr) {
return (*fr)->empty();
}

void LBPHFaceRecognizer_Train(LBPHFaceRecognizer fr, Mats mats, IntVector labels_in) {
void FaceRecognizer_Train(FaceRecognizer fr, Mats mats, IntVector labels_in) {
std::vector<int> labels;

for (int i = 0, *v = labels_in.val; i < labels_in.length; ++v, ++i) {
Expand All @@ -22,7 +22,7 @@ void LBPHFaceRecognizer_Train(LBPHFaceRecognizer fr, Mats mats, IntVector labels
return;
}

void LBPHFaceRecognizer_Update(LBPHFaceRecognizer fr, Mats mats, IntVector labels_in) {
void FaceRecognizer_Update(FaceRecognizer fr, Mats mats, IntVector labels_in) {
std::vector<int> labels;

for (int i = 0, *v = labels_in.val; i < labels_in.length; ++v, ++i) {
Expand All @@ -40,14 +40,14 @@ void LBPHFaceRecognizer_Update(LBPHFaceRecognizer fr, Mats mats, IntVector label
return;
}

int LBPHFaceRecognizer_Predict(LBPHFaceRecognizer fr, Mat sample) {
int FaceRecognizer_Predict(FaceRecognizer fr, Mat sample) {
int label;
label = (*fr)->predict(*sample);

return label;
}

struct PredictResponse LBPHFaceRecognizer_PredictExtended(LBPHFaceRecognizer fr, Mat sample) {
struct PredictResponse FaceRecognizer_PredictExtended(FaceRecognizer fr, Mat sample) {
struct PredictResponse response;
int label;
double confidence;
Expand All @@ -56,68 +56,61 @@ struct PredictResponse LBPHFaceRecognizer_PredictExtended(LBPHFaceRecognizer fr,
response.label = label;
response.confidence = confidence;


return response;
}

double LBPHFaceRecognizer_GetThreshold(LBPHFaceRecognizer fr){
double FaceRecognizer_GetThreshold(FaceRecognizer fr){
return (*fr)->getThreshold();
}

void LBPHFaceRecognizer_SetThreshold(LBPHFaceRecognizer fr, double threshold) {
void FaceRecognizer_SetThreshold(FaceRecognizer fr, double threshold) {
(*fr)->setThreshold(threshold);
return;
}

void FaceRecognizer_SaveFile(FaceRecognizer fr, const char* filename) {
(*fr)->write(filename);
return;
}

void FaceRecognizer_LoadFile(FaceRecognizer fr, const char* filename) {
(*fr)->read(filename);
return;
}

LBPHFaceRecognizer CreateLBPHFaceRecognizer() {
return new cv::Ptr<cv::face::LBPHFaceRecognizer>(cv::face::LBPHFaceRecognizer::create());
}

void LBPHFaceRecognizer_SetRadius(LBPHFaceRecognizer fr, int radius) {
(*fr)->setRadius(radius);

return;
}

void LBPHFaceRecognizer_SetNeighbors(LBPHFaceRecognizer fr, int neighbors) {
(*fr)->setNeighbors(neighbors);

return;
}


int LBPHFaceRecognizer_GetNeighbors(LBPHFaceRecognizer fr) {
int n;

n = (*fr)->getNeighbors();

return n;
}

void LBPHFaceRecognizer_SaveFile(LBPHFaceRecognizer fr, const char* filename) {
(*fr)->write(filename);

return;
}

void LBPHFaceRecognizer_LoadFile(LBPHFaceRecognizer fr, const char* filename) {
(*fr)->read(filename);

return;
}

void LBPHFaceRecognizer_SetGridX(LBPHFaceRecognizer fr, int x) {
(*fr)->setGridX(x);

return;
}

void LBPHFaceRecognizer_SetGridY(LBPHFaceRecognizer fr, int y) {
(*fr)->setGridY(y);

return;
}

int LBPHFaceRecognizer_GetGridX(LBPHFaceRecognizer fr) {
int n = (*fr)->getGridX();

return n;
}

Expand All @@ -126,3 +119,6 @@ int LBPHFaceRecognizer_GetGridY(LBPHFaceRecognizer fr) {
return n;
}

void LBPHFaceRecognizer_Close(LBPHFaceRecognizer fr) {
delete fr;
}
78 changes: 24 additions & 54 deletions contrib/face.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package contrib
import "C"
import (
"image"
"unsafe"

"gocv.io/x/gocv"
)
Expand All @@ -18,12 +17,18 @@ type PredictResponse struct {
Confidence float32 `json:"confidence"`
}

var _ FaceRecognizer = (*LBPHFaceRecognizer)(nil)

// LBPHFaceRecognizer is a wrapper for the OpenCV Local Binary Patterns
// Histograms face recognizer.
type LBPHFaceRecognizer struct {
p C.LBPHFaceRecognizer
}

func (fr *LBPHFaceRecognizer) Empty() bool {
return faceRecognizer_Empty(C.FaceRecognizer(fr.p))
}

// NewLBPHFaceRecognizer creates a new LBPH Recognizer model.
//
// For further information, see:
Expand All @@ -36,49 +41,15 @@ func NewLBPHFaceRecognizer() *LBPHFaceRecognizer {
//
// see https://docs.opencv.org/master/dd/d65/classcv_1_1face_1_1FaceRecognizer.html#ac8680c2aa9649ad3f55e27761165c0d6
func (fr *LBPHFaceRecognizer) Train(images []gocv.Mat, labels []int) {
cparams := []C.int{}
for _, v := range labels {
cparams = append(cparams, C.int(v))
}
labelsVector := C.struct_IntVector{}
labelsVector.val = (*C.int)(&cparams[0])
labelsVector.length = (C.int)(len(cparams))

cMatArray := make([]C.Mat, len(images))
for i, r := range images {
cMatArray[i] = (C.Mat)(r.Ptr())
}
matsVector := C.struct_Mats{
mats: (*C.Mat)(&cMatArray[0]),
length: C.int(len(images)),
}

C.LBPHFaceRecognizer_Train(fr.p, matsVector, labelsVector)
faceRecognizer_Train(C.FaceRecognizer(fr.p), images, labels)
}

// Update updates the existing trained model with new images and labels.
//
// For further information, see:
// https://docs.opencv.org/master/dd/d65/classcv_1_1face_1_1FaceRecognizer.html#a8a4e73ea878dcd0c235d0487189d25f3
func (fr *LBPHFaceRecognizer) Update(newImages []gocv.Mat, newLabels []int) {
cparams := []C.int{}
for _, v := range newLabels {
cparams = append(cparams, C.int(v))
}
labelsVector := C.struct_IntVector{}
labelsVector.val = (*C.int)(&cparams[0])
labelsVector.length = (C.int)(len(cparams))

cMatArray := make([]C.Mat, len(newImages))
for i, r := range newImages {
cMatArray[i] = (C.Mat)(r.Ptr())
}
matsVector := C.struct_Mats{
mats: (*C.Mat)(&cMatArray[0]),
length: C.int(len(newImages)),
}

C.LBPHFaceRecognizer_Update(fr.p, matsVector, labelsVector)
faceRecognizer_Update(C.FaceRecognizer(fr.p), newImages, newLabels)
}

// Predict predicts a label for a given input image. It returns the label for
Expand All @@ -87,7 +58,7 @@ func (fr *LBPHFaceRecognizer) Update(newImages []gocv.Mat, newLabels []int) {
// For further information, see:
// https://docs.opencv.org/master/dd/d65/classcv_1_1face_1_1FaceRecognizer.html#aa2d2f02faffab1bf01317ae6502fb631
func (fr *LBPHFaceRecognizer) Predict(sample gocv.Mat) int {
label := C.LBPHFaceRecognizer_Predict(fr.p, (C.Mat)(sample.Ptr()))
label := faceRecognizer_Predict(C.FaceRecognizer(fr.p), sample)

return int(label)
}
Expand All @@ -99,11 +70,7 @@ func (fr *LBPHFaceRecognizer) Predict(sample gocv.Mat) int {
// For further information, see:
// https://docs.opencv.org/master/dd/d65/classcv_1_1face_1_1FaceRecognizer.html#ab0d593e53ebd9a0f350c989fcac7f251
func (fr *LBPHFaceRecognizer) PredictExtendedResponse(sample gocv.Mat) PredictResponse {
respp := C.LBPHFaceRecognizer_PredictExtended(fr.p, (C.Mat)(sample.Ptr()))
resp := PredictResponse{
Label: int32(respp.label),
Confidence: float32(respp.confidence),
}
resp := faceRecognizer_PredictExtendedResponse(C.FaceRecognizer(fr.p), sample)

return resp
}
Expand All @@ -114,7 +81,7 @@ func (fr *LBPHFaceRecognizer) PredictExtendedResponse(sample gocv.Mat) PredictRe
// For further information, see:
// https://docs.opencv.org/4.x/df/d25/classcv_1_1face_1_1LBPHFaceRecognizer.html#acf2a6993eb4347b3f89009da693a3f70
func (fr *LBPHFaceRecognizer) GetThreshold() float32 {
t := C.LBPHFaceRecognizer_GetThreshold(fr.p)
t := faceRecognizer_GetThreshold(C.FaceRecognizer(fr.p))
return float32(t)
}

Expand All @@ -124,7 +91,7 @@ func (fr *LBPHFaceRecognizer) GetThreshold() float32 {
// For further information, see:
// https://docs.opencv.org/master/dd/d65/classcv_1_1face_1_1FaceRecognizer.html#a3182081e5f8023e658ad8ab96656dd63
func (fr *LBPHFaceRecognizer) SetThreshold(threshold float32) {
C.LBPHFaceRecognizer_SetThreshold(fr.p, (C.double)(threshold))
faceRecognizer_SetThreshold(C.FaceRecognizer(fr.p), threshold)
}

// SetNeighbors sets the neighbors value of the model, i.e. the number of
Expand All @@ -134,14 +101,15 @@ func (fr *LBPHFaceRecognizer) SetThreshold(threshold float32) {
// For further information, see:
// https://docs.opencv.org/master/df/d25/classcv_1_1face_1_1LBPHFaceRecognizer.html#ab225f7bf353ce8697a506eda10124a92
func (fr *LBPHFaceRecognizer) SetNeighbors(neighbors int) {
C.LBPHFaceRecognizer_SetNeighbors(fr.p, (C.int)(neighbors))
C.LBPHFaceRecognizer_SetNeighbors(fr.p, C.int(neighbors))
}

// GetNeighbors returns the neighbors value of the model.
//
// For further information, see:
// https://docs.opencv.org/master/df/d25/classcv_1_1face_1_1LBPHFaceRecognizer.html#a50a3e2ca6e8464166e153c9df84b0a77
func (fr *LBPHFaceRecognizer) GetNeighbors() int {

n := C.LBPHFaceRecognizer_GetNeighbors(fr.p)

return int(n)
Expand All @@ -153,27 +121,23 @@ func (fr *LBPHFaceRecognizer) GetNeighbors() int {
// For further information, see:
// https://docs.opencv.org/master/df/d25/classcv_1_1face_1_1LBPHFaceRecognizer.html#a62d94c75cade902fd3b487b1ef9883fc
func (fr *LBPHFaceRecognizer) SetRadius(radius int) {
C.LBPHFaceRecognizer_SetRadius(fr.p, (C.int)(radius))
C.LBPHFaceRecognizer_SetRadius(fr.p, C.int(radius))
}

// SaveFile saves the trained model data to file.
//
// For further information, see:
// https://docs.opencv.org/master/dd/d65/classcv_1_1face_1_1FaceRecognizer.html#a2adf2d555550194244b05c91fefcb4d6
func (fr *LBPHFaceRecognizer) SaveFile(fname string) {
cName := C.CString(fname)
defer C.free(unsafe.Pointer(cName))
C.LBPHFaceRecognizer_SaveFile(fr.p, cName)
faceRecognizer_SaveFile(C.FaceRecognizer(fr.p), fname)
}

// LoadFile loads a trained model data from file.
//
// For further information, see:
// https://docs.opencv.org/master/dd/d65/classcv_1_1face_1_1FaceRecognizer.html#acc42e5b04595dba71f0777c7179af8c3
func (fr *LBPHFaceRecognizer) LoadFile(fname string) {
cName := C.CString(fname)
defer C.free(unsafe.Pointer(cName))
C.LBPHFaceRecognizer_LoadFile(fr.p, cName)
faceRecognizer_LoadFile(C.FaceRecognizer(fr.p), fname)
}

// SetGridX sets grid's X value
Expand Down Expand Up @@ -218,5 +182,11 @@ func (fr *LBPHFaceRecognizer) SetGrid(p image.Point) {

// GetGrid helper for GetGrid* functions
func (fr *LBPHFaceRecognizer) GetGrid() image.Point {
return image.Point{X: fr.GetGridX(), Y: fr.GetGridY()}
return image.Pt(fr.GetGridX(), fr.GetGridY())
}

func (fr *LBPHFaceRecognizer) Close() error {
C.LBPHFaceRecognizer_Close(fr.p)
fr.p = nil
return nil
}
24 changes: 16 additions & 8 deletions contrib/face.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,39 @@ extern "C" {

#ifdef __cplusplus
typedef cv::Ptr<cv::face::LBPHFaceRecognizer>* LBPHFaceRecognizer;
typedef cv::Ptr<cv::face::FaceRecognizer>* FaceRecognizer;
#else
typedef void* LBPHFaceRecognizer;
typedef void* FaceRecognizer;
#endif

struct PredictResponse {
int label;
double confidence;
};

bool FaceRecognizer_Empty(FaceRecognizer fr);
void FaceRecognizer_Train(FaceRecognizer fr, Mats images, IntVector labels);
void FaceRecognizer_Update(FaceRecognizer fr, Mats images, IntVector labels);
int FaceRecognizer_Predict(FaceRecognizer fr, Mat sample);
struct PredictResponse FaceRecognizer_PredictExtended(FaceRecognizer fr, Mat sample);
double FaceRecognizer_GetThreshold(FaceRecognizer fr);
void FaceRecognizer_SetThreshold(FaceRecognizer fr, double threshold);
void FaceRecognizer_SaveFile(FaceRecognizer fr, const char* filename);
void FaceRecognizer_LoadFile(FaceRecognizer fr, const char* filename);



LBPHFaceRecognizer CreateLBPHFaceRecognizer();
void LBPHFaceRecognizer_Train(LBPHFaceRecognizer fr, Mats images, IntVector labels);
void LBPHFaceRecognizer_Update(LBPHFaceRecognizer fr, Mats images, IntVector labels);
int LBPHFaceRecognizer_Predict(LBPHFaceRecognizer fr, Mat sample);
struct PredictResponse LBPHFaceRecognizer_PredictExtended(LBPHFaceRecognizer fr, Mat sample);
double LBPHFaceRecognizer_GetThreshold(LBPHFaceRecognizer fr);
void LBPHFaceRecognizer_SetThreshold(LBPHFaceRecognizer fr, double threshold);
void LBPHFaceRecognizer_SetRadius(LBPHFaceRecognizer fr, int radius);
void LBPHFaceRecognizer_SetNeighbors(LBPHFaceRecognizer fr, int neighbors);
void LBPHFaceRecognizer_SaveFile(LBPHFaceRecognizer fr, const char* filename);
void LBPHFaceRecognizer_LoadFile(LBPHFaceRecognizer fr, const char* filename);
int LBPHFaceRecognizer_GetNeighbors(LBPHFaceRecognizer fr);
void LBPHFaceRecognizer_SetGridX(LBPHFaceRecognizer fr, int x);
void LBPHFaceRecognizer_SetGridY(LBPHFaceRecognizer fr, int y);
int LBPHFaceRecognizer_GetGridX(LBPHFaceRecognizer fr);
int LBPHFaceRecognizer_GetGridY(LBPHFaceRecognizer fr);
void LBPHFaceRecognizer_Close(LBPHFaceRecognizer fr);




Expand Down
Loading

0 comments on commit 8fe0d8b

Please sign in to comment.