From 2f5f0c75f3257b4ea9c37df6d02e5598b975740f Mon Sep 17 00:00:00 2001
From: zhangmeng <775834166@qq.com>
Date: 星期三, 11 十二月 2019 17:10:27 +0800
Subject: [PATCH] copy from VAProcess

---
 work/sdk/ydetect.go |  184 ++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 169 insertions(+), 15 deletions(-)

diff --git a/work/sdk/ydetect.go b/work/sdk/ydetect.go
index fadf272..737b41a 100644
--- a/work/sdk/ydetect.go
+++ b/work/sdk/ydetect.go
@@ -5,35 +5,48 @@
 	"analysis/work"
 	"container/list"
 	"context"
+	"fmt"
+	"plugin"
 	"sync"
+	"time"
 
+	"basic.com/libgowrapper/sdkstruct.git"
+	"basic.com/pubsub/protomsg.git"
 	"basic.com/valib/gogpu.git"
-
-	"basic.com/valib/gosdk.git"
+	"github.com/gogo/protobuf/proto"
 )
-
-type trackInfo struct {
-	lastTrackObjs []gosdk.CObjTrackInfo
-	lastTrackID   uint64
-}
 
 // YoloDetect yolo detect
 type YoloDetect struct {
-	yolo    *gosdk.YoloHandle
 	iGPU    int
 	cfg     string
 	weights string
 	name    string
 
-	tracker map[string]*trackInfo
-
 	cache *list.List
 	cv    *sync.Cond
 	cond  bool
+
+	handle interface{}
+	fnInit func(string, string, string, int) interface{}
+	fnFree func(interface{})
+	fnRun  func(interface{}, string, []byte, int, int, int, float32, int) ([]sdkstruct.CObjTrackInfo, []sdkstruct.CObjTrackInfo)
 }
 
 // NewYDetectWithTrack with track
 func NewYDetectWithTrack(gi int, cfg, weights, name string) *YoloDetect {
+	soFile := "libyolo.so"
+
+	plug, err := plugin.Open(soFile)
+	if err != nil {
+		logo.Errorln("Open: ", soFile, " error: ", err)
+		return nil
+	}
+
+	fnInit, _ := LoadFunc(plug, soFile, "NewSDK")
+	fnFree, _ := LoadFunc(plug, soFile, "Free")
+	fnRun, _ := LoadFunc(plug, soFile, "Run")
+
 	return &YoloDetect{
 		iGPU:    gi,
 		cfg:     cfg,
@@ -42,6 +55,11 @@
 		cache:   list.New(),
 		cv:      sync.NewCond(&sync.Mutex{}),
 		cond:    false,
+
+		handle: nil,
+		fnInit: fnInit.(func(string, string, string, int) interface{}),
+		fnFree: fnFree.(func(interface{})),
+		fnRun:  fnRun.(func(interface{}, string, []byte, int, int, int, float32, int) ([]sdkstruct.CObjTrackInfo, []sdkstruct.CObjTrackInfo)),
 	}
 }
 
@@ -52,19 +70,155 @@
 	if gpu == -1 {
 		gpu = gogpu.ValidGPU(2048)
 	}
-	yolo := gosdk.InitYolo(y.cfg, y.weights, y.name, gpu)
-	logo.Infoln("yolo use gpu: ", gpu)
+	h := y.fnInit(y.cfg, y.weights, y.name, gpu)
+	logo.Infoln("YOLO USE GPU: ", gpu)
 
-	if yolo == nil {
+	if h == nil {
+		logo.Errorln("CREATE YOLO DETECTOR ERROR")
 		return false
 	}
 
-	y.yolo = yolo
+	y.handle = h
 	return true
 }
 
 // Run impl interface
 func (y *YoloDetect) Run(ctx context.Context, in <-chan work.MsgRS, out chan<- work.MsgRS, typ string) {
-	y.detectTrack(ctx, in, out, typ)
+	go y.work(ctx, out, typ)
 
+	for {
+		select {
+		case <-ctx.Done():
+			y.fnFree(y.handle)
+			return
+		default:
+			rMsg := <-in
+			if !validRemoteMessage(rMsg, typ) {
+				logo.Errorln("yolo validremotemessage invalid")
+				ejectResult(nil, rMsg, out)
+				continue
+			}
+			y.push(rMsg)
+		}
+	}
+
+}
+
+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
+	}
+
+	imgW, imgH := int(i.Width), int(i.Height)
+
+	whole, recent := y.fnRun(y.handle, rMsg.Msg.Cid, i.Data, imgW, imgH, 3, 0.4, 0)
+	if len(recent) > 0 {
+	}
+
+	infos := convert2ProtoYoloTrack(whole, 1.0, 1.0)
+	p := protomsg.ParamYoloObj{Infos: infos}
+
+	data, err := proto.Marshal(&p)
+	if err != nil {
+		fmt.Println("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(whole))
+}
+
+func convert2ProtoYoloTrack(obj []sdkstruct.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
+}
+
+func (y *YoloDetect) work(ctx context.Context, out chan<- work.MsgRS, typ string) {
+	tm := time.Now()
+	sc := 0
+
+	for {
+		select {
+		case <-ctx.Done():
+			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) 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()
 }

--
Gitblit v1.8.0