From dc77bcd30a90869fd8fd54beafb6057e48251bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=9A=D0=BE=D1=80?= =?UTF-8?q?=D0=B5=D0=BA=D0=BE=D0=B2=D1=86=D0=B5=D0=B2?= Date: Tue, 17 Sep 2019 13:17:47 +0300 Subject: [PATCH 01/36] Add libopenblas --- face.go | 1 + 1 file changed, 1 insertion(+) diff --git a/face.go b/face.go index b59010a..9b31286 100644 --- a/face.go +++ b/face.go @@ -3,6 +3,7 @@ package face // #cgo pkg-config: dlib-1 // #cgo CXXFLAGS: -std=c++1z -Wall -O3 -DNDEBUG -march=native // #cgo LDFLAGS: -ljpeg +// #cgo LDFLAGS: -lopenblas // #include // #include // #include "facerec.h" From e394049d511d06d75109f810bd5dae351538107c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=9A=D0=BE=D1=80?= =?UTF-8?q?=D0=B5=D0=BA=D0=BE=D0=B2=D1=86=D0=B5=D0=B2?= Date: Tue, 17 Sep 2019 13:31:29 +0300 Subject: [PATCH 02/36] Add libs --- face.go | 1 + 1 file changed, 1 insertion(+) diff --git a/face.go b/face.go index 9b31286..e54852a 100644 --- a/face.go +++ b/face.go @@ -4,6 +4,7 @@ package face // #cgo CXXFLAGS: -std=c++1z -Wall -O3 -DNDEBUG -march=native // #cgo LDFLAGS: -ljpeg // #cgo LDFLAGS: -lopenblas +// #cgo LDFLAGS: -llapack // #include // #include // #include "facerec.h" From afd80302f12f3c1ec426d8aa10f30f870931db31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=9A=D0=BE=D1=80?= =?UTF-8?q?=D0=B5=D0=BA=D0=BE=D0=B2=D1=86=D0=B5=D0=B2?= Date: Tue, 17 Sep 2019 13:42:51 +0300 Subject: [PATCH 03/36] Math lib --- face.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/face.go b/face.go index e54852a..3160f1e 100644 --- a/face.go +++ b/face.go @@ -4,7 +4,7 @@ package face // #cgo CXXFLAGS: -std=c++1z -Wall -O3 -DNDEBUG -march=native // #cgo LDFLAGS: -ljpeg // #cgo LDFLAGS: -lopenblas -// #cgo LDFLAGS: -llapack +// #cgo LDFLAGS: -lquadmath // #include // #include // #include "facerec.h" From 0ecff40ce133ec492413df57df6552c2395063c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=9A=D0=BE=D1=80?= =?UTF-8?q?=D0=B5=D0=BA=D0=BE=D0=B2=D1=86=D0=B5=D0=B2?= Date: Tue, 17 Sep 2019 13:43:24 +0300 Subject: [PATCH 04/36] lgfortran --- face.go | 1 + 1 file changed, 1 insertion(+) diff --git a/face.go b/face.go index 3160f1e..39fdfc9 100644 --- a/face.go +++ b/face.go @@ -5,6 +5,7 @@ package face // #cgo LDFLAGS: -ljpeg // #cgo LDFLAGS: -lopenblas // #cgo LDFLAGS: -lquadmath +// #cgo LDFLAGS: -lgfortran // #include // #include // #include "facerec.h" From 88ec5d100b9472b58dbed1b5629c2153db1218c7 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 11 Feb 2020 12:25:00 +0300 Subject: [PATCH 05/36] Update --- Makefile | 34 ++++++++++++++- classify.h | 3 ++ face.go | 38 +++++++++++++--- facerec.cc | 108 ++++++++-------------------------------------- facerec.h | 90 +++++++++++++++++++++++++++++++++++++- jpeg_mem_loader.h | 4 ++ 6 files changed, 177 insertions(+), 100 deletions(-) diff --git a/Makefile b/Makefile index efacfdb..f520858 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,17 @@ +.ONESHELL: +.PHONY: all download build sudo_install precommit gofmt-staged testdata + # Should contain src/github.com/Kagami/go-face or tests won't work # properly (multiple definition of C functions). + +# Temporary directory to put files into. +TMP_DIR?=/tmp/ + +BRANCH?=19.19 + export GOPATH = $(PWD)/../../../.. -all: test +all: download build sudo_install test clean precommit: gofmt-staged gofmt-staged: @@ -11,5 +20,26 @@ gofmt-staged: testdata: git clone https://github.com/Kagami/go-face-testdata testdata +download: + curl -Lo $(TMP_DIR)dlib.tar.gz https://github.com/davisking/dlib/archive/v${BRANCH}.tar.gz + cd $(TMP_DIR) + tar xf dlib.tar.gz + rm -rf dlib.tar.gz + +build: + cd $(TMP_DIR)dlib-${BRANCH} + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE=Release -DDLIB_JPEG_SUPPORT=ON -DBUILD_SHARED_LIBS=YES -DDLIB_USE_BLAS=ON -DDLIB_USE_LAPACK=ON .. + cmake --build . --config Release -- -j $(nproc --all) + +sudo_install: + cd $(TMP_DIR)dlib-${BRANCH}/build + sudo make install + +clean: + rm -rf $(TMP_DIR)dlib-${BRANCH} + rm -rf testdata + test: testdata - go test -v + go test -v \ No newline at end of file diff --git a/classify.h b/classify.h index ddc4642..c0a81ac 100644 --- a/classify.h +++ b/classify.h @@ -1,4 +1,6 @@ #pragma once +#ifndef CLASSIFY_H +#define CLASSIFY_H typedef dlib::matrix descriptor; @@ -8,3 +10,4 @@ int classify( const descriptor& test_sample, float tolerance ); +#endif /* CLASSIFY_H */ diff --git a/face.go b/face.go index 39fdfc9..eb50044 100644 --- a/face.go +++ b/face.go @@ -11,6 +11,7 @@ package face // #include "facerec.h" import "C" import ( + "fmt" "image" "io/ioutil" "math" @@ -60,10 +61,27 @@ func NewWithShape(r image.Rectangle, s []image.Point, d Descriptor) Face { // NewRecognizer returns a new recognizer interface. modelDir points to // directory with shape_predictor_5_face_landmarks.dat and // dlib_face_recognition_resnet_model_v1.dat files. -func NewRecognizer(modelDir string) (rec *Recognizer, err error) { - cModelDir := C.CString(modelDir) - defer C.free(unsafe.Pointer(cModelDir)) - ptr := C.facerec_init(cModelDir) +func NewRecognizer(resnetPath, cnnResnetPath, shapePredictorPath string) (rec *Recognizer, err error) { + if !fileExists(resnetPath) { + fmt.Errorf("File '%s' not found!", resnetPath) + os.Exit(1) + } + if !fileExists(cnnResnetPath) { + fmt.Errorf("File '%s' not found!", cnnResnetPath) + os.Exit(1) + } + if !fileExists(shapePredictorPath) { + fmt.Errorf("File '%s' not found!", shapePredictorPath) + os.Exit(1) + } + cResnetPath := C.CString(resnetPath) + defer C.free(unsafe.Pointer(cResnetPath)) + cCnnResnetPath := C.CString(cnnResnetPath) + defer C.free(unsafe.Pointer(cCnnResnetPath)) + cShapePredictorPath := C.CString(shapePredictorPath) + defer C.free(unsafe.Pointer(cShapePredictorPath)) + + ptr := C.facerec_init(cResnetPath, cCnnResnetPath, cShapePredictorPath) if ptr.err_str != nil { defer C.facerec_free(ptr) @@ -76,8 +94,8 @@ func NewRecognizer(modelDir string) (rec *Recognizer, err error) { return } -func NewRecognizerWithConfig(modelDir string, size int, padding float32, jittering int) (rec *Recognizer, err error) { - rec, err = NewRecognizer(modelDir) +func NewRecognizerWithConfig(resnetPath, cnnResnetPath, shapePredictorPath string, size int, padding float32, jittering int) (rec *Recognizer, err error) { + rec, err = NewRecognizer(resnetPath, cnnResnetPath, shapePredictorPath) cSize := C.ulong(size) cPadding := C.double(padding) cJittering := C.int(jittering) @@ -250,3 +268,11 @@ func (rec *Recognizer) Close() { C.facerec_free(rec.ptr) rec.ptr = nil } + +func fileExists(filename string) bool { + info, err := os.Stat(filename) + if os.IsNotExist(err) { + return false + } + return !info.IsDir() +} diff --git a/facerec.cc b/facerec.cc index cd09c54..7f6ce45 100644 --- a/facerec.cc +++ b/facerec.cc @@ -9,75 +9,16 @@ using namespace dlib; -template