New file |
| | |
| | | package main |
| | | |
| | | import ( |
| | | "basic.com/pubsub/protomsg.git" |
| | | "basic.com/valib/logger.git" |
| | | "github.com/knetic/govaluate" |
| | | "ruleprocess/structure" |
| | | "strconv" |
| | | ) |
| | | |
| | | // 车牌算法 |
| | | |
| | | func Entrance(rule *protomsg.Rule, am *structure.AreaMap,lable *structure.Others,args *structure.SdkDatas,message *protomsg.SdkMessage) structure.LittleRuleResult { |
| | | if rule.PolygonId == am.AreaId { // 首先这条规则得是这个算法的规则,其次规则所对应的区域id要跟区域数据的id对的上 |
| | | if rule.SdkArgAlias != "nCarCount" && rule.SdkArgAlias != "nCarLogoCount" { |
| | | logger.Info("过滤车牌信息") |
| | | return filterRule(rule, am) |
| | | } else { |
| | | logger.Info("计算车牌车辆数量") // 目前只能检测出车牌数量 |
| | | return transferParameters(rule, am) |
| | | } |
| | | } else { |
| | | return structure.LittleRuleResult{} |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // 过滤规则先筛选出符合条件的目标数量 |
| | | func filterRule(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult { |
| | | // 处理的都是yolo数据 |
| | | carFlag := rule.SdkArgAlias == "license" || rule.SdkArgAlias == "nColor" || rule.SdkArgAlias == "nConfidence" || |
| | | rule.SdkArgAlias == "nBright" || rule.SdkArgAlias == "nTime" || rule.SdkArgAlias == "nCarBright" || rule.SdkArgAlias == "nCarColor" || |
| | | rule.SdkArgAlias == "nCarLogo" || rule.SdkArgAlias == "nCarType" || rule.SdkArgAlias == "nCarModel" || rule.SdkArgAlias == "nCarModelConfidence" |
| | | |
| | | if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" || carFlag{ // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加 |
| | | logger.Debug("---------走了车牌识别过滤算法",rule.Id,rule.SdkArgAlias,rule.Operator,rule.SdkArgValue,am.AreaId) |
| | | 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) |
| | | case "license": |
| | | formula = arg.Car.License + " " + rule.Operator + " " + rule.SdkArgValue |
| | | logger.Info("当前车牌号码小公式:", formula) |
| | | case "nColor": |
| | | formula = strconv.Itoa(int(arg.Car.NColor)) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | logger.Info("车牌颜色小公式:", formula) |
| | | case "nConfidence": |
| | | formula = strconv.Itoa(int(arg.Car.NConfidence)) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | logger.Info("整牌可信度小公式:", formula) |
| | | case "nBright": |
| | | formula = strconv.Itoa(int(arg.Car.NBright)) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | logger.Info("车牌亮度评价小公式:", formula) |
| | | case "nDirection": |
| | | formula = strconv.Itoa(int(arg.Car.NDirection)) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | logger.Info("车牌运动方向小公式:", formula) |
| | | case "nTime": |
| | | formula = strconv.Itoa(int(arg.Car.NTime)) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | logger.Info("识别耗时小公式:", formula) |
| | | case "nCarBright": |
| | | formula = strconv.Itoa(int(arg.Car.NCarBright)) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | logger.Info("车的亮度小公式:", formula) |
| | | case "nCarColor": |
| | | formula = strconv.Itoa(int(arg.Car.NCarColor)) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | logger.Info("车的颜色小公式:", formula) |
| | | case "nCarLogo": |
| | | formula = strconv.Itoa(int(arg.Car.NCarLogo)) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | logger.Info("车标类型小公式:", formula) |
| | | case "nCarType": |
| | | formula = strconv.Itoa(int(arg.Car.NCarType)) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | logger.Info("车辆类型小公式:", formula) |
| | | //case "nCarModel": |
| | | // formula = strconv.Itoa(int(arg.Car.ncm)) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | // logger.Info("识别成功与否小公式:", formula) |
| | | //case "nCarModelConfidence": |
| | | // formula = strconv.Itoa(int(arg.Car.NCarModelConfidence)) + " " + 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{} |
| | | } |
| | | |
| | | |
| | | // 给数据库的规则表达式代参 args: 一条子规则,区域数据 |
| | | func transferParameters(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult { |
| | | //logger.Info("当前小规则是:---------", rule) |
| | | //logger.Info("得出结果阶段", "比较的规则是:", rule) |
| | | if rule.Operator == "" { |
| | | return structure.LittleRuleResult{am.SdkName, strconv.Itoa(am.TargetNum) + "" + rule.RuleWithPre, rule.Sort} // 如果后面不跟操作符就直接返回数量 比如要跟下一个区域比较数量的就直接返回本区域的数量 |
| | | } |
| | | //args := am.targetNum targetNum 已成所有目标的总数量,这里只算yolo的 |
| | | var num int = len(am.FilterData) |
| | | formula := strconv.Itoa(num) + " " + rule.Operator + " " + rule.SdkArgValue |
| | | expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式 |
| | | result, _ := expression.Evaluate(nil) // 得到数学公式的结果 |
| | | return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + " " + strconv.FormatBool(result.(bool)), rule.Sort} |
| | | // 加上关于算法的判断条件,不能只有关于规则的,有的算法本身就是一个规则,如个体静止,靠右行,所以,拿到当前子规则的sdkid来判断是否是那些特殊的规则 |
| | | } |
| | |
| | | polygonId := "" |
| | | // 先过完条件规则 |
| | | for j := 0; j < len(groupRule.Rules); j++ { |
| | | if groupRule.Rules[j].SdkArgAlias == "score" || groupRule.Rules[j].SdkArgAlias == "proportion" || groupRule.Rules[j].SdkArgAlias == "size" || (groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && groupRule.Rules[j].SdkArgAlias != "time_rule"){ |
| | | |
| | | carFlag := groupRule.Rules[j].SdkArgAlias == "license" || groupRule.Rules[j].SdkArgAlias == "nColor" || groupRule.Rules[j].SdkArgAlias == "nConfidence" || |
| | | groupRule.Rules[j].SdkArgAlias == "nBright" || groupRule.Rules[j].SdkArgAlias == "nTime" || groupRule.Rules[j].SdkArgAlias == "nCarBright" || groupRule.Rules[j].SdkArgAlias == "nCarColor" || |
| | | groupRule.Rules[j].SdkArgAlias == "nCarLogo" || groupRule.Rules[j].SdkArgAlias == "nCarType" || groupRule.Rules[j].SdkArgAlias == "nCarModel" || groupRule.Rules[j].SdkArgAlias == "nCarModelConfidence" |
| | | |
| | | if groupRule.Rules[j].SdkArgAlias == "score" || groupRule.Rules[j].SdkArgAlias == "proportion" || groupRule.Rules[j].SdkArgAlias == "size" || |
| | | (groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && groupRule.Rules[j].SdkArgAlias != "time_rule") || carFlag{ |
| | | for _, sdkData := range args.Sdkdata { |
| | | // 根据规则的sdkId查出其对应的ipcId,用ipcId去找该比对的数据 |
| | | sdk, err := cache.GetSdkById(groupRule.Rules[j].SdkId) |
| | |
| | | } |
| | | } |
| | | } |
| | | // 车辆 |
| | | for j := 0; j < len(groupRule.Rules); j++ { |
| | | if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a978" && (groupRule.Rules[j].SdkArgAlias == "nCarCount" || groupRule.Rules[j].SdkArgAlias == "nCarLogoCount"){ |
| | | 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" { |
New file |
| | |
| | | package main |
| | | |
| | | import ( |
| | | "basic.com/pubsub/protomsg.git" |
| | | "basic.com/valib/logger.git" |
| | | "github.com/golang/protobuf/proto" |
| | | uuid "github.com/satori/go.uuid" |
| | | "ruleprocess/ruleserver" |
| | | "ruleprocess/structure" |
| | | "ruleprocess/util" |
| | | "strconv" |
| | | "time" |
| | | ) |
| | | func ReadData(args *structure.SdkDatas,cameraPolygons []protomsg.CameraPolygon) { |
| | | for _, arg := range args.Sdkdata { |
| | | SdkDataFormat(args.CameraId, arg, cameraPolygons) |
| | | } |
| | | } |
| | | |
| | | // 计算区域内的目标数量以及将相似度、占比、尺寸等打包 |
| | | func CountAreaObjs(a *structure.AreaMap,arg *structure.SdkData) { |
| | | |
| | | a.TargetNum = 0 |
| | | threshold := 80.0 // 相似度 |
| | | intersectionper := 20.0 // 占比 |
| | | size := 0.0 // 尺寸 |
| | | |
| | | areaPoints := ruleserver.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 && ruleserver.PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale) >= intersectionper { |
| | | // 这步要备齐表达式里所需要的所有参数 |
| | | 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.IsYolo, 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) |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | // 将外部传进来的rect(top,bottom,left,right)转化为自己内部的rect(left top width height) |
| | | func rectFormat(rcobj *protomsg.Rect) structure.Rect { |
| | | //logger.Info("++++++++++++++++++++++++++++++收到的yolo的区域坐标:",rcobj) |
| | | rect := structure.Rect{} |
| | | rect.X = float64(rcobj.Left) |
| | | rect.Y = float64(rcobj.Top) |
| | | rect.Width = float64(rcobj.Right - rcobj.Left) |
| | | rect.Height = float64(rcobj.Bottom - rcobj.Top) |
| | | return rect |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | // 将外部传进来的sdk数据包解成 SdkDatas |
| | | func ParamFormat(msg []byte, args *structure.SdkDatas) protomsg.SdkMessage { |
| | | defer func() { |
| | | if err := recover(); err != nil { |
| | | logger.Info("解包过程的异常捕获", err.(string)) |
| | | } |
| | | |
| | | }() |
| | | // 反序列化数据得到sdk入参 |
| | | m := protomsg.SdkMessage{} |
| | | err := proto.Unmarshal(msg, &m) |
| | | if err != nil { |
| | | panic("解析msg时出现错误") |
| | | } |
| | | |
| | | // 先进行一下追踪 |
| | | ruleserver.FaceIsSame(&m) |
| | | args.CameraId = m.Cid |
| | | args.TaskId = m.Tasklab.Taskid |
| | | // 把图片的二进制解压缩进行画框在压缩回去 |
| | | bdata, err := util.UnCompress(m.Data) |
| | | if err != nil { |
| | | panic("解压缩图片时出现错误") |
| | | } |
| | | i := protomsg.Image{} |
| | | err = proto.Unmarshal(bdata, &i) |
| | | 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, IsYolo: true,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), IsYolo: false, 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 |
| | | 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) |
| | | photoMap := structure.PhotoMap{Score: float64(info.NConfidence),Rects: rectFormat(info.RcLocation), IsYolo: false, Car:info} |
| | | arg.Photo = append(arg.Photo, photoMap) |
| | | } |
| | | args.Sdkdata = append(args.Sdkdata, &arg) |
| | | } else { |
| | | continue |
| | | } |
| | | } |
| | | } |
| | | return m |
| | | } |
| | |
| | | ageDescription := getDescription(face.ThftRes.Age) |
| | | logger.Info(ageDescription) |
| | | var target = new(Target) |
| | | target.TargetId = strconv.FormatUint(face.Id, 10) |
| | | target.TargetId = face.Id |
| | | target.TargetScore = face.Score |
| | | 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}} |
| | | //logger.Info("人脸的id:",strconv.FormatUint(face.Id, 10)) |
| | |
| | | // 去重添加 |
| | | var flag = true |
| | | for _, selectTarget := range targetInfos { |
| | | if strconv.FormatUint(target.Id, 10) == selectTarget.TargetId { |
| | | if target.Id == selectTarget.TargetId { |
| | | flag = false |
| | | break |
| | | } |
| | | } |
| | | if flag { |
| | | var target1 = new(Target) |
| | | target1.TargetId = strconv.FormatUint(target.Id, 10) |
| | | target1.TargetId = target.Id |
| | | target1.TargetScore = target.Score |
| | | target1.TargetLocation = Points{TopLeft: Point{target.Location.X, target.Location.Y}, BottomRight: Point{target.Location.X + target.Location.Width, target.Location.Y + target.Location.Height}} |
| | | targetInfos = append(targetInfos, *target1) |
| | |
| | | // 去重添加 |
| | | var flag = true |
| | | for _, selectTarget := range targetInfos { |
| | | if strconv.FormatUint(target.Id, 10) == selectTarget.TargetId { |
| | | if target.Id == selectTarget.TargetId { |
| | | flag = false |
| | | break |
| | | } |
| | | } |
| | | if flag { |
| | | var target1 = new(Target) |
| | | target1.TargetId = strconv.FormatUint(target.Id, 10) |
| | | target1.TargetId = target.Id |
| | | target1.TargetScore = target.Score |
| | | target1.TargetLocation = Points{TopLeft: Point{target.Location.X, target.Location.Y}, BottomRight: Point{target.Location.X + target.Location.Width, target.Location.Y + target.Location.Height}} |
| | | targetInfos = append(targetInfos, *target1) |
| | |
| | | "basic.com/valib/deliver.git" |
| | | "net/http" |
| | | _ "net/http/pprof" |
| | | "plugin" |
| | | "ruleprocess/insertdata" |
| | | "ruleprocess/labelFilter" |
| | | "ruleprocess/structure" |
| | | "ruleprocess/util" |
| | | "time" |
| | | |
| | | "basic.com/valib/logger.git" |
| | | "flag" |
| | | "fmt" |
| | | "github.com/golang/protobuf/proto" |
| | | |
| | | "github.com/spf13/viper" |
| | | "ruleprocess/cache" |
| | | "ruleprocess/ruleserver" |
| | | "sync" |
| | | "github.com/spf13/viper" |
| | | ) |
| | | |
| | | var dbIp = flag.String("dbIp", "127.0.0.1", "dbserver ip") |
| | |
| | | arg := structure.SdkDatas{} |
| | | //paramFormat(msg, &arg) |
| | | start := time.Now() |
| | | m := paramFormat(msg, &arg) |
| | | m := CallParamFormat(msg, &arg) |
| | | // 进行规则处理判断(打上规则的标签) |
| | | ruleserver.Judge(&arg, &m) // 把sdkMessage传进去,方便缓存数据时拼出一个resultMag |
| | | // 把arg里的打的标签拿出来给m再封装一层 |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | // 将外部传进来的rect(top,bottom,left,right)转化为自己内部的rect(left top width height) |
| | | func rectFormat(rcobj *protomsg.Rect) structure.Rect { |
| | | //logger.Info("++++++++++++++++++++++++++++++收到的yolo的区域坐标:",rcobj) |
| | | rect := structure.Rect{} |
| | | rect.X = float64(rcobj.Left) |
| | | rect.Y = float64(rcobj.Top) |
| | | rect.Width = float64(rcobj.Right - rcobj.Left) |
| | | rect.Height = float64(rcobj.Bottom - rcobj.Top) |
| | | return rect |
| | | } |
| | | |
| | | // 将外部传进来的sdk数据包解成 SdkDatas |
| | | func paramFormat(msg []byte, args *structure.SdkDatas) protomsg.SdkMessage { |
| | | defer func() { |
| | | if err := recover(); err != nil { |
| | | logger.Info("解包过程的异常捕获", err.(string)) |
| | | } |
| | | |
| | | }() |
| | | // 反序列化数据得到sdk入参 |
| | | m := protomsg.SdkMessage{} |
| | | err := proto.Unmarshal(msg, &m) |
| | | func CallParamFormat(msg []byte, args *structure.SdkDatas) protomsg.SdkMessage{ |
| | | p,err := plugin.Open("./algorithm/middleware.so") |
| | | if err != nil { |
| | | panic("解析msg时出现错误") |
| | | panic(err) |
| | | } |
| | | |
| | | // 先进行一下追踪 |
| | | ruleserver.FaceIsSame(&m) |
| | | args.CameraId = m.Cid |
| | | args.TaskId = m.Tasklab.Taskid |
| | | // 把图片的二进制解压缩进行画框在压缩回去 |
| | | bdata, err := util.UnCompress(m.Data) |
| | | if err != nil { |
| | | panic("解压缩图片时出现错误") |
| | | f,err1 := p.Lookup("ParamFormat") |
| | | if err1 != nil { |
| | | panic("没有找到中间件入口函数") |
| | | } |
| | | i := protomsg.Image{} |
| | | err = proto.Unmarshal(bdata, &i) |
| | | 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, IsYolo: true,Id: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: info.Pos.FaceID, Rects: rectFormat(info.Pos.RcFace), Score: float64(info.Pos.FAngle.Confidence * 100), IsYolo: false, 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 |
| | | 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) |
| | | photoMap := structure.PhotoMap{Rects: rectFormat(info.RcLocation), IsYolo: false, Car:info} |
| | | arg.Photo = append(arg.Photo, photoMap) |
| | | } |
| | | args.Sdkdata = append(args.Sdkdata, &arg) |
| | | } else { |
| | | continue |
| | | } |
| | | } |
| | | } |
| | | return m |
| | | mess := f.(func(msg []byte, args *structure.SdkDatas)(protomsg.SdkMessage))(msg,args) |
| | | return mess |
| | | } |
| | |
| | | //logger.Info("初步保留两位成str::::",value2) |
| | | return value2 |
| | | } |
| | | // 取出某个时间规则的第几天的规则段集合 |
| | | func GetTimeById(id string, index int) []structure.TimeRange { |
| | | _, cameraTimeRule := cache.GetTimeRuleById(id) |
| | | var timeRangeList []structure.Day |
| | | err := json.Unmarshal([]byte(cameraTimeRule.TimeRule), &timeRangeList) |
| | | if err != nil { |
| | | logger.Error("取时间规则时反序列化错误!") |
| | | } |
| | | for _, timerange := range timeRangeList { |
| | | if timerange.Day == index { |
| | | //logger.Println("取到的时间规则:", timerange.TimeRange) |
| | | return timerange.TimeRange |
| | | } |
| | | } |
| | | return nil |
| | | } |
| | | |
| | | // 根据传入的字符串得到其在一周内的索引 周一到周日分别对应1到7 |
| | | func getIndexOfWeek(weekday string) int { |
| | | var weekdays = [7]string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"} |
| | | for k, value := range weekdays { |
| | | if value == weekday { |
| | | return k + 1 // 因为数据库中存的是1-7代表的周一到周日 |
| | | } |
| | | } |
| | | return 0 |
| | | } |
| | | |
| | | |
| | | |
| | | // 将字符串格式的坐标序列化为Point格式 |
| | | func Json2points(areaPoints string) []structure.Point { |
| | |
| | | // 这步要备齐表达式里所需要的所有参数 |
| | | 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.IsYolo, obj.Rects, obj.Feature, obj.ThftRes, []*structure.BaseInfo{},"",structure.ResultMsg{}} |
| | | arg1 := structure.Arg{obj.Id,uuid,obj.Score, PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), float64(obj.Rects.Width * obj.Rects.Height), a.AreaJson,obj.IsYolo, 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) |
| | |
| | | cameraPolygons := GetPolygons(args.CameraId) |
| | | // 把所有的sdk提取的数据都按所属摄像机的区域归置 |
| | | logger.Debug("当前摄像机id为:",message.Cid,"当前摄像机执行的任务是:",message.Tasklab.Taskname,"--任务id为:",message.Tasklab.Taskid) |
| | | for _, arg := range args.Sdkdata { |
| | | SdkDataFormat(args.CameraId, arg, cameraPolygons) |
| | | } |
| | | CallReadyData(args,cameraPolygons) |
| | | // 跑本摄像机的所有规则组 一组一组跑 |
| | | taskGroup := GetRuleGroup(args.CameraId, args.TaskId) // 本摄像机本任务下所有规则组 |
| | | //logger.Println("看下摄像机下的任务组:",taskRuleList) |
| | |
| | | } |
| | | a,b,c := f.(func(args *structure.SdkDatas,rule protomsg.GroupRule,label *structure.Others,message *protomsg.SdkMessage)(bool,string, string))(args,rule,lable,message) |
| | | return a,b,c |
| | | } |
| | | |
| | | func CallReadyData(args *structure.SdkDatas,cameraPolygons []protomsg.CameraPolygon) { |
| | | p,err := plugin.Open("./algorithm/middleware.so") |
| | | if err != nil { |
| | | panic(err) |
| | | } |
| | | f,err1 := p.Lookup("ReadyData") |
| | | if err1 != nil { |
| | | panic("没有找到中间件入口函数") |
| | | } |
| | | f.(func(args *structure.SdkDatas,cameraPolygons []protomsg.CameraPolygon)())(args,cameraPolygons) |
| | | } |
| | | |
| | | func RunRule(args *structure.SdkDatas, groupRule *protomsg.GroupRule, taskId string, message *protomsg.SdkMessage, label structure.Others) (bool,[]int) { |
| | |
| | | // 处理目标定时数据 |
| | | targets := []*structure.Arg{} |
| | | for _, sdkData := range args.Sdkdata { |
| | | if sdkData.IpcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && sdkNames != "" { // 把yolo数据的各个目标的坐标输出方便后面画框 |
| | | if sdkData.IpcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && sdkNames != "" { // 输出目标数据 |
| | | for _, areaMap := range sdkData.AreaMapList { |
| | | if areaMap.IsEffective { |
| | | targets = append(targets, putTargetsToResult(areaMap)...) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 车辆目标统计 |
| | | cars := []*structure.Arg{} |
| | | for _, sdkData := range args.Sdkdata { |
| | | if sdkData.IpcId == "91d923ef-6200-4549-ab1b-8e773e85d729" && sdkNames != "" { // 把yolo数据的各个目标的坐标输出方便后面画框 |
| | | for _, areaMap := range sdkData.AreaMapList { |
| | | if areaMap.IsEffective { |
| | | cars = append(cars, putYolosToResult(areaMap)...) |
| | | } |
| | | } |
| | | } |
| | |
| | | logger.Info("-------------------目标持续结果标签", len(args.RuleResult["target"].([]structure.Result))) |
| | | //labelTypes = append(labelTypes,2) |
| | | } |
| | | if len(cars) > 0 { |
| | | args.RuleResult["car"] = append(args.RuleResult["car"].([]structure.Result), structure.Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, cars, polygonId, islink,label}) |
| | | logger.Info("-------------------目标持续结果标签", len(args.RuleResult["target"].([]structure.Result))) |
| | | //labelTypes = append(labelTypes,2) |
| | | } |
| | | // 给持续时间的第一张赋予缓存数据(遍历复制) |
| | | if cacheId != "" { // 有这帧数据的缓存 |
| | | tempMap := make(map[string]interface{}) |
| | |
| | | Targets []*Obj |
| | | } |
| | | type Obj struct { |
| | | Id uint64 |
| | | Id string |
| | | Location Rect |
| | | N int // 计数器当前值 |
| | | InitN int // 计数器初始值 |
| | |
| | | |
| | | // 每个目标的参数:相似度,占比,尺寸 |
| | | type Arg struct { |
| | | Id uint64 |
| | | Id string |
| | | Uuid string |
| | | Score float64 // 区域内的目标的相似度 |
| | | Proportion float64 // 区域内的目标的占比 |
| | |
| | | AreaJson string // 所属区域 |
| | | IsYolo bool // 是否是yolo数据 |
| | | Location Rect // 记下每个目标的位置参数,最后给结果装配目标数据的时候用的到 |
| | | Car *protomsg.PlateID // 车辆参数 |
| | | Feature []byte |
| | | ThftRes protomsg.ThftResult |
| | | Liker []*BaseInfo |
| | |
| | | |
| | | // sdk输出的图片上单个目标的数据 |
| | | type PhotoMap struct { |
| | | Id uint64 |
| | | Id string |
| | | Rects Rect // 矩形区域参数 |
| | | Score float64 // 相似度得分(有多大程度像一个目标。人脸,人体或车等等) |
| | | IsYolo bool // 是否是yolo数据 |