package sdk import ( "analysis/goconv" "analysis/logo" "analysis/work" "context" "time" "basic.com/pubsub/protomsg.git" "basic.com/valib/gosdk.git" "github.com/gogo/protobuf/proto" ) func (y *YoloDetect) detectTrack(ctx context.Context, in <-chan work.MsgRS, out chan<- work.MsgRS, typ string) { y.tracker = make(map[string]*trackInfo) go y.work(ctx, out, typ) for { select { case <-ctx.Done(): return default: rMsg := <-in if !validRemoteMessage(rMsg, typ) { logo.Errorln("yolo validremotemessage invalid") ejectResult(nil, rMsg, out) continue } y.push(rMsg) } } } func (y *YoloDetect) push(data work.MsgRS) { y.cv.L.Lock() y.cache.PushBack(data) if y.cache.Len() > 12 { for i := 0; i < y.cache.Len(); { y.cache.Remove(y.cache.Front()) i = i + 2 } } // logo.Infof("push to cache count : %d\n", t.cache.Len()) y.cond = true y.cv.Signal() y.cv.L.Unlock() } func (y *YoloDetect) work(ctx context.Context, out chan<- work.MsgRS, typ string) { tm := time.Now() sc := 0 for { select { case <-ctx.Done(): goconv.Free() return default: y.cv.L.Lock() for !y.cond { y.cv.Wait() } rMsg := y.cache.Front().Value.(work.MsgRS) y.track(rMsg, out, typ) y.cache.Remove(y.cache.Front()) y.cond = false y.cv.L.Unlock() sc++ if sc == 25 { logo.Infoln("YOLO RUN 25 FRAME USE TIME: ", time.Since(tm)) sc = 0 tm = time.Now() } if time.Since(tm) > time.Second { logo.Infof("YOLO RUN %d FRAME USE TIME: %v", sc, time.Since(tm)) sc = 0 tm = time.Now() } } } } func (y *YoloDetect) track(rMsg work.MsgRS, out chan<- work.MsgRS, typ string) { ///////////////////////////////////////////// i := unpackImage(rMsg, typ) if i == nil || i.Data == nil || i.Width <= 0 || i.Height <= 0 { logo.Errorln("yolo image error: ", i) ejectResult(nil, rMsg, out) return } // 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) return } img := gosdk.SDKImage{Data: bgrData, Width: imgW, Height: imgH} v, ok := y.tracker[rMsg.Msg.Cid] if !ok { i := &trackInfo{} y.tracker[rMsg.Msg.Cid] = i v = i } allOrig, _ := gosdk.YoloDetectTrack2(y.yolo, v.lastTrackObjs, &v.lastTrackID, img, 0.4, 0) y.tracker[rMsg.Msg.Cid].lastTrackObjs = allOrig y.tracker[rMsg.Msg.Cid].lastTrackID = v.lastTrackID /// filter rules var allF []gosdk.CObjTrackInfo sdkid := rMsg.Msg.Tasklab.Sdkinfos[rMsg.Msg.Tasklab.Index].Ipcid for _, v := range allOrig { size := (v.ObjInfo.RcObj.Right - v.ObjInfo.RcObj.Left) * (v.ObjInfo.RcObj.Bottom - v.ObjInfo.RcObj.Top) if filter(rMsg.Msg.Tasklab.Taskid, sdkid, v.ObjInfo.Prob, 0, int(size)) { allF = append(allF, v) } } /// filter rules allO := allF // allO := allOrig var data []byte var err error if len(allO) > 0 { infos := convert2ProtoYoloTrack(allO, 1.0, 1.0) p := protomsg.ParamYoloObj{Infos: infos} // logo.Infoln("CID: ", rMsg.Msg.Cid, " TASK: ", rMsg.Msg.Tasklab.Taskid, " YOLO TRACK OBJS: ", len(infos)) data, err = proto.Marshal(&p) if err != nil { logo.Errorln("ydetect track marshal proto yolo obj error", err) data = nil } } ejectResult(data, rMsg, out) var id, name string 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 YOLO COUNT: ", len(allO)) } func convert2ProtoYoloTrack(obj []gosdk.CObjTrackInfo, fx, fy float64) []*protomsg.ObjInfo { ret := []*protomsg.ObjInfo{} for _, v := range obj { if fx < 1.0 || fy < 1.0 { v.ObjInfo.RcObj.Left = (int32)((float64)(v.ObjInfo.RcObj.Left) / fx) v.ObjInfo.RcObj.Right = (int32)((float64)(v.ObjInfo.RcObj.Right) / fx) v.ObjInfo.RcObj.Top = (int32)((float64)(v.ObjInfo.RcObj.Top) / fy) v.ObjInfo.RcObj.Bottom = (int32)((float64)(v.ObjInfo.RcObj.Bottom) / fy) } rect := protomsg.Rect{ Left: v.ObjInfo.RcObj.Left, Right: v.ObjInfo.RcObj.Right, Top: v.ObjInfo.RcObj.Top, Bottom: v.ObjInfo.RcObj.Bottom, } obj := protomsg.ObjInfo{ RcObj: &rect, Typ: v.ObjInfo.Typ, Prob: v.ObjInfo.Prob, ObjID: v.ID, } ret = append(ret, &obj) } return ret }