diff --git a/contrib/face.cpp b/contrib/face.cpp index 7d8f458d..890c40c0 100644 --- a/contrib/face.cpp +++ b/contrib/face.cpp @@ -78,6 +78,88 @@ void FaceRecognizer_LoadFile(FaceRecognizer fr, const char* filename) { return; } +void BasicFaceRecognizer_Train(BasicFaceRecognizer fr, Mats mats, IntVector labels_in){ + std::vector labels; + + for (int i = 0, *v = labels_in.val; i < labels_in.length; ++v, ++i) { + labels.push_back(*v); + } + + std::vector images; + + for (int i = 0; i < mats.length; ++i) { + images.push_back(*mats.mats[i]); + } + + (*fr)->train(images, labels); + + return; +} + +void BasicFaceRecognizer_Update(BasicFaceRecognizer fr, Mats mats, IntVector labels_in){ + std::vector labels; + + for (int i = 0, *v = labels_in.val; i < labels_in.length; ++v, ++i) { + labels.push_back(*v); + } + + std::vector images; + + for (int i = 0; i < mats.length; ++i) { + images.push_back(*mats.mats[i]); + } + (*fr)->update(images, labels); +} + +Mat BasicFaceRecognizer_getEigenValues(BasicFaceRecognizer fr){ + return new cv::Mat((*fr)->getEigenValues()); +} + +Mat BasicFaceRecognizer_getEigenVectors(BasicFaceRecognizer fr){ + return new cv::Mat((*fr)->getEigenVectors()); +} + +Mat BasicFaceRecognizer_getLabels(BasicFaceRecognizer fr){ + return new cv::Mat((*fr)->getLabels()); +} + +Mat BasicFaceRecognizer_getMean(BasicFaceRecognizer fr){ + return new cv::Mat((*fr)->getMean()); +} + +int BasicFaceRecognizer_getNumComponents(BasicFaceRecognizer fr) { + return (*fr)->getNumComponents(); +} + +Mats BasicFaceRecognizer_getProjections(BasicFaceRecognizer fr) { + Mats mats; + + std::vector vec = (*fr)->getProjections(); + + mats.length = (int)vec.size(); + mats.mats = new Mat[vec.size()]; + + for(size_t i = 0; i < vec.size(); i++) { + mats.mats[i] = new cv::Mat(vec[i]); + } + return mats; +} + +void BasicFaceRecognizer_setNumComponents(BasicFaceRecognizer fr, int val){ + (*fr)->setNumComponents(val); +} + +void BasicFaceRecognizer_SaveFile(BasicFaceRecognizer fr, const char* filename){ + (*fr)->write(filename); +} + +void BasicFaceRecognizer_LoadFile(BasicFaceRecognizer fr, const char* filename){ + (*fr)->read(filename); +} + + + + LBPHFaceRecognizer CreateLBPHFaceRecognizer() { return new cv::Ptr(cv::face::LBPHFaceRecognizer::create()); } @@ -121,4 +203,30 @@ int LBPHFaceRecognizer_GetGridY(LBPHFaceRecognizer fr) { void LBPHFaceRecognizer_Close(LBPHFaceRecognizer fr) { delete fr; +} + + +FisherFaceRecognizer FisherFaceRecognizer_Create(void) { + return new cv::Ptr(cv::face::FisherFaceRecognizer::create()); +} + +FisherFaceRecognizer FisherFaceRecognizer_CreateWithParams(int num_components, float threshold) { + return new cv::Ptr(cv::face::FisherFaceRecognizer::create(num_components, threshold)); +} + +void FisherFaceRecognizer_Close(FisherFaceRecognizer fr) { + delete fr; +} + + +EigenFaceRecognizer EigenFaceRecognizer_Create(void) { + return new cv::Ptr(cv::face::EigenFaceRecognizer::create()); +} + +EigenFaceRecognizer EigenFaceRecognizer_CreateWithParams(int num_components, float threshold) { + return new cv::Ptr(cv::face::EigenFaceRecognizer::create(num_components, threshold)); +} + +void EigenFaceRecognizer_Close(EigenFaceRecognizer fr) { + delete fr; } \ No newline at end of file diff --git a/contrib/face.go b/contrib/face.go index 925cf40c..620e4ced 100644 --- a/contrib/face.go +++ b/contrib/face.go @@ -18,6 +18,10 @@ type PredictResponse struct { } var _ FaceRecognizer = (*LBPHFaceRecognizer)(nil) +var _ FaceRecognizer = (*FisherFaceRecognizer)(nil) +var _ BasicFaceRecognizer = (*FisherFaceRecognizer)(nil) +var _ FaceRecognizer = (*EigenFaceRecognizer)(nil) +var _ BasicFaceRecognizer = (*EigenFaceRecognizer)(nil) // LBPHFaceRecognizer is a wrapper for the OpenCV Local Binary Patterns // Histograms face recognizer. @@ -190,3 +194,169 @@ func (fr *LBPHFaceRecognizer) Close() error { fr.p = nil return nil } + +type FisherFaceRecognizer struct { + p C.FisherFaceRecognizer +} + +func NewFisherFaceRecognizer() *FisherFaceRecognizer { + return &FisherFaceRecognizer{p: C.FisherFaceRecognizer_Create()} +} + +func NewFisherFaceRecognizerWithParams(numComponents int, threshold float32) *FisherFaceRecognizer { + return &FisherFaceRecognizer{p: C.FisherFaceRecognizer_CreateWithParams(C.int(numComponents), C.float(threshold))} +} + +func (fr *FisherFaceRecognizer) Empty() bool { + b := faceRecognizer_Empty(C.FaceRecognizer(fr.p)) + return bool(b) +} + +func (fr *FisherFaceRecognizer) GetEigenValues() gocv.Mat { + return basicFaceRecognizer_GetEigenValues(C.BasicFaceRecognizer(fr.p)) +} + +func (fr *FisherFaceRecognizer) GetEigenVectors() gocv.Mat { + return basicFaceRecognizer_GetEigenVectors(C.BasicFaceRecognizer(fr.p)) +} + +func (fr *FisherFaceRecognizer) GetLabels() gocv.Mat { + return basicFaceRecognizer_GetLabels(C.BasicFaceRecognizer(fr.p)) +} + +func (fr *FisherFaceRecognizer) GetMean() gocv.Mat { + return basicFaceRecognizer_GetMean(C.BasicFaceRecognizer(fr.p)) +} + +func (fr *FisherFaceRecognizer) GetNumComponents() int { + return basicFaceRecognizer_GetNumComponents(C.BasicFaceRecognizer(fr.p)) +} + +func (fr *FisherFaceRecognizer) SetNumComponents(val int) { + basicFaceRecognizer_SetNumComponents(C.BasicFaceRecognizer(fr.p), val) +} + +func (fr *FisherFaceRecognizer) GetProjections() []gocv.Mat { + return basicFaceRecognizer_GetProjections(C.BasicFaceRecognizer(fr.p)) +} + +func (fr *FisherFaceRecognizer) GetThreshold() float32 { + return faceRecognizer_GetThreshold(C.FaceRecognizer(fr.p)) +} + +func (fr *FisherFaceRecognizer) SetThreshold(threshold float32) { + faceRecognizer_SetThreshold(C.FaceRecognizer(fr.p), threshold) +} + +func (fr *FisherFaceRecognizer) LoadFile(filename string) { + basicFaceRecognizer_LoadFile(C.BasicFaceRecognizer(fr.p), filename) +} + +func (fr *FisherFaceRecognizer) SaveFile(filename string) { + basicFaceRecognizer_SaveFile(C.BasicFaceRecognizer(fr.p), filename) +} + +func (fr *FisherFaceRecognizer) Predict(sample gocv.Mat) int { + return faceRecognizer_Predict(C.FaceRecognizer(fr.p), sample) +} + +func (fr *FisherFaceRecognizer) PredictExtendedResponse(sample gocv.Mat) PredictResponse { + return faceRecognizer_PredictExtendedResponse(C.FaceRecognizer(fr.p), sample) +} + +func (fr *FisherFaceRecognizer) Train(images []gocv.Mat, labels []int) { + basicFaceRecognizer_Train(C.BasicFaceRecognizer(fr.p), images, labels) +} +func (fr *FisherFaceRecognizer) Update(newImages []gocv.Mat, newLabels []int) { + faceRecognizer_Train(C.FaceRecognizer(fr.p), newImages, newLabels) + +} + +func (fr *FisherFaceRecognizer) Close() error { + C.FisherFaceRecognizer_Close(fr.p) + fr.p = nil + return nil +} + +type EigenFaceRecognizer struct { + p C.EigenFaceRecognizer +} + +func NewEigenFaceRecognizer() *EigenFaceRecognizer { + return &EigenFaceRecognizer{p: C.EigenFaceRecognizer_Create()} +} + +func NewEigenFaceRecognizerWithParams(numComponents int, threshold float32) *EigenFaceRecognizer { + return &EigenFaceRecognizer{p: C.EigenFaceRecognizer_CreateWithParams(C.int(numComponents), C.float(threshold))} +} + +func (fr *EigenFaceRecognizer) Empty() bool { + b := faceRecognizer_Empty(C.FaceRecognizer(fr.p)) + return bool(b) +} + +func (fr *EigenFaceRecognizer) GetEigenValues() gocv.Mat { + return basicFaceRecognizer_GetEigenValues(C.BasicFaceRecognizer(fr.p)) +} + +func (fr *EigenFaceRecognizer) GetEigenVectors() gocv.Mat { + return basicFaceRecognizer_GetEigenVectors(C.BasicFaceRecognizer(fr.p)) +} + +func (fr *EigenFaceRecognizer) GetLabels() gocv.Mat { + return basicFaceRecognizer_GetLabels(C.BasicFaceRecognizer(fr.p)) +} + +func (fr *EigenFaceRecognizer) GetMean() gocv.Mat { + return basicFaceRecognizer_GetMean(C.BasicFaceRecognizer(fr.p)) +} + +func (fr *EigenFaceRecognizer) GetNumComponents() int { + return basicFaceRecognizer_GetNumComponents(C.BasicFaceRecognizer(fr.p)) +} + +func (fr *EigenFaceRecognizer) SetNumComponents(val int) { + basicFaceRecognizer_SetNumComponents(C.BasicFaceRecognizer(fr.p), val) +} + +func (fr *EigenFaceRecognizer) GetProjections() []gocv.Mat { + return basicFaceRecognizer_GetProjections(C.BasicFaceRecognizer(fr.p)) +} + +func (fr *EigenFaceRecognizer) GetThreshold() float32 { + return faceRecognizer_GetThreshold(C.FaceRecognizer(fr.p)) +} + +func (fr *EigenFaceRecognizer) SetThreshold(threshold float32) { + faceRecognizer_SetThreshold(C.FaceRecognizer(fr.p), threshold) +} + +func (fr *EigenFaceRecognizer) LoadFile(filename string) { + basicFaceRecognizer_LoadFile(C.BasicFaceRecognizer(fr.p), filename) +} + +func (fr *EigenFaceRecognizer) SaveFile(filename string) { + basicFaceRecognizer_SaveFile(C.BasicFaceRecognizer(fr.p), filename) +} + +func (fr *EigenFaceRecognizer) Predict(sample gocv.Mat) int { + return faceRecognizer_Predict(C.FaceRecognizer(fr.p), sample) +} + +func (fr *EigenFaceRecognizer) PredictExtendedResponse(sample gocv.Mat) PredictResponse { + return faceRecognizer_PredictExtendedResponse(C.FaceRecognizer(fr.p), sample) +} + +func (fr *EigenFaceRecognizer) Train(images []gocv.Mat, labels []int) { + basicFaceRecognizer_Train(C.BasicFaceRecognizer(fr.p), images, labels) +} + +func (fr *EigenFaceRecognizer) Update(newImages []gocv.Mat, newLabels []int) { + basicFaceRecognizer_Train(C.BasicFaceRecognizer(fr.p), newImages, newLabels) +} + +func (fr *EigenFaceRecognizer) Close() error { + C.EigenFaceRecognizer_Close(fr.p) + fr.p = nil + return nil +} diff --git a/contrib/face.h b/contrib/face.h index 96fa6e2c..c1daf3a5 100644 --- a/contrib/face.h +++ b/contrib/face.h @@ -11,11 +11,17 @@ extern "C" { #include "../core.h" #ifdef __cplusplus -typedef cv::Ptr* LBPHFaceRecognizer; typedef cv::Ptr* FaceRecognizer; +typedef cv::Ptr* BasicFaceRecognizer; +typedef cv::Ptr* LBPHFaceRecognizer; +typedef cv::Ptr* EigenFaceRecognizer; +typedef cv::Ptr* FisherFaceRecognizer; #else -typedef void* LBPHFaceRecognizer; typedef void* FaceRecognizer; +typedef void* BasicFaceRecognizer; +typedef void* LBPHFaceRecognizer; +typedef void* EigenFaceRecognizer; +typedef void* FisherFaceRecognizer; #endif struct PredictResponse { @@ -34,8 +40,19 @@ void FaceRecognizer_SaveFile(FaceRecognizer fr, const char* filename); void FaceRecognizer_LoadFile(FaceRecognizer fr, const char* filename); +void BasicFaceRecognizer_Train(BasicFaceRecognizer fr, Mats images, IntVector labels); +void BasicFaceRecognizer_Update(BasicFaceRecognizer fr, Mats images, IntVector labels); +Mat BasicFaceRecognizer_getEigenValues(BasicFaceRecognizer fr); +Mat BasicFaceRecognizer_getEigenVectors(BasicFaceRecognizer fr); +Mat BasicFaceRecognizer_getLabels(BasicFaceRecognizer fr); +Mat BasicFaceRecognizer_getMean(BasicFaceRecognizer fr); +int BasicFaceRecognizer_getNumComponents(BasicFaceRecognizer fr); +Mats BasicFaceRecognizer_getProjections(BasicFaceRecognizer fr); +void BasicFaceRecognizer_setNumComponents(BasicFaceRecognizer fr, int val); +void BasicFaceRecognizer_SaveFile(BasicFaceRecognizer fr, const char* filename); +void BasicFaceRecognizer_LoadFile(BasicFaceRecognizer fr, const char* filename); -LBPHFaceRecognizer CreateLBPHFaceRecognizer(); +LBPHFaceRecognizer CreateLBPHFaceRecognizer(void); void LBPHFaceRecognizer_SetRadius(LBPHFaceRecognizer fr, int radius); void LBPHFaceRecognizer_SetNeighbors(LBPHFaceRecognizer fr, int neighbors); int LBPHFaceRecognizer_GetNeighbors(LBPHFaceRecognizer fr); @@ -46,7 +63,13 @@ int LBPHFaceRecognizer_GetGridY(LBPHFaceRecognizer fr); void LBPHFaceRecognizer_Close(LBPHFaceRecognizer fr); +FisherFaceRecognizer FisherFaceRecognizer_Create(void); +FisherFaceRecognizer FisherFaceRecognizer_CreateWithParams(int num_components, float threshold); +void FisherFaceRecognizer_Close(FisherFaceRecognizer fr); +EigenFaceRecognizer EigenFaceRecognizer_Create(void); +EigenFaceRecognizer EigenFaceRecognizer_CreateWithParams(int num_components, float threshold); +void EigenFaceRecognizer_Close(EigenFaceRecognizer fr); #ifdef __cplusplus } diff --git a/contrib/face_recognizer.go b/contrib/face_recognizer.go index 1b087e94..1abaf185 100644 --- a/contrib/face_recognizer.go +++ b/contrib/face_recognizer.go @@ -24,6 +24,18 @@ type FaceRecognizer interface { Close() error } +type BasicFaceRecognizer interface { + GetEigenValues() gocv.Mat + GetEigenVectors() gocv.Mat + GetLabels() gocv.Mat + GetMean() gocv.Mat + GetNumComponents() int + SetNumComponents(val int) + GetProjections() []gocv.Mat + SaveFile(fname string) + LoadFile(fname string) +} + func faceRecognizer_Empty(fr C.FaceRecognizer) bool { b := C.FaceRecognizer_Empty(fr) return bool(b) @@ -107,3 +119,102 @@ func faceRecognizer_LoadFile(fr C.FaceRecognizer, fname string) { defer C.free(unsafe.Pointer(cName)) C.FaceRecognizer_LoadFile(fr, cName) } + +func basicFaceRecognizer_Train(fr C.BasicFaceRecognizer, 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.BasicFaceRecognizer_Train(fr, matsVector, labelsVector) +} + +func basicFaceRecognizer_Update(fr C.BasicFaceRecognizer, 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.BasicFaceRecognizer_Update(fr, matsVector, labelsVector) +} + +func basicFaceRecognizer_GetEigenValues(fr C.BasicFaceRecognizer) gocv.Mat { + c_mat := C.BasicFaceRecognizer_getEigenValues(fr) + return gocv.NewMatFromCMat(unsafe.Pointer(c_mat)) +} + +func basicFaceRecognizer_GetEigenVectors(fr C.BasicFaceRecognizer) gocv.Mat { + c_mat := C.BasicFaceRecognizer_getEigenVectors(fr) + return gocv.NewMatFromCMat(unsafe.Pointer(c_mat)) +} + +func basicFaceRecognizer_GetLabels(fr C.BasicFaceRecognizer) gocv.Mat { + c_mat := C.BasicFaceRecognizer_getLabels(fr) + return gocv.NewMatFromCMat(unsafe.Pointer(c_mat)) +} + +func basicFaceRecognizer_GetMean(fr C.BasicFaceRecognizer) gocv.Mat { + c_mat := C.BasicFaceRecognizer_getMean(fr) + return gocv.NewMatFromCMat(unsafe.Pointer(c_mat)) +} + +func basicFaceRecognizer_GetNumComponents(fr C.BasicFaceRecognizer) int { + i := C.BasicFaceRecognizer_getNumComponents(fr) + return int(i) +} + +func basicFaceRecognizer_SetNumComponents(fr C.BasicFaceRecognizer, val int) { + C.BasicFaceRecognizer_setNumComponents(fr, C.int(val)) +} + +func basicFaceRecognizer_GetProjections(fr C.BasicFaceRecognizer) []gocv.Mat { + + c_mats := C.BasicFaceRecognizer_getProjections(fr) + defer C.Mats_Close(c_mats) + + mats := make([]gocv.Mat, 0, c_mats.length) + + for i := 0; i < int(c_mats.length); i++ { + c_mat := C.Mats_get(c_mats, C.int(i)) + mat := gocv.NewMatFromCMat(unsafe.Pointer(c_mat)) + mats = append(mats, mat) + } + + return mats +} + +func basicFaceRecognizer_SaveFile(fr C.BasicFaceRecognizer, fname string) { + cName := C.CString(fname) + defer C.free(unsafe.Pointer(cName)) + C.BasicFaceRecognizer_SaveFile(fr, cName) +} + +func basicFaceRecognizer_LoadFile(fr C.BasicFaceRecognizer, fname string) { + cName := C.CString(fname) + defer C.free(unsafe.Pointer(cName)) + C.BasicFaceRecognizer_LoadFile(fr, cName) +} diff --git a/contrib/face_test.go b/contrib/face_test.go index b01ac8de..0d7534e3 100644 --- a/contrib/face_test.go +++ b/contrib/face_test.go @@ -113,3 +113,131 @@ func TestLBPHFaceRecognizer_SetGrid_GetGrid(t *testing.T) { t.Errorf("got %+v want {7, 5}", p) } } + +func TestEigenFaceRecognizer_Methods(t *testing.T) { + model := NewEigenFaceRecognizer() + if model == nil { + t.Errorf("Invalid NewEigenFaceRecognizer call %v", model) + } + + model.Empty() + + m := model.GetEigenValues() + defer m.Close() + m2 := model.GetEigenVectors() + defer m2.Close() + m3 := model.GetMean() + defer m3.Close() + + nc := model.GetNumComponents() + t.Logf("numComponents %d\n", nc) + + labels := []int{1, 1, 1, 1, 2, 2, 2, 2} + images := []gocv.Mat{ + gocv.IMRead("./att_faces/s1/1.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s1/2.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s1/3.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s1/4.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s2/1.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s2/2.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s2/3.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s2/4.pgm", gocv.IMReadGrayScale), + } + model.Train(images, labels) + + sample := gocv.IMRead("./att_faces/s2/5.pgm", gocv.IMReadGrayScale) + label := model.Predict(sample) + if label != 2 { + t.Errorf("Invalid simple predict! label: %d", label) + } + resp := model.PredictExtendedResponse(sample) + if resp.Label != 2 { + t.Errorf("Invalid extended result predict! label: %d", resp.Label) + } + + // set wrong threshold + model.SetThreshold(0.0) + label = model.Predict(sample) + if label != -1 { + t.Errorf("Invalid set wrong threshold! label: %d", label) + } + + // test save and load + fName := "data.yaml" + model.SaveFile(fName) + modelNew := NewEigenFaceRecognizer() + modelNew.LoadFile(fName) + label = modelNew.Predict(sample) + if label != 2 { + t.Errorf("Invalid loaded data: %d", label) + } +} + +func TestFisherFaceRecognizer_Methods(t *testing.T) { + model := NewFisherFaceRecognizer() + if model == nil { + t.Errorf("Invalid NewFisherFaceRecognizer call %v", model) + } + + model.Empty() + + m := model.GetEigenValues() + defer m.Close() + m2 := model.GetEigenVectors() + defer m2.Close() + m3 := model.GetMean() + defer m3.Close() + + nc := model.GetNumComponents() + t.Logf("numComponents %d\n", nc) + labels := []int{1, 1, 1, 1, 2, 2, 2, 2} + images := []gocv.Mat{ + gocv.IMRead("./att_faces/s1/1.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s1/2.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s1/3.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s1/4.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s2/1.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s2/2.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s2/3.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s2/4.pgm", gocv.IMReadGrayScale), + } + model.Train(images, labels) + + sample := gocv.IMRead("./att_faces/s2/5.pgm", gocv.IMReadGrayScale) + label := model.Predict(sample) + if label != 2 { + t.Errorf("Invalid simple predict! label: %d", label) + } + resp := model.PredictExtendedResponse(sample) + if resp.Label != 2 { + t.Errorf("Invalid extended result predict! label: %d", resp.Label) + } + + // add new data + sample = gocv.IMRead("./att_faces/s3/10.pgm", gocv.IMReadGrayScale) + newLabels := []int{1, 3, 3, 3, 3, 3, 3} + newImages := []gocv.Mat{ + gocv.IMRead("./att_faces/s1/1.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s3/1.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s3/2.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s3/3.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s3/4.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s3/5.pgm", gocv.IMReadGrayScale), + gocv.IMRead("./att_faces/s3/6.pgm", gocv.IMReadGrayScale), + } + model.Update(newImages, newLabels) + label = model.Predict(sample) + if label != 3 { + t.Errorf("Invalid new data update: %d", label) + } + + // test save and load + fName := "data.yaml" + model.SaveFile(fName) + modelNew := NewFisherFaceRecognizer() + modelNew.LoadFile(fName) + label = modelNew.Predict(sample) + if label != 3 { + t.Errorf("Invalid loaded data: %d", label) + } +} diff --git a/core.go b/core.go index 2fc23c7d..07fe80f4 100644 --- a/core.go +++ b/core.go @@ -206,6 +206,11 @@ func NewMat() Mat { return newMat(C.Mat_New()) } +// NewMatFromCMat returns a new Mat from an unsafe.Pointer(C.Mat). +func NewMatFromCMat(c_mat unsafe.Pointer) Mat { + return newMat(C.Mat(c_mat)) +} + // NewMatWithSize returns a new Mat with a specific size and type. func NewMatWithSize(rows int, cols int, mt MatType) Mat { return newMat(C.Mat_NewWithSize(C.int(rows), C.int(cols), C.int(mt)))