| | |
| | | package personTrack |
| | | package main |
| | | |
| | | import ( |
| | | "encoding/json" |
| | |
| | | "strconv" |
| | | "time" |
| | | |
| | | "basic.com/valib/logger.git" |
| | | "github.com/knetic/govaluate" |
| | | "nanomsg.org/go-mangos" |
| | | "nanomsg.org/go-mangos/protocol/req" |
| | | "nanomsg.org/go-mangos/transport/tcp" |
| | | "github.com/knetic/govaluate" |
| | | logger "github.com/alecthomas/log4go" |
| | | |
| | | "basic.com/pubsub/protomsg.git" |
| | | "ruleprocess/structure" |
| | | ) |
| | | |
| | | var sender chan []byte = make(chan []byte) |
| | | var receiver chan string = make(chan string) |
| | | var initFlag bool = false |
| | | var receiver chan map[string]interface{} = make(chan map[string]interface{}) |
| | | |
| | | var sock mangos.Socket |
| | | func Init() { |
| | | go Push() |
| | |
| | | |
| | | // 人体跟踪算法 |
| | | func Entrance(rule *protomsg.Rule, am *structure.AreaMap, lable *structure.Others, args *structure.SdkDatas, message *protomsg.SdkMessage) structure.LittleRuleResult { |
| | | if !initFlag { |
| | | Init() |
| | | } |
| | | |
| | | if rule.PolygonId == am.AreaId { // 首先这条规则得是这个算法的规则,其次规则所对应的区域id要跟区域数据的id对的上 |
| | | //logger.Debug("---------走了人员异常算法", rule.Id, rule.SdkArgAlias, rule.Operator, rule.SdkArgValue, am.AreaId) |
| | | if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" || rule.SdkArgAlias == "" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加 |
| | | return filterRule(rule, am) |
| | | } else if rule.SdkArgAlias == "threshold"{ |
| | | } else if rule.SdkArgAlias == "cmpThreshold"{ |
| | | return track(rule,am) |
| | | } |
| | | return structure.LittleRuleResult{} |
| | |
| | | } |
| | | am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段 |
| | | if am.TargetNum > 0 { |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort} |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort,am.FilterData} |
| | | } else { |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort} |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort,am.FilterData} |
| | | } |
| | | |
| | | } else if rule.SdkArgAlias == "" { |
| | | if am.TargetNum > 0 { |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort} |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort,am.FilterData} |
| | | } else { |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort} |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort,am.FilterData} |
| | | } |
| | | } |
| | | return structure.LittleRuleResult{} |
| | |
| | | trackArg := make(map[string]interface{}) |
| | | esId := uuid.NewV4().String() |
| | | trackArg["esId"] = esId |
| | | trackArg["threshold"] = compareThreshold |
| | | trackArg["cameraId"] = am.CameraId |
| | | trackArg["bodyFeature"] = arg.Feature |
| | | trackArg["faceFeature"] = arg.AttachArg.Feature |
| | | b,err := json.Marshal(trackArg) |
| | | if err != nil { |
| | | _ = logger.Error("json序列化错误", err) |
| | | logger.Error("json序列化错误", err) |
| | | } |
| | | dataId := getCompareMsg(b) |
| | | if esId == dataId { // 说明没比到相似的人 |
| | | logger.Info("没比到人") |
| | | arg.Uuid = dataId |
| | | result := getCompareMsg(b) |
| | | if esId == result["esId"].(string) || result["esId"].(string) == ""{ // 说明没比到相似的人,是新人 |
| | | logger.Info("没比到人,可以入库",am.CameraId) |
| | | arg.Uuid = esId |
| | | } else { |
| | | logger.Info("比对出来的dataId:",dataId) |
| | | base := structure.BaseInfo{TargetId:dataId} |
| | | arg.Liker = append(arg.Liker, &base) |
| | | if result["isHave"].(bool){ // 比到了相似的人且在此摄像机下已经出现过,最后不能插入数据库 |
| | | logger.Info("不许入库的数据",am.CameraId) |
| | | arg.Uuid = "" |
| | | } else { // 比到了相似的人但在此摄像机下未出现过,要插入数据库 |
| | | logger.Info("准备入库的数据",am.CameraId) |
| | | base := structure.BaseInfo{TargetId:result["esId"].(string)} |
| | | arg.Liker = append(arg.Liker, &base) |
| | | } |
| | | } |
| | | } |
| | | |
| | | func track (rule *protomsg.Rule,am *structure.AreaMap) structure.LittleRuleResult{ |
| | | var threshold float32 = 70 // 默认阈值为70 |
| | | defer func() { |
| | | if err := recover();err != nil { |
| | | logger.Error("追踪判断失败",err) |
| | | } |
| | | }() |
| | | var threshold float32 = 60 // 默认阈值为70 |
| | | if th,err := strconv.ParseFloat(rule.SdkArgValue,32); err == nil { |
| | | threshold = float32(th) |
| | | } |
| | | for _, arg := range am.FilterData { |
| | | fillLiker(threshold,arg,am) |
| | | //logger.Info("比完之后的数据追踪数据是:",arg) |
| | | //if len(arg.Liker) == 0 { |
| | | // // 如果没有相似者则删除本目标数据 |
| | | // am.FilterData = append(am.FilterData[:i],am.FilterData[i+1:]...) |
| | |
| | | // return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort} |
| | | //} |
| | | // 无论有没有相似者都要返回true |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort} |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort,nil} |
| | | } |
| | | |
| | | func Push(){ |
| | | var err error |
| | | var msg []byte |
| | | |
| | | logger.Info("追踪请求通道建立") |
| | | if sock, err = req.NewSocket(); err != nil { |
| | | _ = logger.Error("创建请求socket失败: %s", err.Error()) |
| | | logger.Error("创建请求socket失败: %s", err.Error()) |
| | | } |
| | | errSize := sock.SetOption(mangos.OptionMaxRecvSize,5*1024*1024) |
| | | errSize := sock.SetOption(mangos.OptionMaxRecvSize,20*1024*1024) |
| | | if errSize != nil { |
| | | _ = logger.Error("Failed set MaxRecvSize: %v", err) |
| | | logger.Error("Failed set MaxRecvSize: %v", err) |
| | | } |
| | | errTimeOut := sock.SetOption(mangos.OptionRecvDeadline,time.Millisecond * 1500) |
| | | if errTimeOut != nil { |
| | | logger.Error("接收响应超时") |
| | | return |
| | | } |
| | | errTimeOut1 := sock.SetOption(mangos.OptionSendDeadline,time.Millisecond * 1500) |
| | | if errTimeOut1 != nil { |
| | | logger.Error("发送超时") |
| | | return |
| | | } |
| | | //sock.AddTransport(ipc.NewTransport()) |
| | | sock.AddTransport(tcp.NewTransport()) |
| | | serverIP, _ := GetLocalIP() |
| | | if err = sock.Dial("tcp://"+serverIP+":4010"); err != nil { |
| | | _ = logger.Error("请求socket拨号失败: %s", err.Error()) |
| | | if err = sock.Dial("tcp://"+serverIP+":4012"); err != nil { |
| | | logger.Error("请求socket拨号失败: %s", err.Error()) |
| | | } |
| | | logger.Info("序列化数据") |
| | | initFlag = true |
| | | |
| | | for { |
| | | select { |
| | | case data := <- sender: |
| | | logger.Debug("推送数据:",len(data)) |
| | | //trackMap := make(map[string]interface{}) |
| | | //_ = json.Unmarshal(data, &trackMap) |
| | | //logger.Info("请求张增飞比对数据参数:",trackMap) |
| | | if err = sock.Send(data); err != nil { |
| | | _ = logger.Error("推送socket发送数据失败: %s", err.Error()) |
| | | logger.Error("推送socket发送数据失败: %s", err.Error()) |
| | | } |
| | | if msg, err = sock.Recv(); err != nil { |
| | | _ = logger.Error("接收响应失败: %s", err.Error()) |
| | | logger.Error("接收响应失败: %s", err.Error()) |
| | | } |
| | | logger.Debug("数据推送成功!收到响应,数据长度为:",len(msg)) |
| | | receiver <- string(msg) |
| | | recive := make(map[string]interface{}) |
| | | _ = json.Unmarshal(msg,&recive) |
| | | receiver <- recive |
| | | default: |
| | | time.Sleep(time.Millisecond * 10) |
| | | } |
| | | } |
| | | } |
| | | |
| | | func getCompareMsg(data []byte) string{ |
| | | func getCompareMsg(data []byte) map[string]interface{}{ |
| | | sender <- data |
| | | return <- receiver |
| | | } |