panlei
2019-08-15 258ab2a39235115c037394f62783fc9ec1f8fb44
提交了时间段的判断的独立文件
3个文件已添加
2个文件已修改
469 ■■■■ 已修改文件
algorithm/face/face.go 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/intrusion/intrusion.go 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/timeSlot/timeSlot.go 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/readyDataForRule.go 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/ruleToformula.go 158 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/face/face.go
New file
@@ -0,0 +1,96 @@
package face
import (
    "basic.com/pubsub/protomsg.git"
    "github.com/knetic/govaluate"
    "ruleprocess/logger"
    "ruleprocess/ruleserver"
    "strconv"
)
func Entrance () {
}
// 过滤规则先筛选出符合条件的目标数量
func filterRule(rule *protomsg.Rule, am *ruleserver.AreaMap) ruleserver.LittleRuleResult {
        // 处理的是人脸算法 如果这条规则配置的是人脸算法,过滤完条件之后直接得出结果,因为肯定没有数量条件,自己拼接
        //logger.Info("规则的算法id和区域的算法id:", rule.SdkId, "===", am.sdkId)
        if rule.PolygonId == am.AreaId { // 算法和区域都得对的上
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && rule.SdkArgAlias != "time_rule"{
                //logger.Debug("当前小规则是:",rule)
                flag := "false"
                // 把没有相似者的人脸从filterData中删除
                for index := 0; index < len(am.FilterData); {
                    // 将达不到阈值的相似者从相似者数组中删除
                    logger.Info("看看相似者人数:",len(am.FilterData[index].Liker))
                    if len(am.FilterData[index].Liker) == 0 {
                        // Go 语言中切片删除元素的本质是:以被删除元素为分界点,将前后两个部分的内存重新连接起来。不用怀疑,数组删除元素就这么坑爹
                        am.FilterData = append(am.FilterData[:index], am.FilterData[index+1:]...)
                    } else {
                        index++
                    }
                }
                if len(am.FilterData) > 0 {
                    flag = "true"
                }
                logger.Info("---------人脸比对符合条件的数量为:",len(am.FilterData))
                return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" { // 人脸检测
                //logger.Debug("当前小规则是:",rule)
                if rule.Operator == "==" || rule.Operator == ">=" || rule.Operator == "<=" || rule.Operator == "<" || rule.Operator == ">" || rule.Operator == "!=" {
                    // 如果是不规矩的连接符统统返回false 规则也只能判断人脸的相似度,所以不存在别的连接符
                    if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
                        logger.Info("-----------------------过规则之前区域内的人脸数量为:",am.TargetNum)
                        var args []*ruleserver.Arg
                        if rule.RuleWithPre == "&&" {
                            args = am.FilterData
                            //logger.Info("过滤后的args的长度为:",len(args))
                        } else {
                            args = am.Args
                            //logger.Info("没过滤的args的长度为:",len(args))
                        }
                        // 先清空过滤后的数据,再往里塞本次过滤后的数据
                        am.FilterData = am.FilterData[0:0]
                        //logger.Info("-----------------------人脸过滤的args里的数量:", len(args))
                        for _, arg := range args {
                            var formula string
                            if rule.SdkArgAlias == "score" {
                                formula = strconv.FormatFloat(arg.Score, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                                logger.Info("当前相似度小公式:", formula)
                            } else if rule.SdkArgAlias == "proportion" {
                                formula = strconv.FormatFloat(arg.Proportion, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                                logger.Info("当前占比小公式:", formula)
                            } else {
                                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字段
                        logger.Info("过完条件后的目标数量为:",am.TargetNum)
                        if am.TargetNum > 0 {
                            logger.Info("!!!!!!!!!人脸检测成功")
                            return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                        } else {
                            return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                        }
                    } else {
                        return ruleserver.LittleRuleResult{}
                    }
                } else {
                    return ruleserver.LittleRuleResult{}
                }
            } else {
                return ruleserver.LittleRuleResult{}
            }
        } else {
            return ruleserver.LittleRuleResult{}
        }
}
algorithm/intrusion/intrusion.go
New file
@@ -0,0 +1,87 @@
package intrusion
import (
    "basic.com/pubsub/protomsg.git"
    "github.com/knetic/govaluate"
    "ruleprocess/logger"
    "ruleprocess/ruleserver"
    "strconv"
)
func Entrance() {
}
// 过滤规则先筛选出符合条件的目标数量
func filterRule(rule *protomsg.Rule, am *ruleserver.AreaMap) ruleserver.LittleRuleResult {
    // 处理的都是yolo数据
    if rule.PolygonId == am.AreaId { // 首先这条规则得是这个算法的规则,其次规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
            var args []*ruleserver.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
                if rule.SdkArgAlias == "score" {
                    formula = strconv.FormatFloat(arg.Score, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                    logger.Info("当前相似度小公式:", formula)
                } else if rule.SdkArgAlias == "proportion" {
                    formula = strconv.FormatFloat(arg.Proportion, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                    logger.Info("当前占比小公式:", formula)
                } else {
                    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 ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
            } else {
                return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
            }
        } else {
            return ruleserver.LittleRuleResult{}
        }
    } else {
        return ruleserver.LittleRuleResult{}
    }
}
// 给数据库的规则表达式代参 args: 一条子规则,区域数据
func transferParameters(rule *protomsg.Rule, am *ruleserver.AreaMap) ruleserver.LittleRuleResult {
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "objCount" { // 如果参数是要区域内目标数量 即yolo 人脸不会有数量
            //logger.Info("当前小规则是:---------", rule)
            //logger.Info("得出结果阶段", "比较的规则是:", rule)
            if rule.Operator == "" {
                return ruleserver.LittleRuleResult{am.SdkName, strconv.Itoa(am.TargetNum) + "" + rule.RuleWithPre, rule.Sort} // 如果后面不跟操作符就直接返回数量  比如要跟下一个区域比较数量的就直接返回本区域的数量
            }
            //args := am.targetNum     targetNum 已成所有目标的总数量,这里只算yolo的
            var num int = 0
            for _, data := range am.FilterData {
                if data.IsYolo {
                    num++
                }
            }
            formula := strconv.Itoa(num) + " " + rule.Operator + " " + rule.SdkArgValue
            expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
            result, _ := expression.Evaluate(nil)          // 得到数学公式的结果
            return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + " " + strconv.FormatBool(result.(bool)), rule.Sort}
            // 加上关于算法的判断条件,不能只有关于规则的,有的算法本身就是一个规则,如个体静止,靠右行,所以,拿到当前子规则的sdkid来判断是否是那些特殊的规则
        }
    }
    return ruleserver.LittleRuleResult{}
}
algorithm/timeSlot/timeSlot.go
New file
@@ -0,0 +1,96 @@
package timeSlot
import (
    "basic.com/pubsub/protomsg.git"
    "encoding/json"
    "github.com/knetic/govaluate"
    "ruleprocess/cache"
    "ruleprocess/logger"
    "ruleprocess/ruleserver"
    "time"
)
func TimeRuleResult(rule *protomsg.Rule, am *ruleserver.AreaMap) ruleserver.LittleRuleResult {
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "time_rule" { // 判断是否符合时间规
            //logger.Info("----------当前时间规则:---------", rule)
            // 根据放值字段里存的时间规则的id去另一个表里查需要比对的时间段(比如当前时间是周三,应根据区域id查出其周三的几个布防时间段,数组)
            //logger.Info("时间规则的测试")
            now := time.Now()
            index := GetIndexOfWeek(now.Weekday().String())
            timeList := GetTimeById(rule.SdkArgValue, index)
            //logger.Info("当天的时间段集合:----------", timeList)
            //logger.Info("从数据库中查出的时间规则:", timeList)
            // 判断图片数据的时间是否符合当前规则 在一个即为true,全不在为false
            if rule.Operator == "satisfy" || rule.Operator == "==" { // 满足所选的时间规则
                flag := "false"
                for _, timeSlot := range timeList {
                    formula := "'" + timeSlot.Start + "'" + "<" + "'" + am.Time + "'"
                    expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
                    result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
                    formula1 := "'" + timeSlot.End + "'" + ">" + "'" + am.Time + "'"
                    expression1, _ := govaluate.NewEvaluableExpression(formula1) // 得到数学公式
                    result1, _ := expression1.Evaluate(nil)                      // 得到数学公式的结果
                    //logger.Info("看看这两尊大神", result, result1)
                    if result.(bool) && result1.(bool) {
                        flag = "true"
                        break
                    }
                }
                return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
            if rule.Operator == "unsatisfy" || rule.Operator == "!=" { // 不满足所选的时间规则
                flag := "true"
                for _, timeSlot := range timeList {
                    formula := "'" + timeSlot.Start + "'" + " < " + "'" + am.Time + "'"
                    //logger.Info("-----------------时间规则不满足的公式start:", formula)
                    expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
                    result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
                    formula1 := "'" + timeSlot.End + "'" + " > " + "'" + am.Time + "'"
                    //logger.Info("-----------------时间规则不满足的公式end:", formula1)
                    expression1, _ := govaluate.NewEvaluableExpression(formula1) // 得到数学公式
                    result1, _ := expression1.Evaluate(nil)                      // 得到数学公式的结果
                    if result.(bool) && result1.(bool) {
                        flag = "false"
                        break
                    }
                }
                return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
        }
    }
    return ruleserver.LittleRuleResult{}
}
// 取出某个时间规则的第几天的规则段集合
func GetTimeById(id string, index int) []ruleserver.TimeRange {
    _, cameraTimeRule := cache.GetTimeRuleById(id)
    var timeRangeList []ruleserver.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
}
ruleserver/readyDataForRule.go
@@ -141,7 +141,7 @@
    Start string `json:"start"`
    End   string `json:"end"`
}
type day struct {
type Day struct {
    Day       int         `json:"day"`        // 标示当前星期几
    TimeRange []TimeRange `json:"time_range"` // 当天的几个时间段
}
@@ -166,7 +166,7 @@
}
// 给目标填充liker
func (arg *Arg) fillLiker(tableId []string, compareThreshold float32) {
func (arg *Arg) FillLiker(tableId []string, compareThreshold float32) {
    //bytes := bigCache.GetComparePersonBaseInfo(tableId, arg.Feature, compareThreshold)
    comArg := &protomsg.CompareArgs{
        TableIds:tableId,
@@ -250,9 +250,9 @@
                    logger.Info("============================================进行人脸对比")
                    for _, areaMap := range sdkData.AreaMapList {
                        // 拿区域中每个人脸特征值去对比,填充其liker
                        if groupRule.Rules[j].PolygonId == areaMap.areaId {
                        if groupRule.Rules[j].PolygonId == areaMap.AreaId {
                            //logger.Info("--------------看看compareFlag的值和tableId和areaMap.args的长度:",compareFlag,tableIds,len(areaMap.args))
                            for _, arg := range areaMap.args {
                            for _, arg := range areaMap.Args {
                                arg.Liker = arg.Liker[0:0]
                                logger.Info("清空之后看看之前打的人脸标签变了没:")
                                if args.RuleResult["face"] != nil && len(args.RuleResult["face"].([]FaceResult)) > 0 {
@@ -263,14 +263,14 @@
                                    }
                                }
                                if compareFlag == 1 {
                                    arg.fillLiker(nil, threshold)
                                    arg.FillLiker(nil, threshold)
                                }
                                if compareFlag == 2 {
                                    arg.fillLiker(tableIds, threshold)
                                    arg.FillLiker(tableIds, threshold)
                                }
                                //logger.Info("-------------------成功给liker赋值,长度为:", len(arg.Liker))
                            }
                            areaMap.filterData = areaMap.args
                            areaMap.FilterData = areaMap.Args
                            //logger.Info("=======第一次看args:",(areaMap.filterData))
                        }
                        //logger.Info("-------------------------------人脸对比之后的目标数量",len(areaMap.args))
@@ -285,29 +285,29 @@
// 计算区域内的目标数量以及将相似度、占比、尺寸等打包
func (a *AreaMap) CountAreaObjs(arg *SdkData) {
    a.targetNum = 0
    a.TargetNum = 0
    threshold := 0.0       // 相似度
    intersectionper := 0.2 // 占比
    size := 0.0            // 尺寸
    areaPoints := Json2points(a.areaJson)
    areaPoints := Json2points(a.AreaJson)
    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 threshold <= obj.Score && size <= float64(obj.Rects.Width*obj.Rects.Height) && intersectionper <= PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale) {
            // 这步要备齐表达式里所需要的所有参数
            a.targetNum++
            a.TargetNum++
            arg1 := Arg{obj.Id,obj.Score, PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), float64(obj.Rects.Width * obj.Rects.Height), obj.IsYolo, obj.Rects, obj.Feature, obj.ThftRes, []*BaseInfo{}}
            //logger.Println("放进去的arg:-------", arg1)
            a.args = append(a.args, &arg1)
            a.filterData = append(a.filterData, &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]
    a.keepRight = arg.KeepRight
    a.isStatic = arg.IsStatic
    a.Time = time.Unix(time.Now().Unix(), 0).String()[11:16]
    a.KeepRight = arg.KeepRight
    a.IsStatic = arg.IsStatic
    //logger.Println("--------------------看看区域数据:",*a)
}
@@ -319,7 +319,7 @@
    }
    for _, polygon := range cameraPolygons {
        //logger.Println("++++++在这儿看一下区域啊:", polygon.Polygon)
        areaMap := AreaMap{cameraId: cameraId, areaId: polygon.Id, areaJson: polygon.Polygon, triggerLine: polygon.TriggerLine, directionLine: polygon.DirectionLine}
        areaMap := AreaMap{CameraId: cameraId, AreaId: polygon.Id, AreaJson: polygon.Polygon, TriggerLine: polygon.TriggerLine, DirectionLine: polygon.DirectionLine}
        // 为每个摄像机区域填充数据
        areaMap.CountAreaObjs(arg)
        arg.AreaMapList = append(arg.AreaMapList, &areaMap)
ruleserver/ruleToformula.go
@@ -27,22 +27,22 @@
// 每个区域内的图片数据集合
type AreaMap struct {
    cameraId      string
    areaId        string
    groupId       string
    taskId        string
    sdkId         string
    sdkName       string
    areaJson      string
    triggerLine   string
    directionLine string
    targetNum     int    // 区域内目标数量
    args          []*Arg // 区域内目标集合
    filterData    []*Arg // 过滤后区域内目标集合
    time          string // 当前时间(用以匹配时间规则)
    isEffective      bool     // 规则中是否用到了此区域
    keepRight     bool   // 是否靠右行
    isStatic      bool   // 是否静止
    CameraId      string
    AreaId        string
    GroupId       string
    TaskId        string
    SdkId         string
    SdkName       string
    AreaJson      string
    TriggerLine   string
    DirectionLine string
    TargetNum     int    // 区域内目标数量
    Args          []*Arg // 区域内目标集合
    FilterData    []*Arg // 过滤后区域内目标集合
    Time          string // 当前时间(用以匹配时间规则)
    IsEffective   bool   // 规则中是否用到了此区域
    KeepRight     bool   // 是否靠右行
    IsStatic      bool   // 是否静止
}
// sdk输出的图片上单个目标的数据
@@ -91,7 +91,7 @@
    RuleText     string // 文字版规则组
    Location     []Rect // 目标的坐标
    AlarmPolygon string // 触发的报警框
    IsLink         bool   // 是否是联动任务
    IsLink       bool   // 是否是联动任务
    Others
}
type Others struct {
@@ -164,7 +164,7 @@
func RunRule(args *SdkDatas, groupRule *protomsg.GroupRule, taskId string, message *protomsg.SdkMessage, label Others) bool {
    defer func() {
        if err := recover(); err != nil {
            logger.Error("比对规则有误", err.(string))
            logger.Error("比对规则有误", err)
        }
    }()
    logger.Info("+++++++++++规则开始运行+++++++++++++++++当前大规则--:", (*groupRule).GroupText)
@@ -191,8 +191,8 @@
                    if ruleResult.Result != "" {
                        logger.Info("条件规则结果:", ruleResult.Result)
                        // 如果结果为真,把这条规则中的区域置为有效
                        if strings.Contains(ruleResult.Result,"true") {
                            areaMap.isEffective = true
                        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) {
@@ -223,8 +223,8 @@
                for _, areaMap := range sdkData.AreaMapList {
                    ruleResult := transferParameters(groupRule.Rules[j], areaMap)
                    if ruleResult.Result != "" {
                        if strings.Contains(ruleResult.Result,"true") {
                            areaMap.isEffective = true
                        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) {
@@ -252,8 +252,8 @@
                for _, areaMap := range sdkData.AreaMapList {
                    ruleResult := timeRuleResult(groupRule.Rules[j], areaMap)
                    if ruleResult.Result != "" {
                        if strings.Contains(ruleResult.Result,"true") {
                            areaMap.isEffective = true
                        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) {
@@ -330,7 +330,7 @@
                for _, sdkData := range args.Sdkdata {
                    if sdkData.IpcId == "A8B73405-373D-4F23-CED2-A617EBD7EC55" && faceFlag { // sdkData里有人脸数据且配置了算法才把符合条件的数据塞进标签里去
                        for _, areaMap := range sdkData.AreaMapList {
                            if areaMap.isEffective {
                            if areaMap.IsEffective {
                                faces = append(faces, putFaceToResult(areaMap, faces)...)
                            }
                        }
@@ -357,11 +357,11 @@
                    islink = false
                }
                if sdkNames != "" {
                    args.RuleResult["yolo"] = append(args.RuleResult["yolo"].([]Result), Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, locations, polygonId, islink,label,})
                    args.RuleResult["yolo"] = append(args.RuleResult["yolo"].([]Result), Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, locations, polygonId, islink, label,})
                    //logger.Info("-------------------yolo结果标签长度", len(args.RuleResult["yolo"].([]Result)))
                }
                if faceFlag {
                    args.RuleResult["face"] = append(args.RuleResult["face"].([]FaceResult), FaceResult{Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, []Rect{}, polygonId, islink,label,}, faces})
                    args.RuleResult["face"] = append(args.RuleResult["face"].([]FaceResult), FaceResult{Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, []Rect{}, polygonId, islink, label,}, faces})
                    //logger.Info("-------------------face结果标签", len(args.RuleResult["face"].([]FaceResult)))
                }
                return true
@@ -382,8 +382,8 @@
func putFaceToResult(am *AreaMap, faceList []Arg) []Arg {
    faces := []Arg{}
    if len(am.filterData) > 0 {
        for _, data := range am.filterData {
    if len(am.FilterData) > 0 {
        for _, data := range am.FilterData {
            flag := true
            for _, face := range faceList {
                if data.Location.X == face.Location.X && data.Location.Y == face.Location.Y && data.Location.Width == face.Location.Width && data.Location.Height == face.Location.Height {
@@ -401,8 +401,8 @@
func putYolosToResult(am *AreaMap) []Rect {
    locations := []Rect{}
    if len(am.filterData) > 0 {
        for _, data := range am.filterData {
    if len(am.FilterData) > 0 {
        for _, data := range am.FilterData {
            locations = append(locations, data.Location)
        }
    }
@@ -491,7 +491,7 @@
                result, _ := expression.Evaluate(nil) // 得到数学公式的结果
                if result.(bool) {
                    logger.Info("___________________________________________________________________联动任务报警")
                    if TimeEleList[groupRule.GroupId] != nil {  // 极偶尔有情况会等于nil,不知道为啥,做个判断以防宕机
                    if TimeEleList[groupRule.GroupId] != nil { // 极偶尔有情况会等于nil,不知道为啥,做个判断以防宕机
                        // 把数组里缓存的数据取出来一起报警
                        label.LinkCache = []ResultMsg{}
                        for _, ruleRes := range TimeEleList[groupRule.GroupId].RuleResults {
@@ -514,7 +514,7 @@
        } else {
            logger.Warn("数组不圆满不打标签")
            // 倒是把打的组规则标签给去掉了啊
            lens := len(args.RuleResult["yolo"].([]Result))-1
            lens := len(args.RuleResult["yolo"].([]Result)) - 1
            args.RuleResult["yolo"] = args.RuleResult["yolo"].([]Result)[0:lens]
        }
    } else { // 没有报警,
@@ -541,44 +541,44 @@
    if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" || rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" {
        // 处理的是人脸算法 如果这条规则配置的是人脸算法,过滤完条件之后直接得出结果,因为肯定没有数量条件,自己拼接
        //logger.Info("规则的算法id和区域的算法id:", rule.SdkId, "===", am.sdkId)
        if rule.PolygonId == am.areaId { // 算法和区域都得对的上
        if rule.PolygonId == am.AreaId { // 算法和区域都得对的上
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && rule.SdkArgAlias != "time_rule"{
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && rule.SdkArgAlias != "time_rule" {
                //logger.Debug("当前小规则是:",rule)
                flag := "false"
                // 把没有相似者的人脸从filterData中删除
                for index := 0; index < len(am.filterData); {
                for index := 0; index < len(am.FilterData); {
                    // 将达不到阈值的相似者从相似者数组中删除
                    logger.Info("看看相似者人数:",len(am.filterData[index].Liker))
                    if len(am.filterData[index].Liker) == 0 {
                    logger.Info("看看相似者人数:", len(am.FilterData[index].Liker))
                    if len(am.FilterData[index].Liker) == 0 {
                        // Go 语言中切片删除元素的本质是:以被删除元素为分界点,将前后两个部分的内存重新连接起来。不用怀疑,数组删除元素就这么坑爹
                        am.filterData = append(am.filterData[:index], am.filterData[index+1:]...)
                        am.FilterData = append(am.FilterData[:index], am.FilterData[index+1:]...)
                    } else {
                        index++
                    }
                }
                if len(am.filterData) > 0 {
                if len(am.FilterData) > 0 {
                    flag = "true"
                }
                logger.Info("---------人脸比对符合条件的数量为:",len(am.filterData))
                return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + flag, rule.Sort}
                logger.Info("---------人脸比对符合条件的数量为:", len(am.FilterData))
                return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" { // 人脸检测
                //logger.Debug("当前小规则是:",rule)
                if rule.Operator == "==" || rule.Operator == ">=" || rule.Operator == "<=" || rule.Operator == "<" || rule.Operator == ">" || rule.Operator == "!=" {
                    // 如果是不规矩的连接符统统返回false 规则也只能判断人脸的相似度,所以不存在别的连接符
                    if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
                        logger.Info("-----------------------过规则之前区域内的人脸数量为:",am.targetNum)
                        logger.Info("-----------------------过规则之前区域内的人脸数量为:", am.TargetNum)
                        var args []*Arg
                        if rule.RuleWithPre == "&&" {
                            args = am.filterData
                            args = am.FilterData
                            //logger.Info("过滤后的args的长度为:",len(args))
                        } else {
                            args = am.args
                            args = am.Args
                            //logger.Info("没过滤的args的长度为:",len(args))
                        }
                        // 先清空过滤后的数据,再往里塞本次过滤后的数据
                        am.filterData = am.filterData[0:0]
                        am.FilterData = am.FilterData[0:0]
                        //logger.Info("-----------------------人脸过滤的args里的数量:", len(args))
                        for _, arg := range args {
                            var formula string
@@ -595,16 +595,16 @@
                            expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
                            result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
                            if result.(bool) {
                                am.filterData = append(am.filterData, arg) // 得到符合条件的过滤数据
                                am.FilterData = append(am.FilterData, arg) // 得到符合条件的过滤数据
                            }
                        }
                        am.targetNum = len(am.filterData) // 把符合条件的目标数量更新到targetNum字段
                        logger.Info("过完条件后的目标数量为:",am.targetNum)
                        if am.targetNum > 0 {
                        am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段
                        logger.Info("过完条件后的目标数量为:", am.TargetNum)
                        if am.TargetNum > 0 {
                            logger.Info("!!!!!!!!!人脸检测成功")
                            return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                            return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                        } else {
                            return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                            return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                        }
                    } else {
                        return LittleRuleResult{}
@@ -620,16 +620,16 @@
        }
    } else {
        // 处理的都是yolo数据
        if rule.PolygonId == am.areaId { // 首先这条规则得是这个算法的规则,其次规则所对应的区域id要跟区域数据的id对的上
        if rule.PolygonId == am.AreaId { // 首先这条规则得是这个算法的规则,其次规则所对应的区域id要跟区域数据的id对的上
            if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
                var args []*Arg
                if rule.RuleWithPre == "&&" {
                    args = am.filterData
                    args = am.FilterData
                } else {
                    args = am.args
                    args = am.Args
                }
                // 先清空过滤后的数据,再往里塞本次过滤后的数据
                am.filterData = am.filterData[0:0]
                am.FilterData = am.FilterData[0:0]
                //logger.Debug("看看args:::::", args)
                for _, arg := range args {
                    var formula string
@@ -646,14 +646,14 @@
                    expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
                    result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
                    if result.(bool) {
                        am.filterData = append(am.filterData, arg) // 得到符合条件的过滤数据
                        am.FilterData = append(am.FilterData, arg) // 得到符合条件的过滤数据
                    }
                }
                am.targetNum = len(am.filterData) // 把符合条件的目标数量更新到targetNum字段
                if am.targetNum > 0 {
                    return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段
                if am.TargetNum > 0 {
                    return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                } else {
                    return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                    return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                }
            } else {
@@ -668,7 +668,7 @@
// 如果有持续时间条件维护开启一个定时器
func duration(rule *protomsg.Rule, groupId string, am *AreaMap, args *SdkDatas, message *protomsg.SdkMessage) {
    if rule.PolygonId == am.areaId { // 首先规则所对应的区域id要跟区域数据的id对的上  配置的算法要对的上
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上  配置的算法要对的上
        if rule.SdkArgAlias == "duration" { //
            logger.Info("当前小规则是:---------", rule)
            // 先看看定时器元素队列中是否有这条规则的定时器,如果有就不能再次创建了
@@ -693,16 +693,16 @@
// 给数据库的规则表达式代参 args: 一条子规则,区域数据
func transferParameters(rule *protomsg.Rule, am *AreaMap) LittleRuleResult {
    if rule.PolygonId == am.areaId { // 首先规则所对应的区域id要跟区域数据的id对的上
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "objCount" { // 如果参数是要区域内目标数量 即yolo 人脸不会有数量
            //logger.Info("当前小规则是:---------", rule)
            //logger.Info("得出结果阶段", "比较的规则是:", rule)
            if rule.Operator == "" {
                return LittleRuleResult{am.sdkName, strconv.Itoa(am.targetNum) + "" + rule.RuleWithPre, rule.Sort} // 如果后面不跟操作符就直接返回数量  比如要跟下一个区域比较数量的就直接返回本区域的数量
                return LittleRuleResult{am.SdkName, strconv.Itoa(am.TargetNum) + "" + rule.RuleWithPre, rule.Sort} // 如果后面不跟操作符就直接返回数量  比如要跟下一个区域比较数量的就直接返回本区域的数量
            }
            //args := am.targetNum     targetNum 已成所有目标的总数量,这里只算yolo的
            var num int = 0
            for _, data := range am.filterData {
            for _, data := range am.FilterData {
                if data.IsYolo {
                    num++
                }
@@ -710,26 +710,14 @@
            formula := strconv.Itoa(num) + " " + rule.Operator + " " + rule.SdkArgValue
            expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
            result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
            return LittleRuleResult{am.sdkName, rule.RuleWithPre + " " + strconv.FormatBool(result.(bool)), rule.Sort}
            return LittleRuleResult{am.SdkName, rule.RuleWithPre + " " + strconv.FormatBool(result.(bool)), rule.Sort}
            // 加上关于算法的判断条件,不能只有关于规则的,有的算法本身就是一个规则,如个体静止,靠右行,所以,拿到当前子规则的sdkid来判断是否是那些特殊的规则
        } else if rule.SdkId == "IsStatic" { // 静止算法
            if am.isStatic {
                return LittleRuleResult{}
            } else {
                return LittleRuleResult{}
            }
        } else if rule.SdkId == "KeepRight" { // 靠右行算法
            if am.keepRight {
                return LittleRuleResult{}
            } else {
                return LittleRuleResult{}
            }
        }
    }
    return LittleRuleResult{}
}
func timeRuleResult(rule *protomsg.Rule, am *AreaMap) LittleRuleResult {
    if rule.PolygonId == am.areaId { // 首先规则所对应的区域id要跟区域数据的id对的上
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "time_rule" { // 判断是否符合时间规
            //logger.Info("----------当前时间规则:---------", rule)
            // 根据放值字段里存的时间规则的id去另一个表里查需要比对的时间段(比如当前时间是周三,应根据区域id查出其周三的几个布防时间段,数组)
@@ -744,11 +732,11 @@
            if rule.Operator == "satisfy" || rule.Operator == "==" { // 满足所选的时间规则
                flag := "false"
                for _, timeSlot := range timeList {
                    formula := "'" + timeSlot.Start + "'" + "<" + "'" + am.time + "'"
                    formula := "'" + timeSlot.Start + "'" + "<" + "'" + am.Time + "'"
                    expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
                    result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
                    formula1 := "'" + timeSlot.End + "'" + ">" + "'" + am.time + "'"
                    formula1 := "'" + timeSlot.End + "'" + ">" + "'" + am.Time + "'"
                    expression1, _ := govaluate.NewEvaluableExpression(formula1) // 得到数学公式
                    result1, _ := expression1.Evaluate(nil)                      // 得到数学公式的结果
                    //logger.Info("看看这两尊大神", result, result1)
@@ -757,18 +745,18 @@
                        break
                    }
                }
                return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + flag, rule.Sort}
                return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
            if rule.Operator == "unsatisfy" || rule.Operator == "!=" { // 不满足所选的时间规则
                flag := "true"
                for _, timeSlot := range timeList {
                    formula := "'" + timeSlot.Start + "'" + " < " + "'" + am.time + "'"
                    formula := "'" + timeSlot.Start + "'" + " < " + "'" + am.Time + "'"
                    //logger.Info("-----------------时间规则不满足的公式start:", formula)
                    expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
                    result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
                    formula1 := "'" + timeSlot.End + "'" + " > " + "'" + am.time + "'"
                    formula1 := "'" + timeSlot.End + "'" + " > " + "'" + am.Time + "'"
                    //logger.Info("-----------------时间规则不满足的公式end:", formula1)
                    expression1, _ := govaluate.NewEvaluableExpression(formula1) // 得到数学公式
                    result1, _ := expression1.Evaluate(nil)                      // 得到数学公式的结果
@@ -777,7 +765,7 @@
                        break
                    }
                }
                return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + flag, rule.Sort}
                return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
        }