From 5d94d4ce9e064340681d5fa668213faf19b0ab5f Mon Sep 17 00:00:00 2001 From: danile71 Date: Wed, 12 Feb 2020 20:52:23 +0300 Subject: [PATCH] Add tags * if you want use 'gocv' - build -tags gocv --- face.go | 55 ++++------------------------------------------ facerec.cc | 3 --- gocv.cc | 32 +++++++++++++++++++++++++++ gocv.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ gocv.h | 19 ++++++++++++++++ wrapper.cc | 26 ---------------------- wrapper.h | 1 - 7 files changed, 119 insertions(+), 81 deletions(-) create mode 100644 gocv.cc create mode 100644 gocv.go create mode 100644 gocv.h diff --git a/face.go b/face.go index 9052c11..b4c6c08 100644 --- a/face.go +++ b/face.go @@ -1,9 +1,5 @@ package face -// #cgo !windows pkg-config: opencv4 -// #cgo CXXFLAGS: --std=c++11 -// #cgo windows CPPFLAGS: -IC:/opencv/build/install/include -// #cgo windows LDFLAGS: -LC:/opencv/build/install/x64/mingw/lib -lopencv_core420 -lopencv_face420 -lopencv_videoio420 -lopencv_imgproc420 -lopencv_highgui420 -lopencv_imgcodecs420 -lopencv_objdetect420 -lopencv_features2d420 -lopencv_video420 -lopencv_dnn420 -lopencv_xfeatures2d420 -lopencv_plot420 -lopencv_tracking420 -lopencv_img_hash420 -lopencv_calib3d420 // #cgo pkg-config: dlib-1 // #cgo CXXFLAGS: -std=c++1z -Wall -O3 -DNDEBUG -march=native // #cgo LDFLAGS: -ljpeg @@ -18,8 +14,6 @@ import ( "math" "os" "unsafe" - - "gocv.io/x/gocv" ) const ( @@ -35,6 +29,10 @@ const ( Male ) +func (g Gender) String() string { + return [...]string{"Female", "Male"}[g] +} + // A Recognizer creates face descriptors for provided images and // classifies them into categories. type Recognizer struct { @@ -191,43 +189,6 @@ func (rec *Recognizer) detectBuffer(type_ int, imgData []byte) (faces []Face, er return } -func (rec *Recognizer) detectMat(type_ int, mat gocv.Mat) (faces []Face, err error) { - cType := C.int(type_) - var ptr C.image_pointer - - ret := C.facerec_detect_mat(rec.ptr, (*C.image_pointer)(unsafe.Pointer(&ptr)), unsafe.Pointer(mat.Ptr()), cType) - defer C.free(unsafe.Pointer(ret)) - - if ret.err_str != nil { - defer C.free(unsafe.Pointer(ret.err_str)) - err = makeError(C.GoString(ret.err_str), int(ret.err_code)) - return - } - - numFaces := int(ret.num_faces) - if numFaces == 0 { - return - } - - // Copy faces data to Go structure. - defer C.free(unsafe.Pointer(ret.rectangles)) - - rDataLen := numFaces * rectLen - rDataPtr := unsafe.Pointer(ret.rectangles) - rData := (*[1 << 30]C.long)(rDataPtr)[:rDataLen:rDataLen] - - for i := 0; i < numFaces; i++ { - face := Face{imagePointer: &ptr} - x0 := int(rData[i*rectLen]) - y0 := int(rData[i*rectLen+1]) - x1 := int(rData[i*rectLen+2]) - y1 := int(rData[i*rectLen+3]) - face.Rectangle = image.Rect(x0, y0, x1, y1) - faces = append(faces, face) - } - return -} - func (rec *Recognizer) detectFile(type_ int, file string) (faces []Face, err error) { if !fileExists(file) { err = ImageLoadError(fmt.Sprintf("File '%s' not found!", file)) @@ -271,14 +232,6 @@ func (rec *Recognizer) detectFile(type_ int, file string) (faces []Face, err err return } -func (rec *Recognizer) DetectMat(mat gocv.Mat) (faces []Face, err error) { - return rec.detectMat(0, mat) -} - -func (rec *Recognizer) DetectMatCNN(mat gocv.Mat) (faces []Face, err error) { - return rec.detectMat(1, mat) -} - // Detect returns all faces found on the provided image, sorted from // left to right. Empty list is returned if there are no faces, error is // returned if there was some error while decoding/processing image. diff --git a/facerec.cc b/facerec.cc index 4f4d22b..ddc4eb6 100644 --- a/facerec.cc +++ b/facerec.cc @@ -5,9 +5,6 @@ #include #include #include -#include -#include -#include #include "facerec.h" #include "classify.h" diff --git a/gocv.cc b/gocv.cc new file mode 100644 index 0000000..2c426d1 --- /dev/null +++ b/gocv.cc @@ -0,0 +1,32 @@ +// +build gocv + +#include +#include +#include +#include "facerec.h" +#include "gocv.h" + +using namespace dlib; + +facesret* facerec_detect_mat(facerec* rec, image_pointer *p, const void *mat,int type) { + facesret* ret = (facesret*)calloc(1, sizeof(facesret)); + image_t img; + std::vector rects; + cv::Mat *mat_img = new cv::Mat(*((cv::Mat*)mat)); + IplImage ipl_img = cvIplImage(*mat_img); + + try { + cv_image dlib_img(&ipl_img); + assign_image(img, dlib_img); + } catch(image_load_error& e) { + ret->err_str = strdup(e.what()); + ret->err_code = IMAGE_LOAD_ERROR; + return ret; + } catch (std::exception& e) { + ret->err_str = strdup(e.what()); + ret->err_code = UNKNOWN_ERROR; + return ret; + } + + return facerec_detect(ret, p, rec, img, type); +} diff --git a/gocv.go b/gocv.go new file mode 100644 index 0000000..fdee37c --- /dev/null +++ b/gocv.go @@ -0,0 +1,64 @@ +// +build gocv + +package face + +// #cgo !windows pkg-config: opencv4 +// #cgo CXXFLAGS: --std=c++1z +// #cgo windows CPPFLAGS: -IC:/opencv/build/install/include +// #cgo windows LDFLAGS: -LC:/opencv/build/install/x64/mingw/lib -lopencv_core420 -lopencv_face420 -lopencv_videoio420 -lopencv_imgproc420 -lopencv_highgui420 -lopencv_imgcodecs420 -lopencv_objdetect420 -lopencv_features2d420 -lopencv_video420 -lopencv_dnn420 -lopencv_xfeatures2d420 -lopencv_plot420 -lopencv_tracking420 -lopencv_img_hash420 -lopencv_calib3d420 +// #include +// #include +// #include "wrapper.h" +// #include "gocv.h" +import "C" +import ( + "image" + "unsafe" + + "gocv.io/x/gocv" +) + +func (rec *Recognizer) detectMat(type_ int, mat gocv.Mat) (faces []Face, err error) { + cType := C.int(type_) + var ptr C.image_pointer + + ret := C.facerec_detect_mat(rec.ptr, (*C.image_pointer)(unsafe.Pointer(&ptr)), unsafe.Pointer(mat.Ptr()), cType) + defer C.free(unsafe.Pointer(ret)) + + if ret.err_str != nil { + defer C.free(unsafe.Pointer(ret.err_str)) + err = makeError(C.GoString(ret.err_str), int(ret.err_code)) + return + } + + numFaces := int(ret.num_faces) + if numFaces == 0 { + return + } + + // Copy faces data to Go structure. + defer C.free(unsafe.Pointer(ret.rectangles)) + + rDataLen := numFaces * rectLen + rDataPtr := unsafe.Pointer(ret.rectangles) + rData := (*[1 << 30]C.long)(rDataPtr)[:rDataLen:rDataLen] + + for i := 0; i < numFaces; i++ { + face := Face{imagePointer: &ptr} + x0 := int(rData[i*rectLen]) + y0 := int(rData[i*rectLen+1]) + x1 := int(rData[i*rectLen+2]) + y1 := int(rData[i*rectLen+3]) + face.Rectangle = image.Rect(x0, y0, x1, y1) + faces = append(faces, face) + } + return +} + +func (rec *Recognizer) DetectMat(mat gocv.Mat) (faces []Face, err error) { + return rec.detectMat(0, mat) +} + +func (rec *Recognizer) DetectMatCNN(mat gocv.Mat) (faces []Face, err error) { + return rec.detectMat(1, mat) +} diff --git a/gocv.h b/gocv.h new file mode 100644 index 0000000..5370859 --- /dev/null +++ b/gocv.h @@ -0,0 +1,19 @@ +// +build gocv + +#pragma once +#ifndef GOCV_H +#define GOCV_H + +#include "wrapper.h" + +#ifdef __cplusplus +extern "C" { +#endif + +facesret* facerec_detect_mat(facerec* rec, image_pointer *p, const void *mat,int type); + +#ifdef __cplusplus +} +#endif + +#endif /* GOCV_H */ diff --git a/wrapper.cc b/wrapper.cc index ce6c407..6b22a06 100644 --- a/wrapper.cc +++ b/wrapper.cc @@ -6,9 +6,6 @@ #include #include #include -#include -#include -#include #include "facerec.h" #include "classify.h" @@ -91,29 +88,6 @@ facesret* facerec_detect_file(facerec* rec, image_pointer *p, const char* file,i return facerec_detect(ret, p, rec, img, type); } -facesret* facerec_detect_mat(facerec* rec, image_pointer *p, const void *mat,int type) { - facesret* ret = (facesret*)calloc(1, sizeof(facesret)); - image_t img; - std::vector rects; - cv::Mat *mat_img = new cv::Mat(*((cv::Mat*)mat)); - IplImage ipl_img = cvIplImage(*mat_img); - - try { - cv_image dlib_img(&ipl_img); - assign_image(img, dlib_img); - } catch(image_load_error& e) { - ret->err_str = strdup(e.what()); - ret->err_code = IMAGE_LOAD_ERROR; - return ret; - } catch (std::exception& e) { - ret->err_str = strdup(e.what()); - ret->err_code = UNKNOWN_ERROR; - return ret; - } - - return facerec_detect(ret, p, rec, img, type); -} - facesret* facerec_detect_buffer(facerec* rec, image_pointer *p, unsigned char* img_data, int len,int type) { facesret* ret = (facesret*)calloc(1, sizeof(facesret)); image_t img; diff --git a/wrapper.h b/wrapper.h index f08f49d..03bcadd 100644 --- a/wrapper.h +++ b/wrapper.h @@ -47,7 +47,6 @@ typedef struct faceret { facerec* facerec_init(); facesret* facerec_detect_file(facerec*, image_pointer *, const char*,int); facesret* facerec_detect_buffer(facerec*, image_pointer *, unsigned char*, int, int); -facesret* facerec_detect_mat(facerec* rec, image_pointer *p, const void *mat,int type); faceret* facerec_recognize(facerec*, image_pointer*, int, int, int, int); int facerec_gender(facerec* rec, image_pointer *p, int x, int y, int x1, int y1); void facerec_set_cnn(facerec* , const char *);