panlei
2019-11-16 90f568cf48fcc3131b45a2081dea40015eae5c5b
把数据格式化以及装配放进so
2个文件已添加
7个文件已修改
589 ■■■■ 已修改文件
algorithm/car/car.go 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/middleware/middleware.go 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/middleware/readyData.go 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
insertdata/insertDataToEs.go 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.go 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/readyDataForRule.go 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/ruleToformula.go 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
structure/algorithm.go 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
structure/rule.go 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/car/car.go
New file
@@ -0,0 +1,134 @@
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来判断是否是那些特殊的规则
}
algorithm/middleware/middleware.go
@@ -20,7 +20,13 @@
    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)
@@ -126,6 +132,42 @@
            }
        }
    }
    // 车辆
    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" {
algorithm/middleware/readyData.go
New file
@@ -0,0 +1,192 @@
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
}
insertdata/insertDataToEs.go
@@ -233,7 +233,7 @@
                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))
@@ -397,14 +397,14 @@
                            // 去重添加
                            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)
@@ -812,14 +812,14 @@
                        // 去重添加
                        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)
main.go
@@ -6,21 +6,19 @@
    "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")
@@ -93,7 +91,7 @@
                    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再封装一层
@@ -113,128 +111,15 @@
    }
}
// 将外部传进来的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
}
ruleserver/readyDataForRule.go
@@ -93,35 +93,6 @@
    //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 {
@@ -275,7 +246,7 @@
            // 这步要备齐表达式里所需要的所有参数
            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)
ruleserver/ruleToformula.go
@@ -27,9 +27,7 @@
        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)
@@ -88,6 +86,18 @@
    }
    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) {
@@ -169,10 +179,21 @@
            // 处理目标定时数据
            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)...)
                        }
                    }
                }
@@ -199,6 +220,11 @@
                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{})
structure/algorithm.go
@@ -7,7 +7,7 @@
    Targets []*Obj
}
type Obj struct {
    Id           uint64
    Id           string
    Location     Rect
    N            int // 计数器当前值
    InitN         int // 计数器初始值
structure/rule.go
@@ -6,7 +6,7 @@
// 每个目标的参数:相似度,占比,尺寸
type Arg struct {
    Id         uint64
    Id         string
    Uuid       string
    Score      float64 // 区域内的目标的相似度
    Proportion float64 // 区域内的目标的占比
@@ -14,6 +14,7 @@
    AreaJson   string  // 所属区域
    IsYolo     bool    // 是否是yolo数据
    Location   Rect    // 记下每个目标的位置参数,最后给结果装配目标数据的时候用的到
    Car           *protomsg.PlateID // 车辆参数
    Feature    []byte
    ThftRes    protomsg.ThftResult
    Liker      []*BaseInfo
@@ -42,7 +43,7 @@
// sdk输出的图片上单个目标的数据
type PhotoMap struct {
    Id      uint64
    Id      string
    Rects   Rect    // 矩形区域参数
    Score   float64 // 相似度得分(有多大程度像一个目标。人脸,人体或车等等)
    IsYolo  bool    // 是否是yolo数据