zhangmeng
2019-12-11 2f5f0c75f3257b4ea9c37df6d02e5598b975740f
work/sdk/facetrack.go
@@ -30,50 +30,21 @@
*/
import "C"
import (
   "analysis/goconv"
   "analysis/logo"
   "analysis/work"
   "context"
   "fmt"
   "time"
   "unsafe"
   "basic.com/libgowrapper/sdkstruct.git"
   "basic.com/pubsub/protomsg.git"
   "basic.com/valib/gosdk.git"
   "github.com/gogo/protobuf/proto"
)
func tconvert2ProtoFacePos(dec gosdk.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,
   }
}
const (
   CacheFrameNum   = 3
   TrackChnTimeout = time.Duration(10)
   cacheFrameNum   = 3
   trackChnTimeout = time.Duration(10)
)
func (e *EFDetect) cleanChnStat() {
@@ -108,6 +79,7 @@
   for {
      select {
      case <-ctx.Done():
         e.fnFree(e.handle)
         return
      default:
         rMsg := <-in
@@ -121,7 +93,7 @@
            e.ftrackChans[rMsg.Msg.Cid] <- rMsg
         } else {
            e.ftrackChans[rMsg.Msg.Cid] = make(chan work.MsgRS, CacheFrameNum)
            e.ftrackChans[rMsg.Msg.Cid] = make(chan work.MsgRS, cacheFrameNum)
            chn := e.getAvailableChn()
            if chn < 0 {
               logo.Infof("TOO MUCH CHANNEL")
@@ -137,7 +109,7 @@
            }
            // conv to bgr24 and resize
            imgW, imgH := int(i.Width), int(i.Height)
            ret := gosdk.ResizeFaceTracker(e.ftrackChannels[rMsg.Msg.Cid], imgW, imgH)
            ret := e.fnTrackerResize(e.handle, e.ftrackChannels[rMsg.Msg.Cid], imgW, imgH)
            logo.Infof("ResizeFaceTracker: cid:%s, chan:%d, wXh:%d x %d ,result:%d\n",
               rMsg.Msg.Cid, e.ftrackChannels[rMsg.Msg.Cid], imgW, imgH, ret)
            go e.detectTrackOneChn(ctx, e.ftrackChans[rMsg.Msg.Cid], out, typ, e.ftrackChannels[rMsg.Msg.Cid])
@@ -156,8 +128,8 @@
   for {
      select {
      case <-ctx.Done():
         goconv.Free()
         return
      case rMsg := <-in:
         if !validRemoteMessage(rMsg, typ) {
@@ -175,20 +147,14 @@
         // conv to bgr24 and resize
         imgW, imgH := int(i.Width), int(i.Height)
         bgrData := goconv.YUV2BGR(i.Data, imgW, imgH)
         if bgrData == nil {
            ejectResult(nil, rMsg, out)
            continue
         }
         img := gosdk.SDKImage{Data: bgrData, Width: imgW, Height: imgH}
         detect := gosdk.FaceTrackSimple(img, dtchn)
         fRes := e.fnRun(e.handle, i.Data, imgW, imgH, 3, dtchn)
         var faces []*protomsg.ResultFaceDetect
         //将sdk返回值转换成protomsg类型
         for _, d := range detect {
         for _, r := range fRes {
            d := r.Info
            /// 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)
@@ -198,31 +164,23 @@
            }
            /// filter rules
            //运行sd
            dec := gosdk.FaceInfo2FacePos(d)
            prop := gosdk.FaceProperty(dec, img, dtchn)
            feat := gosdk.FaceExtract(dec, img, dtchn)
            resP := (*protomsg.ThftResult)(unsafe.Pointer(&prop))
            result := tconvert2ProtoFacePos(d)
            feat := r.Feat
            prop := (*protomsg.ThftResult)(unsafe.Pointer(&r.Prop))
            fpos := tconvert2ProtoFacePos(d)
            //组成结果并序列化
            res := &protomsg.ResultFaceDetect{Pos: result, Result: resP, Feats: feat}
            res := &protomsg.ResultFaceDetect{Pos: fpos, Result: prop, Feats: feat}
            faces = append(faces, res)
         }
         var err error
         var data []byte
         if len(faces) > 0 {
            // logo.Infoln("CID: ", rMsg.Msg.Cid, " TASK: ", rMsg.Msg.Tasklab.Taskid, " FACE TRACK OBJS: ", len(faces))
            facePos := protomsg.ParamFacePos{Faces: faces}
            data, err = proto.Marshal(&facePos)
            if err != nil {
               logo.Errorln("fdetect marshal proto face pos error", err)
               fmt.Println("fdetect marshal proto face pos error", err)
               data = nil
            }
         }
@@ -232,21 +190,21 @@
         if rMsg.Msg.Tasklab != nil {
            id, name = rMsg.Msg.Tasklab.Taskid, rMsg.Msg.Tasklab.Taskname
         }
         logo.Infoln("CAMERAID: ", rMsg.Msg.Cid, " TASKID: ", id, " TASKNAME: ", name, " DETECT FACE COUNT: ", len(faces))
         logo.Infoln("CAMERAID: ", rMsg.Msg.Cid, " TASKID: ", id, " TASKNAME: ", name, " DETECT FACE COUNT: ", len(fRes))
         sc++
         if sc == 25 {
            logo.Infoln("chan:%d, FACE RUN 25 FRAME USE TIME: ", dtchn, time.Since(tm))
            logo.Infoln("CHAN:%d, FACE RUN 25 FRAME USE TIME: ", dtchn, time.Since(tm))
            sc = 0
            tm = time.Now()
         }
         if time.Since(tm) > time.Second {
            logo.Infof("cahn:%d, FACE RUN %d FRAME USE TIME: %v", dtchn, sc, time.Since(tm))
            logo.Infof("CHAN:%d, FACE RUN %d FRAME USE TIME: %v", dtchn, sc, time.Since(tm))
            sc = 0
            tm = time.Now()
         }
      case <-time.After(TrackChnTimeout * time.Second):
      case <-time.After(trackChnTimeout * time.Second):
         logo.Errorln("Timeout to get image, curCid:", curCid)
         if curCid != "" {
            delete(e.ftrackChans, curCid)
@@ -258,160 +216,31 @@
   }
}
//func (e *EFDetect) detectTrack(ctx context.Context, in <-chan work.MsgRS, out chan<- work.MsgRS, typ string) {
//   tm := time.Now()
//   sc := 0
//
//   for {
//      select {
//      case <-ctx.Done():
//         goconv.Free()
//         return
//      default:
//         rMsg := <-in
//          validMsg := validRemoteMessage(rMsg, typ)
//
//         i := unpackImage(rMsg, typ)
//         if i == nil {
//             ejectResult(nil, rMsg, out)
//            continue
//         }
//
//         // conv to bgr24 and resize
//         imgW, imgH := int(i.Width), int(i.Height)
//         resizeW, resizeH := util.SFI.TrackPicWidth, util.SFI.TrackPicHeight
//         fx := (float64)(resizeW) / (float64)(imgW)
//         fy := (float64)(resizeH) / (float64)(imgH)
//
//         origData, resizeData := goconv.YUV2BGRandResize(i.Data, goconv.PIX_FMT_NV12, imgW, imgH, fx, fy)
//         if origData == nil {
//             ejectResult(nil, rMsg, out)
//            continue
//         }
//         // resize to track
//         if imgW < resizeW && imgH < resizeH {
//            resizeData = origData
//            resizeW, resizeH = imgW, imgH
//         }
//         // resize to track
//
//         img := gosdk.SDKImage{Data: origData, Width: imgW, Height: imgH}
//         imgTrack := gosdk.SDKImage{Data: resizeData, Width: resizeW, Height: resizeH}
//          if !validMsg {
//             ejectResult(nil, rMsg, out)
//            continue
//         }
//         //运行sdk
//         c, ok, _ := e.q.Get()
//         if !ok {
//            logo.Errorln("fdetect there is no idle thread")
//            ejectResult(nil, rMsg, out)
//            continue
//         }
//         detect := gosdk.FaceTrackSimple(imgTrack, c.(int))
//         e.q.Put(c)
//
//         // if len(detect) > 0 {
//         //    logo.Infof("FACE DETECT FROM CAMERA %s IMAGE-ID %d, TASKID %s, %d FACES COUNT\n", rMsg.Msg.Cid, i.Id, rMsg.Msg.Tasklab.Taskid, len(detect))
//         // }
//
//         var faces []*protomsg.ResultFaceDetect
//
//         //将sdk返回值转换成protomsg类型
//         for _, d := range detect {
//
//            /// 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
//
//            if fx < 1.0 || fy < 1.0 {
//               d.RcFace.Left = (int32)((float64)(d.RcFace.Left) / fx)
//               d.RcFace.Top = (int32)((float64)(d.RcFace.Top) / fy)
//               d.RcFace.Right = (int32)((float64)(d.RcFace.Right) / fx)
//               d.RcFace.Bottom = (int32)((float64)(d.RcFace.Bottom) / fy)
//               d.PtLeftEye.X = (int32)((float64)(d.PtLeftEye.X) / fx)
//               d.PtLeftEye.Y = (int32)((float64)(d.PtLeftEye.Y) / fy)
//               d.PtRightEye.X = (int32)((float64)(d.PtRightEye.X) / fx)
//               d.PtRightEye.Y = (int32)((float64)(d.PtRightEye.Y) / fy)
//               d.PtMouth.X = (int32)((float64)(d.PtMouth.X) / fx)
//               d.PtMouth.Y = (int32)((float64)(d.PtMouth.Y) / fy)
//               d.PtNose.X = (int32)((float64)(d.PtNose.X) / fx)
//               d.PtNose.Y = (int32)((float64)(d.PtNose.Y) / fy)
//
//               faceData := d.PFacialData[:8192]
//               data := C.CBytes(faceData)
//               defer C.free(data)
//               resizeP := C.resize(&data, C.float(fx), C.float(fy))
//               fd := C.GoBytes(resizeP, 8192)
//               d.PFacialData = *(*[8192]uint8)(unsafe.Pointer(&fd[0]))
//
//            }
//
//            //运行sd
//            dec := gosdk.FaceInfo2FacePos(d)
//
//            c, ok, _ := e.qprop.Get()
//            if !ok {
//               logo.Errorln("fproperty there is no idle thread")
//               continue
//            }
//            prop := gosdk.FaceProperty(dec, imgTrack, c.(int))
//            e.qprop.Put(c)
//
//            c, ok, _ = e.qext.Get()
//            if !ok {
//               logo.Errorln("fextract there is no idle thread")
//               continue
//            }
//            feat := gosdk.FaceExtract(dec, imgTrack, c.(int))
//            e.qext.Put(c)
//
//            resP := (*protomsg.ThftResult)(unsafe.Pointer(&prop))
//
//            result := tconvert2ProtoFacePos(d)
//
//            //组成结果并序列化
//            res := &protomsg.ResultFaceDetect{Pos: result, Result: resP, Feats: feat}
//            faces = append(faces, res)
//
//         }
//
//         var err error
//         var data []byte
//         if len(faces) > 0 {
//
//            // logo.Infoln("CID: ", rMsg.Msg.Cid, " TASK: ", rMsg.Msg.Tasklab.Taskid, " FACE TRACK OBJS: ", len(faces))
//
//            facePos := protomsg.ParamFacePos{Faces: faces}
//            data, err = proto.Marshal(&facePos)
//            if err != nil {
//               logo.Errorln("fdetect marshal proto face pos error", err)
//               data = nil
//            }
//         }
//
//         // logo.Infoln("CURRENT INDEX: ",rMsg.Msg.Tasklab.Index)
//         rMsg.BGRImg = &img
//         ejectResult(data, rMsg, out)
//
//         sc++
//         if sc == 25 {
//            logo.Infoln("FACE RUN 25 FRAME USE TIME: ", time.Since(tm))
//            sc = 0
//            tm = time.Now()
//         }
//
//         if time.Since(tm) > time.Second {
//            logo.Infof("FACE RUN %d FRAME USE TIME: %v", sc, time.Since(tm))
//            sc = 0
//            tm = time.Now()
//         }
//
//      }
//   }
//}
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,
   }
}