| | |
| | | resultSplice := []*structure.LittleRuleResult{} |
| | | sdkNames := "" |
| | | polygonId := "" |
| | | // 这步过的是时间段规则(时间段等) |
| | | for j := 0; j < len(groupRule.Rules); j++ { |
| | | for _, sdkData := range args.Sdkdata { |
| | | sdk, err := cache.GetSdkById(groupRule.Rules[j].SdkId) |
| | | if err != nil { |
| | | logger.Error("没查到sdk的信息---", err) |
| | | } |
| | | ipcId := sdk.IpcId |
| | | sdkName := sdk.SdkName |
| | | if ipcId == sdkData.IpcId { |
| | | for _, areaMap := range sdkData.AreaMapList { |
| | | ruleResult := timeRuleResult(groupRule.Rules[j], areaMap) |
| | | if ruleResult.Result != "" { |
| | | if strings.Contains(ruleResult.Result, "false") { |
| | | return false,"","" // 不符合时间规则的话直接返回,不再浪费时间 |
| | | } |
| | | if strings.Contains(ruleResult.Result, "true") { |
| | | areaMap.IsEffective = true |
| | | } |
| | | //logger.Info("时间规则结果:", ruleResult.Result) |
| | | if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) { |
| | | sdkNames = sdkName + " " |
| | | } |
| | | if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(polygonId, groupRule.Rules[j].PolygonId) { |
| | | polygonId += groupRule.Rules[j].PolygonId + "," |
| | | } |
| | | resultSplice = append(resultSplice, &ruleResult) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 先过完条件规则 |
| | | for j := 0; j < len(groupRule.Rules); j++ { |
| | | |
| | |
| | | } |
| | | } |
| | | } |
| | | // 跨摄像机跟踪 |
| | | for j := 0; j < len(groupRule.Rules); j++ { |
| | | if groupRule.Rules[j].SdkId == "人体跟踪" && groupRule.Rules[j].SdkArgAlias != "灵魂参数"{ |
| | | for _, sdkData := range args.Sdkdata { |
| | | // 根据规则的sdkId查出其对应的ipcId,用ipcId去找该比对的数据 |
| | | sdk, err := cache.GetSdkById(groupRule.Rules[j].SdkId) |
| | | if err != nil { |
| | | _ = logger.Error("没查到sdk的信息---", err) |
| | | } |
| | | ipcId := sdk.IpcId |
| | | sdkName := sdk.SdkName |
| | | //logger.Info("规则的ipcId与sdkData的IpcId:", ipcId, "===", sdkData.IpcId) |
| | | if ipcId == sdkData.IpcId { |
| | | //logger.Info("当前走的规则是--:", groupRule.Rules[j],sdkName,groupRule.Rules[j].SdkArgAlias, "---","") |
| | | for _, areaMap := range sdkData.AreaMapList { |
| | | ruleResult := CallSo(sdk.Id, groupRule.Rules[j], areaMap,lable,args,message) |
| | | if ruleResult.Result != "" { |
| | | //logger.Info("车牌结果:", ruleResult.Result) |
| | | // 如果结果为真,把这条规则中的区域置为有效 |
| | | if strings.Contains(ruleResult.Result, "true") { |
| | | areaMap.IsEffective = true |
| | | } |
| | | // 如果此结果为真且当前过的是yolo算法,应记下此规则所对应的sdkName,另外,还要去重 (后加:把此条触碰的区域id也记录下来) |
| | | if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) { |
| | | sdkNames = sdkName + " " |
| | | } |
| | | if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(polygonId, groupRule.Rules[j].PolygonId) { |
| | | polygonId += groupRule.Rules[j].PolygonId + "," |
| | | } |
| | | resultSplice = append(resultSplice, &ruleResult) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 再过其他数据 这步直接得到结果(真或假) 过目标数量 |
| | | for j := 0; j < len(groupRule.Rules); j++ { |
| | | if groupRule.Rules[j].SdkArgAlias == "objCount" { |
| | |
| | | } |
| | | } |
| | | } |
| | | // 这步过的是时间段规则(时间段等) |
| | | for j := 0; j < len(groupRule.Rules); j++ { |
| | | for _, sdkData := range args.Sdkdata { |
| | | sdk, err := cache.GetSdkById(groupRule.Rules[j].SdkId) |
| | | if err != nil { |
| | | logger.Error("没查到sdk的信息---", err) |
| | | } |
| | | ipcId := sdk.IpcId |
| | | sdkName := sdk.SdkName |
| | | if ipcId == sdkData.IpcId { |
| | | for _, areaMap := range sdkData.AreaMapList { |
| | | ruleResult := timeRuleResult(groupRule.Rules[j], areaMap) |
| | | if ruleResult.Result != "" { |
| | | if strings.Contains(ruleResult.Result, "true") { |
| | | areaMap.IsEffective = true |
| | | } |
| | | //logger.Info("时间规则结果:", ruleResult.Result) |
| | | if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) { |
| | | sdkNames = sdkName + " " |
| | | } |
| | | if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(polygonId, groupRule.Rules[j].PolygonId) { |
| | | polygonId += groupRule.Rules[j].PolygonId + "," |
| | | } |
| | | resultSplice = append(resultSplice, &ruleResult) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 将数组按sort排序 |
| | | sort.Sort(ruleserver.ResultList(resultSplice)) |
| | | // 排序后取各自的结果和连接符拼出规则表达式得出结果 |
| | |
| | | soName = "static.so" |
| | | } else if sdkId == "812b674b-2375-4589-919a-5c1c3278a978" { |
| | | soName = "plate.so" |
| | | } else if sdkId == "人体跟踪" { |
| | | soName = "personTrack.so" |
| | | } |
| | | //soInfo,errr := cache.GetSoInfoById(sdkId) |
| | | //if errr != nil { |
| | | //soInfo,err := cache.GetSoInfoById(sdkId) |
| | | //if err != nil { |
| | | // panic("没读到注册表") |
| | | //} |
| | | //soName := soInfo.SoName |
| | |
| | | // 这步要备齐表达式里所需要的所有参数 |
| | | a.TargetNum++ |
| | | uuid := uuid.NewV4().String() |
| | | arg1 := structure.Arg{obj.Id,uuid,obj.Score, ruleserver.PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), float64(obj.Rects.Width * obj.Rects.Height), a.AreaJson,obj.Type, obj.Rects, obj.Car,obj.Feature, obj.ThftRes, []*structure.BaseInfo{},"",structure.ResultMsg{}} |
| | | arg1 := structure.Arg{structure.SourceArg{obj.Id,uuid,obj.Score, ruleserver.PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), float64(obj.Rects.Width * obj.Rects.Height), a.AreaJson,obj.Type, obj.Rects, obj.Car,obj.Feature,obj.ThftRes, []*structure.BaseInfo{},"",structure.ResultMsg{}},structure.SourceArg{}} |
| | | //logger.Println("放进去的arg:-------", arg1) |
| | | a.Args = append(a.Args, &arg1) |
| | | a.FilterData = append(a.FilterData, &arg1) |
| | |
| | | logger.Info("接到数据,摄像机为:", m.Cid, "图片的id为:", i.Id) |
| | | //logger.Info("----------------看看有几个算法:",len(m.Tasklab.Sdkinfos)) |
| | | for _, sdkinfo := range m.Tasklab.Sdkinfos { // yolo算法 |
| | | if sdkinfo.Sdktype == "Yolo" { |
| | | arg := structure.SdkData{} |
| | | arg.TaskId = m.Tasklab.Taskid |
| | | arg.IpcId = sdkinfo.Ipcid |
| | | arg.IsYolo = true |
| | | arg.ImageWidth = int(i.Width) |
| | | arg.ImageHeight = int(i.Height) |
| | | logger.Info("-----追踪之后sdkinfo.Sdkdata的长度为:----", len(sdkinfo.Sdkdata)) |
| | | if len(sdkinfo.Sdkdata) > 1 { |
| | | // 大于1才有数据 |
| | | yoloParam := protomsg.ParamYoloObj{} |
| | | err = proto.Unmarshal(sdkinfo.Sdkdata, &yoloParam) |
| | | if err != nil { |
| | | logger.Info("解析YOLO sdk数据时出现错误", err) |
| | | continue |
| | | } |
| | | var yoloNum int = 0 |
| | | for _, info := range yoloParam.Infos { |
| | | if info.Typ == 0 { |
| | | //logger.Debug("-------------yolo的坐标有几个",info.RcObj) |
| | | photoMap := structure.PhotoMap{Rects: rectFormat(info.RcObj), Score: float64(info.Prob) * 100, Type: "yolo",Id:strconv.Itoa(int(info.ObjID))} |
| | | arg.Photo = append(arg.Photo, photoMap) |
| | | yoloNum++ |
| | | } |
| | | } |
| | | logger.Info("--------------追踪之后yolo的个数:", yoloNum) |
| | | args.Sdkdata = append(args.Sdkdata, &arg) |
| | | } else { |
| | | continue |
| | | } |
| | | |
| | | } |
| | | if sdkinfo.Sdktype == "FaceDetect" { // 人脸检测 |
| | | arg := structure.SdkData{} |
| | | arg.TaskId = m.Tasklab.Taskid |
| | | arg.IpcId = sdkinfo.Ipcid |
| | | arg.IsYolo = false |
| | | arg.ImageWidth = int(i.Width) |
| | | arg.ImageHeight = int(i.Height) |
| | | if len(sdkinfo.Sdkdata) > 1 { |
| | | faceParam := protomsg.ParamFacePos{} |
| | | err = proto.Unmarshal(sdkinfo.Sdkdata, &faceParam) |
| | | if err != nil { |
| | | logger.Info("解析FACE sdk数据时出现错误", err) |
| | | continue |
| | | } |
| | | logger.Info("--------------追踪之后人脸的个数:", len(faceParam.Faces)) |
| | | for _, info := range faceParam.Faces { |
| | | //logger.Info("_______________________________________________第一次看相似值:",info.Pos.FAngle.Confidence*100) |
| | | photoMap := structure.PhotoMap{Id: strconv.Itoa(int(info.Pos.FaceID)) , Rects: rectFormat(info.Pos.RcFace), Score: float64(info.Pos.FAngle.Confidence * 100), Type: "face", ThftRes: *(info.Result), Feature: info.Feats} |
| | | arg.Photo = append(arg.Photo, photoMap) |
| | | } |
| | | args.Sdkdata = append(args.Sdkdata, &arg) |
| | | } else { |
| | | continue |
| | | } |
| | | } |
| | | if sdkinfo.Sdktype == "Plate" { // 车牌识别 |
| | | arg := structure.SdkData{} |
| | | arg.TaskId = m.Tasklab.Taskid |
| | | logger.Info("车牌的ipcid:",sdkinfo.Ipcid) |
| | | arg.IpcId = sdkinfo.Ipcid |
| | | arg.IsYolo = false |
| | | arg.ImageWidth = int(i.Width) |
| | | arg.ImageHeight = int(i.Height) |
| | | if len(sdkinfo.Sdkdata) > 1 { |
| | | plateIDResult := protomsg.PlateIDResult {} |
| | | err = proto.Unmarshal(sdkinfo.Sdkdata, &plateIDResult ) |
| | | if err != nil { |
| | | logger.Info("解析车牌数据时出现错误", err) |
| | | continue |
| | | } |
| | | for _, info := range plateIDResult.Result { |
| | | logger.Info("接收车牌数据:",info.FvdConf,info.NVehicleColor1,info.NPlateFlag,info.RcCarLocation) |
| | | if info.NConfidence > 70 { |
| | | logger.Info("车牌也符合的数据",info.FvdConf,info.NVehicleColor1,info.NPlateFlag,info.RcCarLocation,info.NConfidence,) |
| | | photoMap := structure.PhotoMap{Id: info.License,Score: float64(info.FvdConf)*100,Rects: rectFormat(info.RcCarLocation), Type: "plate", Car:info} |
| | | arg.Photo = append(arg.Photo, photoMap) |
| | | } |
| | | } |
| | | args.Sdkdata = append(args.Sdkdata, &arg) |
| | | } else { |
| | | continue |
| | | } |
| | | switch sdkinfo.Sdktype { |
| | | case "Yolo": |
| | | extractYolo(args,m,sdkinfo,i) |
| | | case "FaceDetect": |
| | | extractFace(args,m,sdkinfo,i) |
| | | case "Plate": |
| | | extractCar(args,m,sdkinfo,i) |
| | | case "Track": |
| | | extractTrack(args,m,sdkinfo,i) |
| | | } |
| | | } |
| | | return m |
| | | } |
| | | |
| | | // 把人脸放进对应的人体 |
| | | func FacePush2Body () { |
| | | |
| | | } |
| | | // 提取face |
| | | func extractFace(args *structure.SdkDatas,m protomsg.SdkMessage,sdkinfo *protomsg.SdkmsgWithTask,i protomsg.Image) { |
| | | arg := structure.SdkData{} |
| | | arg.TaskId = m.Tasklab.Taskid |
| | | arg.IpcId = sdkinfo.Ipcid |
| | | arg.IsYolo = false |
| | | arg.ImageWidth = int(i.Width) |
| | | arg.ImageHeight = int(i.Height) |
| | | if len(sdkinfo.Sdkdata) > 1 { |
| | | faceParam := protomsg.ParamFacePos{} |
| | | err := proto.Unmarshal(sdkinfo.Sdkdata, &faceParam) |
| | | if err != nil { |
| | | logger.Info("解析FACE sdk数据时出现错误", err) |
| | | return |
| | | } |
| | | logger.Info("--------------追踪之后人脸的个数:", len(faceParam.Faces)) |
| | | for _, info := range faceParam.Faces { |
| | | //logger.Info("_______________________________________________第一次看相似值:",info.Pos.FAngle.Confidence*100) |
| | | photoMap := structure.PhotoMap{Id: strconv.Itoa(int(info.Pos.FaceID)) , Rects: rectFormat(info.Pos.RcFace), Score: float64(info.Pos.FAngle.Confidence * 100), Type: "face", ThftRes: *(info.Result), Feature: info.Feats} |
| | | arg.Photo = append(arg.Photo, photoMap) |
| | | } |
| | | args.Sdkdata = append(args.Sdkdata, &arg) |
| | | } |
| | | } |
| | | // 提取yolo |
| | | func extractYolo(args *structure.SdkDatas,m protomsg.SdkMessage,sdkinfo *protomsg.SdkmsgWithTask,i protomsg.Image) { |
| | | arg := structure.SdkData{} |
| | | arg.TaskId = m.Tasklab.Taskid |
| | | arg.IpcId = sdkinfo.Ipcid |
| | | arg.IsYolo = true |
| | | arg.ImageWidth = int(i.Width) |
| | | arg.ImageHeight = int(i.Height) |
| | | logger.Info("-----追踪之后sdkinfo.Sdkdata的长度为:----", len(sdkinfo.Sdkdata)) |
| | | if len(sdkinfo.Sdkdata) > 1 { |
| | | // 大于1才有数据 |
| | | yoloParam := protomsg.ParamYoloObj{} |
| | | err := proto.Unmarshal(sdkinfo.Sdkdata, &yoloParam) |
| | | if err != nil { |
| | | logger.Info("解析YOLO sdk数据时出现错误", err) |
| | | return |
| | | } |
| | | var yoloNum int = 0 |
| | | for _, info := range yoloParam.Infos { |
| | | if info.Typ == 0 { |
| | | //logger.Debug("-------------yolo的坐标有几个",info.RcObj) |
| | | photoMap := structure.PhotoMap{Rects: rectFormat(info.RcObj), Score: float64(info.Prob) * 100, Type: "yolo",Id:strconv.Itoa(int(info.ObjID))} |
| | | arg.Photo = append(arg.Photo, photoMap) |
| | | yoloNum++ |
| | | } |
| | | } |
| | | logger.Info("--------------追踪之后yolo的个数:", yoloNum) |
| | | args.Sdkdata = append(args.Sdkdata, &arg) |
| | | } else { |
| | | return |
| | | } |
| | | } |
| | | |
| | | // 提取car |
| | | func extractCar(args *structure.SdkDatas,m protomsg.SdkMessage,sdkinfo *protomsg.SdkmsgWithTask,i protomsg.Image) { |
| | | arg := structure.SdkData{} |
| | | arg.TaskId = m.Tasklab.Taskid |
| | | arg.IpcId = sdkinfo.Ipcid |
| | | arg.IsYolo = false |
| | | arg.ImageWidth = int(i.Width) |
| | | arg.ImageHeight = int(i.Height) |
| | | if len(sdkinfo.Sdkdata) > 1 { |
| | | plateIDResult := protomsg.PlateIDResult {} |
| | | err := proto.Unmarshal(sdkinfo.Sdkdata, &plateIDResult ) |
| | | if err != nil { |
| | | logger.Info("解析车牌数据时出现错误", err) |
| | | return |
| | | } |
| | | for _, info := range plateIDResult.Result { |
| | | logger.Info("接收车牌数据:",info.FvdConf,info.NVehicleColor1,info.NPlateFlag,info.RcCarLocation) |
| | | if info.NConfidence > 70 { |
| | | logger.Info("车牌也符合的数据",info.FvdConf,info.NVehicleColor1,info.NPlateFlag,info.RcCarLocation,info.NConfidence,) |
| | | photoMap := structure.PhotoMap{Id: info.License,Score: float64(info.FvdConf)*100,Rects: rectFormat(info.RcCarLocation), Type: "plate", Car:info} |
| | | arg.Photo = append(arg.Photo, photoMap) |
| | | } |
| | | } |
| | | args.Sdkdata = append(args.Sdkdata, &arg) |
| | | } else { |
| | | return |
| | | } |
| | | } |
| | | |
| | | // 提取跟踪 |
| | | func extractTrack(args *structure.SdkDatas,m protomsg.SdkMessage,sdkinfo *protomsg.SdkmsgWithTask,i protomsg.Image) { |
| | | arg := structure.SdkData{} |
| | | arg.TaskId = m.Tasklab.Taskid |
| | | arg.IpcId = sdkinfo.Ipcid |
| | | arg.IsYolo = false |
| | | arg.ImageWidth = int(i.Width) |
| | | arg.ImageHeight = int(i.Height) |
| | | if len(sdkinfo.Sdkdata) > 1 { |
| | | plateIDResult := protomsg.PlateIDResult {} |
| | | err := proto.Unmarshal(sdkinfo.Sdkdata, &plateIDResult ) |
| | | if err != nil { |
| | | logger.Info("解析跟踪目标数据时出现错误", err) |
| | | return |
| | | } |
| | | for _, info := range plateIDResult.Result { |
| | | logger.Info("接收车牌数据:",info.FvdConf,info.NVehicleColor1,info.NPlateFlag,info.RcCarLocation) |
| | | if info.NConfidence > 70 { |
| | | logger.Info("车牌也符合的数据",info.FvdConf,info.NVehicleColor1,info.NPlateFlag,info.RcCarLocation,info.NConfidence,) |
| | | photoMap := structure.PhotoMap{Id: info.License,Score: float64(info.FvdConf)*100,Rects: rectFormat(info.RcCarLocation), Type: "plate", Car:info} |
| | | arg.Photo = append(arg.Photo, photoMap) |
| | | } |
| | | } |
| | | args.Sdkdata = append(args.Sdkdata, &arg) |
| | | } else { |
| | | return |
| | | } |
| | | } |
New file |
| | |
| | | package personTrack |
| | | |
| | | import ( |
| | | "encoding/json" |
| | | "errors" |
| | | "net" |
| | | "strconv" |
| | | |
| | | "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 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"{ |
| | | return track(rule,am) |
| | | } |
| | | return structure.LittleRuleResult{} |
| | | } else { |
| | | return structure.LittleRuleResult{} |
| | | } |
| | | } |
| | | |
| | | // 过滤规则先筛选出符合条件的目标数量 |
| | | func filterRule(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult { |
| | | // 处理的都是yolo数据 |
| | | if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加 |
| | | var args []*structure.Arg |
| | | if rule.RuleWithPre == "&&" { |
| | | args = am.FilterData |
| | | } else { |
| | | args = am.Args |
| | | } |
| | | // 先清空过滤后的数据,再往里塞本次过滤后的数据 |
| | | am.FilterData = am.FilterData[0:0] |
| | | //logger.Debug("看看args:::::", args) |
| | | for _, arg := range args { |
| | | var formula string |
| | | switch rule.SdkArgAlias { |
| | | case "score": |
| | | formula = strconv.FormatFloat(arg.Score, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | //logger.Info("相似度小公式:", formula) |
| | | case "proportion": |
| | | formula = strconv.FormatFloat(arg.Proportion, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | //logger.Info("占比公式:", formula) |
| | | case "size": |
| | | formula = strconv.FormatFloat(arg.Size, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | //logger.Info("尺寸小公式:", formula) |
| | | } |
| | | expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式 |
| | | result, _ := expression.Evaluate(nil) // 得到数学公式的结果 |
| | | if result.(bool) { |
| | | am.FilterData = append(am.FilterData, arg) // 得到符合条件的过滤数据 |
| | | } |
| | | } |
| | | am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段 |
| | | if am.TargetNum > 0 { |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort} |
| | | } else { |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort} |
| | | } |
| | | |
| | | } else if rule.SdkArgAlias == "" { |
| | | if am.TargetNum > 0 { |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort} |
| | | } else { |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort} |
| | | } |
| | | } |
| | | return structure.LittleRuleResult{} |
| | | } |
| | | |
| | | // 给目标填充liker |
| | | func fillLiker(compareThreshold float32,arg *structure.Arg,am *structure.AreaMap) { |
| | | trackArg := make(map[string]interface{}) |
| | | trackArg["esId"] = "" |
| | | 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) |
| | | } |
| | | esId := getCompareMsg(b) |
| | | logger.Info("比对出来的esid:",esId) |
| | | base := structure.BaseInfo{TargetId:esId} |
| | | arg.Liker = append(arg.Liker, &base) |
| | | } |
| | | |
| | | func track (rule *protomsg.Rule,am *structure.AreaMap) structure.LittleRuleResult{ |
| | | var threshold float32 = 70 // 默认阈值为70 |
| | | if th,err := strconv.ParseFloat(rule.SdkArgValue,32); err == nil { |
| | | threshold = float32(th) |
| | | } |
| | | for i, arg := range am.FilterData { |
| | | fillLiker(threshold,arg,am) |
| | | if len(arg.Liker) == 0 { |
| | | // 如果没有相似者则删除本目标数据 |
| | | am.FilterData = append(am.FilterData[:i],am.FilterData[i+1:]...) |
| | | } |
| | | } |
| | | if len(am.FilterData) > 0 { |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort} |
| | | } else { |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort} |
| | | } |
| | | } |
| | | |
| | | func Push(){ |
| | | var err error |
| | | var msg []byte |
| | | |
| | | if sock, err = req.NewSocket(); err != nil { |
| | | _ = logger.Error("创建请求socket失败: %s", err.Error()) |
| | | } |
| | | errSize := sock.SetOption(mangos.OptionMaxRecvSize,5*1024*1024) |
| | | if errSize != nil { |
| | | _ = logger.Error("Failed set MaxRecvSize: %v", err) |
| | | } |
| | | //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()) |
| | | } |
| | | logger.Info("序列化数据") |
| | | initFlag = true |
| | | for { |
| | | select { |
| | | // case <-ctx.Done(): |
| | | // return |
| | | case data := <- sender: |
| | | |
| | | logger.Info("数据长度为:",len(data)) |
| | | |
| | | logger.Debug("推送数据") |
| | | if err = sock.Send(data); err != nil { |
| | | _ = logger.Error("推送socket发送数据失败: %s", err.Error()) |
| | | } |
| | | if msg, err = sock.Recv(); err != nil { |
| | | _ = logger.Error("接收响应失败: %s", err.Error()) |
| | | } |
| | | logger.Debug("数据推送成功!收到响应,数据长度为:",len(msg)) |
| | | receiver <- string(msg) |
| | | default: |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | func getCompareMsg(data []byte) string{ |
| | | sender <- data |
| | | return <- receiver |
| | | } |
| | | |
| | | // 获取本机ip |
| | | func GetLocalIP() (ipv4 string, err error) { |
| | | var ( |
| | | addrs []net.Addr |
| | | addr net.Addr |
| | | ipNet *net.IPNet // IP地址 |
| | | isIpNet bool |
| | | ) |
| | | // 获取所有网卡 |
| | | if addrs, err = net.InterfaceAddrs(); err != nil { |
| | | return |
| | | } |
| | | // 取第一个非lo的网卡IP |
| | | for _, addr = range addrs { |
| | | // 这个网络地址是IP地址: ipv4, ipv6 |
| | | if ipNet, isIpNet = addr.(*net.IPNet); isIpNet && !ipNet.IP.IsLoopback() { |
| | | // 跳过IPV6 |
| | | if ipNet.IP.To4() != nil { |
| | | ipv4 = ipNet.IP.String() // 192.168.1.1 |
| | | return |
| | | } |
| | | } |
| | | } |
| | | |
| | | err = errors.New("ipv4 not found") |
| | | return |
| | | } |
| | |
| | | github.com/jeanphorn/log4go v0.0.0-20190526082429-7dbb8deb9468 // indirect |
| | | github.com/kirinlabs/HttpRequest v0.1.5 // indirect |
| | | github.com/knetic/govaluate v3.0.0+incompatible |
| | | github.com/panjf2000/ants/v2 v2.2.2 // indirect |
| | | github.com/pierrec/lz4 v2.2.3+incompatible |
| | | github.com/satori/go.uuid v1.2.0 |
| | | github.com/spf13/viper v1.4.0 |
| | |
| | | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= |
| | | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= |
| | | github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= |
| | | github.com/panjf2000/ants/v2 v2.2.2 h1:TWzusBjq/IflXhy+/S6u5wmMLCBdJnB9tPIx9Zmhvok= |
| | | github.com/panjf2000/ants/v2 v2.2.2/go.mod h1:1GFm8bV8nyCQvU5K4WvBCTG1/YBFOD2VzjffD8fV55A= |
| | | github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= |
| | | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= |
| | | github.com/pierrec/lz4 v2.2.3+incompatible h1:YpgKDCFg5dd0Eb+XlgrfJtH4fAqoRA1kBcKnBZ4EFSE= |
| | |
| | | package insertdata |
| | | |
| | | import ( |
| | | logger "github.com/alecthomas/log4go" |
| | | "encoding/base64" |
| | | "encoding/json" |
| | | "errors" |
| | | "net" |
| | | "ruleprocess/cache" |
| | | "ruleprocess/structure" |
| | | "strconv" |
| | | "time" |
| | | |
| | | "basic.com/pubsub/protomsg.git" |
| | | "github.com/golang/protobuf/proto" |
| | | "github.com/satori/go.uuid" |
| | | logger "github.com/alecthomas/log4go" |
| | | |
| | | "ruleprocess/cache" |
| | | "ruleprocess/structure" |
| | | "basic.com/pubsub/protomsg.git" |
| | | "ruleprocess/ruleserver" |
| | | "ruleprocess/util" |
| | | ) |
| | |
| | | ServerIp string `yaml:"serverIp"` |
| | | ServerPort string `yaml:"serverPort"` |
| | | DbTablePersons string `yaml:"dbTablePersons"` |
| | | } |
| | | |
| | | //func InitInsertEs() { |
| | | // weedfsUrl = "http://"+WeedFs.Ip+":"+strconv.Itoa(WeedFs.UploadPort)+"/submit" |
| | | // videoPersonUrl = "http://"+EsInfo.Masterip+":"+EsInfo.Httpport+"/"+EsInfo.EsIndex.VideoPersons.IndexName+"/"+EsInfo.EsIndex.VideoPersons.IndexType |
| | | // personAction = "http://"+EsInfo.Masterip+":"+EsInfo.Httpport+"/"+EsInfo.EsIndex.Personaction.IndexName+"/"+EsInfo.EsIndex.Personaction.IndexType |
| | | //} |
| | | |
| | | // 人脸的数据结构 |
| | | type PerVideoPicture struct { |
| | | Id string `json:"id"` |
| | | CameraId string `json:"cameraId"` |
| | | CameraAddr string `json:"cameraAddr"` |
| | | CameraName string `json:"cameraName"` |
| | | PicDate string `json:"picDate"` |
| | | PicMaxUrl []string `json:"picMaxUrl"` |
| | | TaskId string `json:"taskId"` |
| | | TaskName string `json:"taskName"` |
| | | SdkName string `json:"sdkName"` |
| | | Content string `json:"content"` |
| | | AlarmRules []AlarmRule `json:"alarmRules"` |
| | | LikeDate string `json:"likeDate"` |
| | | ShowLabels string `json:"showLabels"` |
| | | OtherLabels string `json:"otherLabels"` |
| | | VideoUrl string `json:"videoUrl"` |
| | | AnalyServerId string `json:"analyServerId"` |
| | | AnalyServerName string `json:"analyServerName"` |
| | | AnalyServerIp string `json:"analyServerIp"` |
| | | ClusterId string `json:"clusterId"` |
| | | IsAlarm bool `json:"isAlarm"` |
| | | IsAckAlarm bool `json:"isAckAlarm"` |
| | | IsCollect bool `json:"isCollect"` |
| | | IsDelete bool `json:"isDelete"` |
| | | BaseInfo []*structure.BaseInfo `json:"baseInfo"` |
| | | TargetInfo []Target `json:"targetInfo"` |
| | | LinkTag string `json:"linkTag"` |
| | | LinkTagInfo []*LinkInfo `json:"linkTagInfo"` |
| | | } |
| | | |
| | | type LinkInfo struct { |
| | |
| | | TargetInfo []Target `json:"targetInfo"` |
| | | } |
| | | |
| | | type Target struct { |
| | | // 统一的数据结构 |
| | | type PerVideoPicture struct { |
| | | LinkInfo |
| | | LinkTag string `json:"linkTag"` |
| | | LinkTagInfo []*LinkInfo `json:"linkTagInfo"` |
| | | } |
| | | |
| | | type SourceTarget struct { |
| | | TargetId string `json:"targetId"` |
| | | TargetScore float64 `json:"targetScore"` |
| | | TargetType string `json:"targetType"` |
| | | Feature string `json:"feature"` |
| | | PicSmUrl string `json:"picSmUrl"` |
| | | TargetLocation Points `json:"targetLocation"` |
| | | } |
| | | type Target struct { |
| | | SourceTarget |
| | | AttachTarget SourceTarget |
| | | } |
| | | |
| | | type Points struct { |
| | |
| | | panic("配置文件不合法") |
| | | } |
| | | weedfsUrl = "http://" + localConfig1.WebPicIp + ":" + strconv.Itoa(int(localConfig1.WebPicPort)) + "/submit" |
| | | videoPersonUrl = "http://" + localConfig1.AlarmIp + ":" + strconv.Itoa(int(localConfig1.AlarmPort)) + "/" + EsInfo.EsIndex.AIOcean.IndexName + "/" + EsInfo.EsIndex.AIOcean.IndexType |
| | | videoPersonUrl = "http://" + localConfig1.AlarmIp + ":" + strconv.Itoa(int(localConfig1.AlarmPort)) + "/" + EsInfo.EsIndex.AIOcean.IndexName + "/" + EsInfo.EsIndex.AIOcean.IndexType+"?refresh=true" |
| | | InsertFace(msg) |
| | | InsertYolo(msg) |
| | | InsertTarget(msg) |
| | |
| | | |
| | | // 往es中插入人脸类型数据 |
| | | func InsertFace(msg structure.ResultMsg) { |
| | | if (msg.RuleResult["face"] != nil && len(msg.RuleResult["face"].([]structure.Result)) > 0) || (msg.RuleResult["plate"] != nil && len(msg.RuleResult["plate"].([]structure.Result)) > 0) { |
| | | if (msg.RuleResult["face"] != nil && len(msg.RuleResult["face"].([]structure.Result)) > 0) || (msg.RuleResult["plate"] != nil && len(msg.RuleResult["plate"].([]structure.Result)) > 0) || (msg.RuleResult["track"] != nil && len(msg.RuleResult["track"].([]structure.Result)) > 0) { |
| | | for key, results := range msg.RuleResult { |
| | | if key == "face" || key == "plate" { |
| | | if key == "face" || key == "plate" || key == "track"{ |
| | | logger.Info("往ES插人脸数据(或车牌数据)") |
| | | faces := []*ObjAndRules{} |
| | | faces = PutFace(faces, results.([]structure.Result)) |
| | |
| | | target.Feature = base64.StdEncoding.EncodeToString(face.Feature) |
| | | target.PicSmUrl = resp["fileUrl"].(string) |
| | | target.TargetLocation = Points{TopLeft: Point{face.Location.X, face.Location.Y}, BottomRight: Point{face.Location.X + face.Location.Width, face.Location.Y + face.Location.Height}} |
| | | target.AttachTarget = SourceTarget{face.AttachArg.Id,face.AttachArg.Score,face.AttachArg.Type,base64.StdEncoding.EncodeToString(face.AttachArg.Feature),"",Points{TopLeft: Point{face.AttachArg.Location.X, face.AttachArg.Location.Y}, BottomRight: Point{face.AttachArg.Location.X + face.AttachArg.Location.Width, face.AttachArg.Location.Y + face.AttachArg.Location.Height}}} |
| | | var targetInfos []Target |
| | | targetInfos = append(targetInfos, *target) |
| | | |
| | |
| | | sdkname = "车牌识别" |
| | | } |
| | | //logger.Info("人脸目标target:",targetInfos) |
| | | pervideo := PerVideoPicture{ |
| | | pervideo := PerVideoPicture{LinkInfo{ |
| | | face.Uuid, |
| | | msg.Cid, |
| | | msg.Push.Cam.Addr, |
| | |
| | | false, |
| | | face.Liker, |
| | | targetInfos, |
| | | }, |
| | | "", |
| | | []*LinkInfo{}, |
| | | } |
| | |
| | | if resp["fileUrl"] != nil { |
| | | url = append(url, resp["fileUrl"].(string)) |
| | | //esDataId := uuid.NewV4().String() |
| | | peraction := PerVideoPicture{ |
| | | peraction := PerVideoPicture{LinkInfo{ |
| | | msg.Push.PushId, |
| | | msg.Cid, |
| | | msg.Push.Cam.Addr, |
| | |
| | | false, |
| | | nil, |
| | | targetInfos, |
| | | }, |
| | | linkTag, |
| | | linkTagInfos, |
| | | } |
| | |
| | | return |
| | | } |
| | | //esDataId := uuid.NewV4().String() |
| | | peraction := PerVideoPicture{ |
| | | peraction := PerVideoPicture{LinkInfo{ |
| | | msg.Push.PushId, |
| | | msg.Cid, |
| | | msg.Push.Cam.Addr, |
| | |
| | | false, |
| | | nil, |
| | | targetInfos, |
| | | }, |
| | | linkTag, |
| | | linkTagInfos, |
| | | } |
| | |
| | | } |
| | | errSize := sock.SetOption(mangos.OptionMaxRecvSize,30*1024*1024) |
| | | if errSize != nil { |
| | | logger.Error("传输的数据超过大小限制") |
| | | _ = logger.Error("传输的数据超过大小限制") |
| | | return |
| | | } |
| | | errTimeOut := sock.SetOption(mangos.OptionRecvDeadline,time.Millisecond * 1500) |
| | | if errTimeOut != nil { |
| | | logger.Error("接收响应超时") |
| | | _ = logger.Error("接收响应超时") |
| | | return |
| | | } |
| | | errTimeOut1 := sock.SetOption(mangos.OptionSendDeadline,time.Millisecond * 1500) |
| | | if errTimeOut1 != nil { |
| | | logger.Error("发送超时") |
| | | _ = logger.Error("发送超时") |
| | | return |
| | | } |
| | | errWrite := sock.SetOption(mangos.OptionWriteQLen,5) |
| | | if errWrite != nil { |
| | | logger.Error("设置传输缓存大小失败") |
| | | _ = logger.Error("设置传输缓存大小失败") |
| | | return |
| | | } |
| | | errRead := sock.SetOption(mangos.OptionReadQLen,5) |
| | | if errRead != nil { |
| | | logger.Error("设置传输缓存大小失败") |
| | | _ = logger.Error("设置传输缓存大小失败") |
| | | return |
| | | } |
| | | sock.AddTransport(tcp.NewTransport()) |
| | | if err = sock.Dial("tcp://"+url); err != nil { |
| | | logger.Error("请求socket拨号失败: ", err.Error()) |
| | | _ = logger.Error("请求socket拨号失败: ", err.Error()) |
| | | } |
| | | logger.Info("序列化数据") |
| | | |
| | | //for v := range pool{ |
| | | // logger.Info("无限循环",v.Cid) |
| | | //} |
| | | //var ch chan *structure.ResultMsg |
| | | //for _, v := range urlChans { |
| | | // if v.url == url{ |
| | | // ch = v.ch |
| | | // } |
| | | //} |
| | | //logger.Info("chan信息:",urlPool[url]) |
| | | for { |
| | | select { |
| | | // case <-ctx.Done(): |
| | | // return |
| | | case data := <- urlPool[url]: |
| | | //logger.Info("接收到数据",data.Cid) |
| | | //bytes,err1 := proto.Marshal(data) |
| | | |
| | | go func(data []byte) { |
| | | //logger.Info("数据长度为:",len(data)) |
| | | //if err1 != nil { |
| | | // logger.Info("序列化失败:",err1) |
| | | //} |
| | | start := time.Now() |
| | | //logger.Debug("groutine"+url+"推送数据") |
| | | //bytes := []byte("ndfasojdfaidsos") |
| | | if err = sock.Send(data); err != nil { |
| | | Die("groutine"+url+"推送socket发送数据失败: ", err.Error()) |
| | | } |
| | |
| | | } |
| | | }(data) |
| | | default: |
| | | |
| | | time.Sleep(time.Second) |
| | | } |
| | | } |
| | | sock.Close() |
| | |
| | | Recommended: "[%D %T] [%L] (%S) %M"
|
| | | -->
|
| | | <property name="format">[%D %T] [%L] (%S) %M</property>
|
| | | <property name="rotate">false</property> <!-- true enables log rotation, otherwise append -->
|
| | | <property name="maxsize">600M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 -->
|
| | | <property name="rotate">true</property> <!-- true enables log rotation, otherwise append -->
|
| | | <property name="maxsize">800M</property> <!-- \d+[KMG]? Suffixes are in terms of 2**10 -->
|
| | | <property name="maxlines">10K</property> <!-- \d+[KMG]? Suffixes are in terms of thousands -->
|
| | | <property name="daily">true</property> <!-- Automatically rotates when a log message is written after midnight -->
|
| | | </filter>
|
| | |
| | | package main |
| | | |
| | | import ( |
| | | "basic.com/dbapi.git" |
| | | "basic.com/pubsub/protomsg.git" |
| | | "basic.com/valib/deliver.git" |
| | | |
| | | "flag" |
| | | "fmt" |
| | | "sync" |
| | | "net/http" |
| | | _ "net/http/pprof" |
| | | "plugin" |
| | | |
| | | //"github.com/spf13/viper" |
| | | logger "github.com/alecthomas/log4go" |
| | | "github.com/panjf2000/ants/v2" |
| | | |
| | | "basic.com/pubsub/protomsg.git" |
| | | "basic.com/valib/deliver.git" |
| | | "ruleprocess/insertdata" |
| | | "ruleprocess/labelFilter" |
| | | "ruleprocess/structure" |
| | | //"basic.com/valib/logger.git" |
| | | "flag" |
| | | "fmt" |
| | | //"github.com/spf13/viper" |
| | | logger "github.com/alecthomas/log4go" |
| | | "ruleprocess/cache" |
| | | "ruleprocess/ruleserver" |
| | | "sync" |
| | | ) |
| | | |
| | | var dbIp = flag.String("dbIp", "127.0.0.1", "dbserver ip") |
| | |
| | | } |
| | | func main() { |
| | | //fmt.Println("缓存初始化完成",<- initchan)//dbserver初始化完毕 |
| | | defer ants.Release() |
| | | go func() { |
| | | http.ListenAndServe("0.0.0.0:8899",nil) |
| | | }() |
| | |
| | | wg := sync.WaitGroup{} |
| | | wg.Add(3) |
| | | |
| | | dbapi.Init(*dbIp, *dbPort) |
| | | go cache.Init(initchan, *dbIp, *surveyPort, *pubPort) |
| | | logger.Info("cache init completed!!!", <-initchan) //dbserver初始化完毕 |
| | | ruleserver.Init() |
| | | labelFilter.Init() |
| | | |
| | | go ruleserver.TimeTicker() |
| | | go ruleserver.StartServer() |
| | | //timeEle := ruleserver.TimeElement{N: 300, InitN: 300} |
| | | //ruleserver.TimeEleList["ruleprocess"] = &timeEle |
| | | |
| | | nReciever("ipc:///tmp/sdk-2-rules-process.ipc", deliver.PushPull, 1) |
| | | wg.Wait() |
| | | |
| | | } |
| | | func nReciever(url string, m deliver.Mode, count int) { |
| | | c := deliver.NewServer(m, url) |
| | |
| | | } |
| | | |
| | | func nRecvImpl(c deliver.Deliver, index int) { |
| | | |
| | | var msg []byte |
| | | //var wg1 sync.WaitGroup |
| | | //p,_ := ants.NewPool(100) |
| | | //syncCalculateSum := func() { |
| | | // Task(msg) |
| | | // wg1.Done() |
| | | //} |
| | | //wg1.Wait() |
| | | var err error |
| | | //msgChan := make(chan []byte,100) |
| | | for { |
| | | select { |
| | | // case <-ctx.Done(): |
| | | // return |
| | | default: |
| | | msg, err = c.Recv() |
| | | //msgChan <- msg |
| | | if err != nil { |
| | | //logger.Info("recv error : ", err) |
| | | fmt.Println("recv error : ", err) |
| | | continue |
| | | } else { |
| | | |
| | | //go func(msg []byte) { |
| | | //logger.Debug("当前时间戳:", time.Now().Unix()) |
| | | //logger.Warn(time.Now().Format("2006-01-02 15:04:05")) |
| | | arg := structure.SdkDatas{} |
| | | //paramFormat(msg, &arg) |
| | | //start := time.Now() |
| | | m := CallParamFormat(msg, &arg) |
| | | // 进行规则处理判断(打上规则的标签) |
| | | ruleserver.Judge(&arg, &m) // 把sdkMessage传进去,方便缓存数据时拼出一个resultMag |
| | | // 把arg里的打的标签拿出来给m再封装一层 |
| | | resultMsg := structure.ResultMsg{SdkMessage: &m, RuleResult: arg.RuleResult} |
| | | ruleserver.GetAttachInfo(resultMsg.SdkMessage) |
| | | //ruleEnd := time.Since(start) |
| | | //logger.Debug("规则判断完所用时间:", ruleEnd) |
| | | // 将打完标签的数据插入到ES |
| | | insertdata.InsertToEs(resultMsg) |
| | | //esEnd := time.Since(start) |
| | | //logger.Debug("插入完Es所用时间:", esEnd) |
| | | //事件推送 |
| | | labelFilter.PushSomthing(resultMsg) |
| | | //}(msg) |
| | | } |
| | | msg, err = c.Recv() |
| | | if err == nil { |
| | | //wg1.Add(1) |
| | | //_ = p.Submit(syncCalculateSum) |
| | | Task(msg) |
| | | } |
| | | } |
| | | } |
| | | |
| | | func Task (msg []byte) { |
| | | arg := structure.SdkDatas{} |
| | | //start := time.Now() |
| | | m := CallParamFormat(msg, &arg) |
| | | // 进行规则处理判断(打上规则的标签) |
| | | ruleserver.Judge(&arg, &m) // 把sdkMessage传进去,方便缓存数据时拼出一个resultMag |
| | | // 把arg里的打的标签拿出来给m再封装一层 |
| | | resultMsg := structure.ResultMsg{SdkMessage: &m, RuleResult: arg.RuleResult} |
| | | ruleserver.GetAttachInfo(resultMsg.SdkMessage) |
| | | // 将打完标签的数据插入到ES |
| | | insertdata.InsertToEs(resultMsg) |
| | | //事件推送 |
| | | labelFilter.PushSomthing(resultMsg) |
| | | } |
| | | func CallParamFormat(msg []byte, args *structure.SdkDatas) protomsg.SdkMessage{ |
| | | //logger.Info("呼叫中间件格式化数据") |
| | | p,err := plugin.Open("./algorithm/middleware.so") |
| | |
| | | return mess |
| | | } |
| | | |
| | | // 5分钟收不到消息杀死自己重启 |
| | |
| | | import ( |
| | | "basic.com/dbapi.git" |
| | | "basic.com/pubsub/protomsg.git" |
| | | logger "github.com/alecthomas/log4go" |
| | | "encoding/json" |
| | | "errors" |
| | | "fmt" |
| | | logger "github.com/alecthomas/log4go" |
| | | "github.com/golang/protobuf/proto" |
| | | uuid "github.com/satori/go.uuid" |
| | | "math" |
| | | "nanomsg.org/go-mangos" |
| | | "nanomsg.org/go-mangos/protocol/req" |
| | |
| | | } |
| | | |
| | | // 计算区域内的目标数量以及将相似度、占比、尺寸等打包 |
| | | func CountAreaObjs(a *structure.AreaMap,arg *structure.SdkData) { |
| | | |
| | | a.TargetNum = 0 |
| | | threshold := 80.0 // 相似度 |
| | | intersectionper := 20.0 // 占比 |
| | | size := 0.0 // 尺寸 |
| | | |
| | | areaPoints := Json2points(a.AreaJson) |
| | | logger.Info("看看图片的width和height:",arg.ImageWidth,arg.ImageHeight) |
| | | widthScale := float64(arg.ImageWidth) / 960 |
| | | heigthScale := float64(arg.ImageHeight) / 540 |
| | | for _, obj := range arg.Photo { |
| | | //logger.Info("------------------看看sdkData:", arg.SdkName, "的Photo数据----------------", obj, "----顺便看看占比-----:", PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale)) |
| | | if obj.Score >= threshold && float64(obj.Rects.Width*obj.Rects.Height) >= size && PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale) >= intersectionper { |
| | | // 这步要备齐表达式里所需要的所有参数 |
| | | a.TargetNum++ |
| | | uuid := uuid.NewV4().String() |
| | | arg1 := structure.Arg{obj.Id,uuid,obj.Score, PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), float64(obj.Rects.Width * obj.Rects.Height), a.AreaJson,obj.Type, obj.Rects, obj.Car,obj.Feature, obj.ThftRes, []*structure.BaseInfo{},"",structure.ResultMsg{}} |
| | | //logger.Println("放进去的arg:-------", arg1) |
| | | a.Args = append(a.Args, &arg1) |
| | | a.FilterData = append(a.FilterData, &arg1) |
| | | } |
| | | } |
| | | //logger.Info("区域是:",areaPoints,"区域内目标数量为:",a.TargetNum,"---",len(a.FilterData)) |
| | | a.Time = time.Unix(time.Now().Unix(), 0).String()[11:16] |
| | | //logger.Println("--------------------看看区域数据:",*a) |
| | | } |
| | | |
| | | // 把sdk从数据帧上提取的按照区域分类归置 |
| | | func SdkDataFormat(cameraId string, arg *structure.SdkData, cameraPolygons []protomsg.CameraPolygon) { |
| | | logger.Info("==================================本sdkData中解出来的目标数据=======================================") |
| | | for _, photo := range arg.Photo { |
| | | logger.Info("--------解析出来的数据---", cameraId, arg.IpcId, photo.Rects, photo.Score) |
| | | } |
| | | for _, polygon := range cameraPolygons { |
| | | //logger.Println("++++++在这儿看一下区域啊:", polygon.Polygon) |
| | | areaMap := structure.AreaMap{CameraId: cameraId, AreaId: polygon.Id, AreaJson: polygon.Polygon, TriggerLine: polygon.TriggerLine, DirectionLine: polygon.DirectionLine} |
| | | // 为每个摄像机区域填充数据 |
| | | CountAreaObjs(&areaMap,arg) |
| | | arg.AreaMapList = append(arg.AreaMapList, &areaMap) |
| | | } |
| | | } |
| | | //func CountAreaObjs(a *structure.AreaMap,arg *structure.SdkData) { |
| | | // |
| | | // a.TargetNum = 0 |
| | | // threshold := 80.0 // 相似度 |
| | | // intersectionper := 20.0 // 占比 |
| | | // size := 0.0 // 尺寸 |
| | | // |
| | | // areaPoints := Json2points(a.AreaJson) |
| | | // logger.Info("看看图片的width和height:",arg.ImageWidth,arg.ImageHeight) |
| | | // widthScale := float64(arg.ImageWidth) / 960 |
| | | // heigthScale := float64(arg.ImageHeight) / 540 |
| | | // for _, obj := range arg.Photo { |
| | | // //logger.Info("------------------看看sdkData:", arg.SdkName, "的Photo数据----------------", obj, "----顺便看看占比-----:", PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale)) |
| | | // if obj.Score >= threshold && float64(obj.Rects.Width*obj.Rects.Height) >= size && PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale) >= intersectionper { |
| | | // // 这步要备齐表达式里所需要的所有参数 |
| | | // a.TargetNum++ |
| | | // uuid := uuid.NewV4().String() |
| | | // arg1 := structure.Arg{obj.Id,uuid,obj.Score, PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), float64(obj.Rects.Width * obj.Rects.Height), a.AreaJson,obj.Type, obj.Rects, obj.Car,obj.Feature, obj.ThftRes, []*structure.BaseInfo{},"",structure.ResultMsg{}} |
| | | // //logger.Println("放进去的arg:-------", arg1) |
| | | // a.Args = append(a.Args, &arg1) |
| | | // a.FilterData = append(a.FilterData, &arg1) |
| | | // } |
| | | // } |
| | | // //logger.Info("区域是:",areaPoints,"区域内目标数量为:",a.TargetNum,"---",len(a.FilterData)) |
| | | // a.Time = time.Unix(time.Now().Unix(), 0).String()[11:16] |
| | | // //logger.Println("--------------------看看区域数据:",*a) |
| | | //} |
| | | // |
| | | //// 把sdk从数据帧上提取的按照区域分类归置 |
| | | //func SdkDataFormat(cameraId string, arg *structure.SdkData, cameraPolygons []protomsg.CameraPolygon) { |
| | | // logger.Info("==================================本sdkData中解出来的目标数据=======================================") |
| | | // for _, photo := range arg.Photo { |
| | | // logger.Info("--------解析出来的数据---", cameraId, arg.IpcId, photo.Rects, photo.Score) |
| | | // } |
| | | // for _, polygon := range cameraPolygons { |
| | | // //logger.Println("++++++在这儿看一下区域啊:", polygon.Polygon) |
| | | // areaMap := structure.AreaMap{CameraId: cameraId, AreaId: polygon.Id, AreaJson: polygon.Polygon, TriggerLine: polygon.TriggerLine, DirectionLine: polygon.DirectionLine} |
| | | // // 为每个摄像机区域填充数据 |
| | | // CountAreaObjs(&areaMap,arg) |
| | | // arg.AreaMapList = append(arg.AreaMapList, &areaMap) |
| | | // } |
| | | //} |
| | | |
| | | func Push(data *protomsg.CompareArgs,sock mangos.Socket) []byte{ |
| | | //var sock mangos.Socket |
| | |
| | | //} |
| | | errSize := sock.SetOption(mangos.OptionMaxRecvSize,5*1024*1024) |
| | | if errSize != nil { |
| | | logger.Error("Failed set MaxRecvSize: %v", err) |
| | | _ = logger.Error("Failed set MaxRecvSize: %v", err) |
| | | return nil |
| | | } |
| | | serverIP, _ := GetLocalIP() |
| | | if err = sock.Dial("tcp://"+serverIP+":4010"); err != nil { |
| | | logger.Error("请求socket拨号失败: %s", err.Error()) |
| | | _ = logger.Error("请求socket拨号失败: %s", err.Error()) |
| | | } |
| | | //sock.AddTransport(ipc.NewTransport()) |
| | | sock.AddTransport(tcp.NewTransport()) |
| | |
| | | logger.Debug("推送数据") |
| | | //bytes := []byte("ndfasojdfaidsos") |
| | | if err = sock.Send(bytes); err != nil { |
| | | logger.Error("推送socket发送数据失败: %s", err.Error()) |
| | | _ = logger.Error("推送socket发送数据失败: %s", err.Error()) |
| | | //os.Exit(1) |
| | | } |
| | | if msg, err = sock.Recv(); err != nil { |
| | | logger.Error("接收响应失败: %s", err.Error()) |
| | | _ = logger.Error("接收响应失败: %s", err.Error()) |
| | | //os.Exit(1) |
| | | } |
| | | logger.Debug("数据推送成功!收到响应,数据长度为:",len(msg)) |
| | |
| | | var msg []byte |
| | | |
| | | 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) |
| | | if errSize != nil { |
| | | logger.Error("Failed set MaxRecvSize: %v", err) |
| | | _ = logger.Error("Failed set MaxRecvSize: %v", err) |
| | | } |
| | | //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()) |
| | | _ = logger.Error("请求socket拨号失败: %s", err.Error()) |
| | | } |
| | | logger.Info("序列化数据") |
| | | |
| | |
| | | logger.Info("序列化失败:",err1) |
| | | } |
| | | logger.Debug("推送数据") |
| | | //bytes := []byte("ndfasojdfaidsos") |
| | | if err = sock.Send(bytes); err != nil { |
| | | logger.Error("推送socket发送数据失败: %s", err.Error()) |
| | | //os.Exit(1) |
| | | _ = logger.Error("推送socket发送数据失败: %s", err.Error()) |
| | | } |
| | | if msg, err = sock.Recv(); err != nil { |
| | | logger.Error("接收响应失败: %s", err.Error()) |
| | | //os.Exit(1) |
| | | _ = logger.Error("接收响应失败: %s", err.Error()) |
| | | } |
| | | logger.Debug("数据推送成功!收到响应,数据长度为:",len(msg)) |
| | | receiver <- msg |
| | | default: |
| | | |
| | | time.Sleep(time.Second) |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | // 跟踪目标统计 |
| | | personTrack := []*structure.Arg{} |
| | | for _, sdkData := range args.Sdkdata { |
| | | //logger.Info("看看sdkNames",sdkNames) |
| | | if sdkData.IpcId == "跟踪的ipcId" { // 把跟踪页面的各个目标的坐标输出 |
| | | for _, areaMap := range sdkData.AreaMapList { |
| | | if areaMap.IsEffective { |
| | | personTrack = append(personTrack, putFaceToResult(areaMap, personTrack)...) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | var islink bool |
| | | if groupRule.SetType == "linkTask" { |
| | | islink = true |
| | |
| | | //logger.Info("-------------------车牌结果标签", len(args.RuleResult["plate"].([]structure.Result))) |
| | | //labelTypes = append(labelTypes,2) |
| | | } |
| | | if len(personTrack) > 0 { |
| | | args.RuleResult["track"] = append(args.RuleResult["track"].([]structure.Result), structure.Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, personTrack, polygonId, islink,label}) |
| | | //logger.Info("-------------------车牌结果标签", len(args.RuleResult["plate"].([]structure.Result))) |
| | | //labelTypes = append(labelTypes,2) |
| | | } |
| | | // 给持续时间的第一张赋予缓存数据(遍历复制) |
| | | //if cacheId != "" { // 有这帧数据的缓存 |
| | | // tempMap := make(map[string]interface{}) |
| | |
| | | select { |
| | | case dbMsg := <-videotapChan: |
| | | publishMessage(dbMsg) |
| | | default: |
| | | time.Sleep(time.Second) |
| | | } |
| | | } |
| | | } |
| | |
| | | ) |
| | | |
| | | // 每个目标的参数:相似度,占比,尺寸 |
| | | type Arg struct { |
| | | Id string |
| | | Uuid string |
| | | Score float64 // 区域内的目标的相似度 |
| | | Proportion float64 // 区域内的目标的占比 |
| | | Size float64 // 区域内的目标的尺寸 |
| | | AreaJson string // 所属区域 |
| | | Type string // 记载数据类型 |
| | | Location Rect // 记下每个目标的位置参数,最后给结果装配目标数据的时候用的到 |
| | | Car *protomsg.PlateIDVehicle // 车辆参数 |
| | | Feature []byte |
| | | ThftRes protomsg.ThftResult |
| | | Liker []*BaseInfo |
| | | TimeLable string |
| | | CacheData ResultMsg |
| | | type SourceArg struct { |
| | | Id string |
| | | Uuid string |
| | | Score float64 // 区域内的目标的相似度 |
| | | Proportion float64 // 区域内的目标的占比 |
| | | Size float64 // 区域内的目标的尺寸 |
| | | AreaJson string // 所属区域 |
| | | Type string // 记载数据类型 |
| | | Location Rect // 记下每个目标的位置参数,最后给结果装配目标数据的时候用的到 |
| | | Car *protomsg.PlateIDVehicle // 车辆参数 |
| | | Feature []byte |
| | | ThftRes protomsg.ThftResult |
| | | Liker []*BaseInfo |
| | | TimeLable string |
| | | CacheData ResultMsg |
| | | } |
| | | |
| | | type Arg struct { |
| | | SourceArg |
| | | AttachArg SourceArg |
| | | } |
| | | // 每个区域内的图片数据集合 |
| | | type AreaMap struct { |
| | | CameraId string |
| | |
| | | TargetNum int // 区域内目标数量 |
| | | Args []*Arg // 区域内目标集合 |
| | | FilterData []*Arg // 过滤后区域内目标集合 |
| | | AlarmObj []*Arg // 区域内最后满足规则的目标 |
| | | AlarmObj []*Arg // 区域内最后满足规则的目标 |
| | | Time string // 当前时间(用以匹配时间规则) |
| | | IsEffective bool // 规则中是否用到了此区域 |
| | | } |
| | |
| | | Id string |
| | | Rects Rect // 矩形区域参数 |
| | | Score float64 // 相似度得分(有多大程度像一个目标。人脸,人体或车等等) |
| | | Type string // 记载数据类型 |
| | | Type string // 记载数据类型 |
| | | ThftRes protomsg.ThftResult |
| | | Feature []byte |
| | | Car *protomsg.PlateIDVehicle |
| | | Car *protomsg.PlateIDVehicle |
| | | } |
| | | |
| | | // 每个算法对于当前帧画面自己提取的数据 |
| | |
| | | AlarmLevel int32 // 报警等级 |
| | | RuleText string // 文字版规则组 |
| | | //Location []TargetInfo // 目标的坐标 |
| | | AlarmObj []*Arg // 报警的目标数据 打算废掉上面的Location |
| | | AlarmObj []*Arg // 报警的目标数据 打算废掉上面的Location |
| | | AlarmPolygon string // 触发的报警框 |
| | | IsLink bool // 是否是联动任务 |
| | | Others |
| | |
| | | TargetPicUrl string `json:"targetPicUrl"` |
| | | MonitorLevel string `json:"monitorLevel"` |
| | | Content string `json:"content"` |
| | | DbLabel string `json:"labels"` |
| | | //PhoneNum string `json:"phoneNum"` |
| | | //Sex string `json:"sex"` |
| | | //IdCard string `json:"idCard"` |
| | | DbLabel string `json:"labels"` |
| | | } |