派生自 libgowrapper/face

zhangmeng
2020-01-15 0ffd95f2278e860736e46f8b73f357470f5a3d91
goface.go
@@ -12,14 +12,16 @@
*/
import "C"
import (
   "errors"
   "unsafe"
   "basic.com/libgowrapper/sdkstruct.git"
   "basic.com/pubsub/protomsg.git"
   "github.com/gogo/protobuf/proto"
)
// SDKFace sdk
type SDKFace struct {
   handle      unsafe.Pointer
   detector    bool
   extractor   bool
   propertizer bool
@@ -28,14 +30,9 @@
}
// NewSDK sdk
func NewSDK(fn func(...interface{})) interface{} {
   h := C.create_sdkface()
   if h == nil {
      return nil
   }
func NewSDK(fn func(...interface{})) *SDKFace {
   return &SDKFace{
      handle:      h,
      detector:    false,
      extractor:   false,
      propertizer: false,
@@ -45,11 +42,8 @@
}
// Free free
func Free(i interface{}) {
   s := i.(*SDKFace)
   if s != nil && s.handle != nil {
      C.release(s.handle)
   }
func (s *SDKFace) Free() {
   C.c_api_release()
}
func (s *SDKFace) printLog(l ...interface{}) {
@@ -59,60 +53,67 @@
}
// Detector detector
func Detector(i interface{}, minFaces, rollAngles, threadMax, gpu int) bool {
   s := i.(*SDKFace)
func (s *SDKFace) Detector(minFaces, rollAngle, threadMax, gpu int) bool {
   if s.detector {
      return true
   }
   ret := C.init_detector(s.handle, C.int(minFaces), C.int(rollAngles), C.int(threadMax), C.int(gpu))
   ret := C.c_api_face_detector_init(C.int(threadMax), C.int(gpu), C.int(minFaces), C.int(rollAngle))
   if ret <= 0 {
      s.printLog("->face--> CREATE Detector ERROR")
      s.printLog("->face--> CREATE Detector ERROR: ", ret)
      return false
   }
   s.printLog("->face--> CREATE Detector Threads: ", threadMax, " GPU:", gpu)
   s.detector = true
   return true
}
// Extractor ext
func Extractor(i interface{}, threadMax, gpu int) bool {
   s := i.(*SDKFace)
func (s *SDKFace) Extractor(threadMax, gpu int) bool {
   if s.extractor {
      return true
   }
   ret := C.init_extractor(s.handle, C.int(threadMax), C.int(gpu))
   ret := C.c_api_face_extractor_init(C.int(threadMax), C.int(gpu))
   if ret <= 0 {
      s.printLog("->face--> CREATE Extractor ERROR")
      s.printLog("->face--> CREATE Extractor ERROR: ", ret)
      return false
   }
   s.printLog("->face--> CREATE Extractor Threads: ", threadMax, " GPU:", gpu)
   s.extractor = true
   return true
}
// Propertizer prop
func Propertizer(i interface{}, threadMax int) bool {
   s := i.(*SDKFace)
func (s *SDKFace) Propertizer(threadMax int) bool {
   if s.propertizer {
      return true
   }
   ret := C.init_propertizer(s.handle, C.int(threadMax))
   ret := C.c_api_face_property_init(C.int(threadMax))
   if ret <= 0 {
      s.printLog("->face--> CREATE Propertizer ERROR")
      s.printLog("->face--> CREATE Propertizer ERROR: ", ret)
      return false
   }
   s.printLog("->face--> CREATE Propertizer Threads: ", threadMax)
   s.propertizer = true
   return true
}
// Tracker track
func Tracker(i interface{}, w, h, maxFaces, interval, sampleSize, threadMax, gpu int) bool {
   s := i.(*SDKFace)
   if s.tracker {
      return s.tracker
   }
   ret := C.init_tracker(s.handle, C.int(w), C.int(h), C.int(maxFaces), C.int(interval), C.int(sampleSize), C.int(threadMax), C.int(gpu))
func (s *SDKFace) Tracker(w, h, maxFaces, interval, sampleSize, threadMax, gpu int) bool {
   if s.tracker {
      return true
   }
   ret := C.c_api_face_tracker_init(C.int(threadMax), C.int(gpu), C.int(w), C.int(h), C.int(maxFaces), C.int(interval), C.int(sampleSize))
   if ret <= 0 {
      s.printLog("->face--> CREATE Tracker ERROR")
      s.printLog("->face--> CREATE Tracker ERROR: ", ret)
      return false
   }
   s.tracker = true
@@ -134,65 +135,65 @@
}
// Detect det
func Detect(s *SDKFace, data []byte, w, h, c int, ch int) []sdkstruct.CFacePos {
func (s *SDKFace) Detect(data []byte, w, h, c int, ch int) []sdkstruct.CFacePos {
   if !s.detector {
      return nil
   }
   var cfpos unsafe.Pointer
   var count C.int
   ret := C.detect(s.handle, unsafe.Pointer(&data[0]), C.int(w), C.int(h), C.int(c), C.int(ch), &cfpos, &count)
   if ret > 0 {
      return CFacePosArrayToGoArray(cfpos, int(count))
   cfpos := C.c_api_face_detect(&count, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.int(ch))
   if cfpos != nil {
      defer C.free(unsafe.Pointer(cfpos))
      return CFacePosArrayToGoArray(unsafe.Pointer(cfpos), int(count))
   }
   s.printLog("->face--> Detect No One, Ret: ", ret)
   s.printLog("->face--> Detect No One")
   return nil
}
// Extract extract
func Extract(s *SDKFace, fpos sdkstruct.CFacePos, data []byte, w, h, c int, ch int) []byte {
   pos := (*C.cFacePos)(unsafe.Pointer(&fpos))
   //(void *handle, const cFacePos *pos, const void*data, const int w, const int h, const int c, const int chan, void **feat, int *featLen);
   var feat unsafe.Pointer
   var featLen C.int
   ret := C.extract(s.handle, pos, unsafe.Pointer(&data[0]), C.int(w), C.int(h), C.int(c), C.int(ch), &feat, &featLen)
   if ret > 0 {
      return C.GoBytes(feat, featLen)
func (s *SDKFace) Extract(fpos sdkstruct.CFacePos, data []byte, w, h, c int, ch int) []byte {
   if !s.extractor {
      return nil
   }
   s.printLog("->face--> Extract Nothing, Ret: ", ret)
   s.printLog("->face--> facepos: ", fpos)
   var featLen C.int
   pos := (*C.cFacePos)(unsafe.Pointer(&fpos))
   if pos == nil {
      return nil
   }
   p := C.c_api_face_extract(&featLen, pos, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.int(ch))
   if p != nil {
      defer C.free(unsafe.Pointer(p))
      return C.GoBytes(unsafe.Pointer(p), featLen)
   }
   s.printLog("->face--> Extract Nothing")
   return nil
}
// Compare face compare
func Compare(i interface{}, feat1 []byte, feat2 []byte) float32 {
   s := i.(*SDKFace)
func (s *SDKFace) Compare(feat1 []byte, feat2 []byte) float32 {
   if s.extractor {
      return 0
   }
   res := C.compare(s.handle, (*C.uchar)(unsafe.Pointer(&feat1[0])), (*C.uchar)(unsafe.Pointer(&feat2[0])))
   res := C.c_api_face_compare((*C.uchar)(unsafe.Pointer(&feat1[0])), (*C.uchar)(unsafe.Pointer(&feat2[0])))
   return float32(res)
}
// Propertize prop
func Propertize(s *SDKFace, fpos sdkstruct.CFacePos, data []byte, w, h, c int, ch int) *sdkstruct.CThftResult {
func (s *SDKFace) Propertize(fpos sdkstruct.CFacePos, data []byte, w, h, c int, ch int) sdkstruct.CThftResult {
   if !s.propertizer {
      return nil
      return sdkstruct.CThftResult{Age: 0}
   }
   pos := (*C.cFacePos)(unsafe.Pointer(&fpos))
   var thft unsafe.Pointer
   ret := C.propertize(s.handle, pos, unsafe.Pointer(&data[0]), C.int(w), C.int(h), C.int(c), C.int(ch), &thft)
   if ret == 0 {
      gothft := *(*sdkstruct.CThftResult)(thft)
      C.free(thft)
      return &gothft
   }
   s.printLog("->face--> Propertize Nothing, Ret: ", ret)
   return nil
   result := C.c_api_face_property(pos, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.int(ch))
   s.printLog("->face--> Propertize")
   return *(*sdkstruct.CThftResult)(unsafe.Pointer(&result))
}
// CFaceInfoArrayToGoArray convert cFaceInfo array to go
@@ -208,7 +209,7 @@
}
// Track track
func Track(s *SDKFace, data []byte, w, h, c int, ch int) []sdkstruct.CFaceInfo {
func (s *SDKFace) Track(data []byte, w, h, c int, ch int) []sdkstruct.CFaceInfo {
   if !s.tracker {
      return nil
   }
@@ -216,17 +217,14 @@
   //img, const int chan, void **fInfo, int *fcnt);
   var fCount C.int
   var finfos unsafe.Pointer
   ret := C.track(s.handle, unsafe.Pointer(&data[0]), C.int(w), C.int(h), C.int(c), C.int(ch), &finfos, &fCount)
   if ret > 0 {
      faces := CFaceInfoArrayToGoArray(finfos, int(fCount))
      //if len(faces) > 0{
      // fmt.Println("faces detected:", len(faces))
      //}
      return faces
   cFinfo := C.c_api_face_track(&fCount, (*C.uchar)(unsafe.Pointer(&data[0])), C.int(w), C.int(h), C.int(ch))
   // fmt.Println("cFinfo detected:", cFinfo)
   if cFinfo == nil {
      return nil
   }
   return nil
   defer C.free(unsafe.Pointer(cFinfo))
   faces := CFaceInfoArrayToGoArray(unsafe.Pointer(cFinfo), int(fCount))
   return faces
}
// FaceInfo2FacePos info -> pos
@@ -247,31 +245,23 @@
}
// TrackerResize init face tracker
func TrackerResize(i interface{}, w, h, ch int) bool {
   s := i.(*SDKFace)
func (s *SDKFace) TrackerResize(w, h, ch int) int {
   if !s.tracker {
      s.printLog("->face--> TrackerResize Failed, No Tracker Init")
      return false
      return -1
   }
   ret := C.resize(s.handle, C.int(w), C.int(h), C.int(ch))
   if ret == 1 {
      return true
   }
   s.printLog("->face--> TrackerResize Failed, Ret: ", ret, " SDK Channel: ", ch, " Size: ", w, "x", h)
   return false
   return int(C.c_api_face_track_resize(C.int(ch), C.int(w), C.int(h)))
}
// Run run
func Run(i interface{}, data []byte, w, h, c, dchan int) []sdkstruct.CFaceResult {
func (s *SDKFace) Run(data []byte, w, h, c, dchan int) (int, []byte, error) {
   if data == nil || w <= 0 || h <= 0 {
      return nil
      return 0, nil, errors.New("->face--> Face Input Image Error")
   }
   s := i.(*SDKFace)
   if !s.tracker || !s.extractor || !s.propertizer {
      return nil
      return 0, nil, errors.New("->face--> Face SDK No Init Correctly")
   }
   channel := c
@@ -279,31 +269,70 @@
      channel = 3
   }
   // if !TrackerResize(i, w, h, dchan) {
   //    return nil
   // }
   var fInfo []sdkstruct.CFaceInfo
   fInfo = Track(s, data, w, h, c, dchan)
   fInfo = s.Track(data, w, h, c, dchan)
   if len(fInfo) == 0 {
      return 0, nil, errors.New("->face--> Face Track No One")
   }
   var faces []sdkstruct.CFaceResult
   //将sdk返回值转换成protomsg类型
   var faces []*protomsg.ResultFaceDetect
   for _, d := range fInfo {
      //运行sd
      dec := FaceInfo2FacePos(d)
      prop := Propertize(s, dec, data, w, h, c, dchan)
      feat := Extract(s, dec, data, w, h, c, dchan)
      p := s.Propertize(dec, data, w, h, c, dchan)
      feat := s.Extract(dec, data, w, h, c, dchan)
      result := sdkstruct.CFaceResult{
         Info: d,
         Prop: *prop,
         Feat: feat,
      }
      faces = append(faces, result)
      /// filter rules
      // sdkid := rMsg.Msg.Tasklab.Sdkinfos[rMsg.Msg.Tasklab.Index].Ipcid
      // size := (d.RcFace.Right - d.RcFace.Left) * (d.RcFace.Bottom - d.RcFace.Top)
      // angle := d.FAngle
      // if !filter(rMsg.Msg.Tasklab.Taskid, sdkid, angle.Confidence, float32(angle.Yaw), int(size)) {
      //    continue
      // }
      /// filter rules
      prop := (*protomsg.ThftResult)(unsafe.Pointer(&p))
      fpos := tconvert2ProtoFacePos(d)
      //组成结果并序列化
      res := &protomsg.ResultFaceDetect{Pos: fpos, Result: prop, Feats: feat}
      faces = append(faces, res)
   }
   facePos := protomsg.ParamFacePos{Faces: faces}
   d, e := proto.Marshal(&facePos)
   return faces
   return len(faces), d, e
}
func tconvert2ProtoFacePos(dec sdkstruct.CFaceInfo) *protomsg.FacePos {
   crect := dec.RcFace
   rect := protomsg.Rect{Left: crect.Left, Top: crect.Top, Right: crect.Right, Bottom: crect.Bottom}
   leftEye := (*protomsg.Point)(unsafe.Pointer(&dec.PtLeftEye))
   rightEye := (*protomsg.Point)(unsafe.Pointer(&dec.PtRightEye))
   mouth := (*protomsg.Point)(unsafe.Pointer(&dec.PtMouth))
   nose := (*protomsg.Point)(unsafe.Pointer(&dec.PtNose))
   angle := (*protomsg.FaceAngle)(unsafe.Pointer(&dec.FAngle))
   faceID := uint64(dec.NFaceID)
   facialData := dec.PFacialData[:512]
   // facialData := make([]byte, 512)
   // copy(facialData[:], dec.PFacialData[:512])
   return &protomsg.FacePos{
      RcFace:     &rect,
      PtLeftEye:  leftEye,
      PtRightEye: rightEye,
      PtMouth:    mouth,
      PtNose:     nose,
      FAngle:     angle,
      Quality:    dec.NQuality,
      FacialData: facialData,
      FaceID:     faceID,
   }
}