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
|
}
|