Skip to content

Commit

Permalink
Add tags
Browse files Browse the repository at this point in the history
* if you want use 'gocv' - build -tags gocv
  • Loading branch information
Danile71 committed Feb 12, 2020
1 parent 04ab32b commit 5d94d4c
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 81 deletions.
55 changes: 4 additions & 51 deletions face.go
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -18,8 +14,6 @@ import (
"math"
"os"
"unsafe"

"gocv.io/x/gocv"
)

const (
Expand All @@ -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 {
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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.
Expand Down
3 changes: 0 additions & 3 deletions facerec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/graph_utils.h>
#include <dlib/image_io.h>
#include <dlib/opencv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/core/types_c.h>
#include "facerec.h"
#include "classify.h"

Expand Down
32 changes: 32 additions & 0 deletions gocv.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// +build gocv

#include <dlib/opencv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/core/types_c.h>
#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<rectangle> rects;
cv::Mat *mat_img = new cv::Mat(*((cv::Mat*)mat));
IplImage ipl_img = cvIplImage(*mat_img);

try {
cv_image<bgr_pixel> 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);
}
64 changes: 64 additions & 0 deletions gocv.go
Original file line number Diff line number Diff line change
@@ -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 <stdlib.h>
// #include <stdint.h>
// #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)
}
19 changes: 19 additions & 0 deletions gocv.h
Original file line number Diff line number Diff line change
@@ -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 */
26 changes: 0 additions & 26 deletions wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/graph_utils.h>
#include <dlib/image_io.h>
#include <dlib/opencv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/core/types_c.h>
#include "facerec.h"
#include "classify.h"

Expand Down Expand Up @@ -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<rectangle> rects;
cv::Mat *mat_img = new cv::Mat(*((cv::Mat*)mat));
IplImage ipl_img = cvIplImage(*mat_img);

try {
cv_image<bgr_pixel> 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;
Expand Down
1 change: 0 additions & 1 deletion wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down

0 comments on commit 5d94d4c

Please sign in to comment.