mirror of
https://github.com/bububa/openvision.git
synced 2025-09-27 01:56:04 +08:00
fix(face): eye status goapi
This commit is contained in:
115
go/examples/eye/main.go
Normal file
115
go/examples/eye/main.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/jpeg"
|
||||
"log"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/bububa/openvision/go/common"
|
||||
"github.com/bububa/openvision/go/face/detecter"
|
||||
"github.com/bububa/openvision/go/face/eye"
|
||||
)
|
||||
|
||||
func main() {
|
||||
wd, _ := os.Getwd()
|
||||
dataPath := cleanPath(wd, "~/go/src/github.com/bububa/openvision/data")
|
||||
imgPath := filepath.Join(dataPath, "./images")
|
||||
modelPath := filepath.Join(dataPath, "./models")
|
||||
common.CreateGPUInstance()
|
||||
defer common.DestroyGPUInstance()
|
||||
cpuCores := common.GetBigCPUCount()
|
||||
common.SetOMPThreads(cpuCores)
|
||||
log.Printf("CPU big cores:%d\n", cpuCores)
|
||||
d := retinaface(modelPath)
|
||||
defer d.Destroy()
|
||||
common.SetEstimatorThreads(d, cpuCores)
|
||||
e := lenet(modelPath)
|
||||
defer e.Destroy()
|
||||
common.SetEstimatorThreads(e, cpuCores)
|
||||
for _, fn := range []string{"eye-open.jpg", "eye-close.jpg", "eye-half.jpg"} {
|
||||
detect(d, e, imgPath, fn)
|
||||
}
|
||||
}
|
||||
|
||||
func retinaface(modelPath string) detecter.Detecter {
|
||||
modelPath = filepath.Join(modelPath, "fd")
|
||||
d := detecter.NewRetinaFace()
|
||||
if err := d.LoadModel(modelPath); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func lenet(modelPath string) eye.Detecter {
|
||||
modelPath = filepath.Join(modelPath, "eye/lenet")
|
||||
d := eye.NewLenet()
|
||||
if err := d.LoadModel(modelPath); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func detect(d detecter.Detecter, e eye.Detecter, imgPath string, filename string) {
|
||||
inPath := filepath.Join(imgPath, filename)
|
||||
imgLoaded, err := loadImage(inPath)
|
||||
if err != nil {
|
||||
log.Fatalln("load image failed,", err)
|
||||
}
|
||||
img := common.NewImage(imgLoaded)
|
||||
faces, err := d.Detect(img)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
for _, face := range faces {
|
||||
rect := face.Rect
|
||||
closed, err := e.IsClosed(img, rect)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
fmt.Printf("fn: %s, closed: %+v\n", filename, closed)
|
||||
}
|
||||
}
|
||||
|
||||
func loadImage(filePath string) (image.Image, error) {
|
||||
fn, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer fn.Close()
|
||||
img, _, err := image.Decode(fn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return img, nil
|
||||
}
|
||||
|
||||
func saveImage(img image.Image, filePath string) error {
|
||||
buf := new(bytes.Buffer)
|
||||
if err := jpeg.Encode(buf, img, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
fn, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fn.Close()
|
||||
fn.Write(buf.Bytes())
|
||||
return nil
|
||||
}
|
||||
|
||||
func cleanPath(wd string, path string) string {
|
||||
usr, _ := user.Current()
|
||||
dir := usr.HomeDir
|
||||
if path == "~" {
|
||||
return dir
|
||||
} else if strings.HasPrefix(path, "~/") {
|
||||
return filepath.Join(dir, path[2:])
|
||||
}
|
||||
return filepath.Join(wd, path)
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
// +build !vulkan
|
||||
|
||||
package recognizer
|
||||
package eye
|
||||
|
||||
/*
|
||||
#cgo CXXFLAGS: --std=c++11 -fopenmp
|
||||
|
@@ -17,27 +17,28 @@ import (
|
||||
// Detecter represents Eye Detector interface
|
||||
type Detecter interface {
|
||||
common.Estimator
|
||||
Status(img *common.Image, face common.Rectangle) ([]float64, error)
|
||||
IsClosed(img *common.Image, face common.Rectangle) (bool, error)
|
||||
}
|
||||
|
||||
// Status extract scores using recognizer
|
||||
func Status(r Detecter, img *common.Image, faceRect common.Rectangle) ([]float64, error) {
|
||||
// IsClosed check whether eyes are closed
|
||||
func IsClosed(r Detecter, img *common.Image, faceRect common.Rectangle) (bool, error) {
|
||||
imgWidth := img.WidthF64()
|
||||
imgHeight := img.HeightF64()
|
||||
data := img.Bytes()
|
||||
CFeatures := common.NewCFloatVector()
|
||||
defer common.FreeCFloatVector(CFeatures)
|
||||
scoresC := common.NewCFloatVector()
|
||||
defer common.FreeCFloatVector(scoresC)
|
||||
CRect := faceRect.CRect(imgWidth, imgHeight)
|
||||
errCode := C.eye_status(
|
||||
(C.IEye)(r.Pointer()),
|
||||
(*C.uchar)(unsafe.Pointer(&data[0])),
|
||||
C.int(imgWidth), C.int(imgHeight),
|
||||
(*C.Rect)(unsafe.Pointer(CRect)),
|
||||
(*C.FloatVector)(unsafe.Pointer(CFeatures)),
|
||||
(*C.FloatVector)(unsafe.Pointer(scoresC)),
|
||||
)
|
||||
C.free(unsafe.Pointer(CRect))
|
||||
if errCode != 0 {
|
||||
return nil, openvision.RecognizeFaceError(int(errCode))
|
||||
return false, openvision.RecognizeFaceError(int(errCode))
|
||||
}
|
||||
return common.GoFloatVector(CFeatures), nil
|
||||
scores := common.GoFloatVector(scoresC)
|
||||
return len(scores) > 0 && scores[0] == 1, nil
|
||||
}
|
||||
|
@@ -39,7 +39,7 @@ func (d *Lenet) Destroy() {
|
||||
common.DestroyEstimator(d)
|
||||
}
|
||||
|
||||
// Status implement Eye Detecter interface
|
||||
func (d *Lenet) Status(img *common.Image, faceRect common.Rectangle) ([]float64, error) {
|
||||
return Status(d, img, faceRect)
|
||||
// IsClosed implement Eye Detecter interface
|
||||
func (d *Lenet) IsClosed(img *common.Image, faceRect common.Rectangle) (bool, error) {
|
||||
return IsClosed(d, img, faceRect)
|
||||
}
|
||||
|
Reference in New Issue
Block a user