New file |
| | |
| | | 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{} |
| | | } |
| | | } |
New file |
| | |
| | | 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{} |
| | | } |
New file |
| | |
| | | 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 |
| | | } |
| | |
| | | Start string `json:"start"` |
| | | End string `json:"end"` |
| | | } |
| | | type day struct { |
| | | type Day struct { |
| | | Day int `json:"day"` // 标示当前星期几 |
| | | TimeRange []TimeRange `json:"time_range"` // 当天的几个时间段 |
| | | } |
| | |
| | | } |
| | | |
| | | // 给目标填充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, |
| | |
| | | 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 { |
| | |
| | | } |
| | | } |
| | | 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)) |
| | |
| | | // 计算区域内的目标数量以及将相似度、占比、尺寸等打包 |
| | | 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) |
| | | } |
| | | |
| | |
| | | } |
| | | 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) |
| | |
| | | |
| | | // 每个区域内的图片数据集合 |
| | | 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输出的图片上单个目标的数据 |
| | |
| | | RuleText string // 文字版规则组 |
| | | Location []Rect // 目标的坐标 |
| | | AlarmPolygon string // 触发的报警框 |
| | | IsLink bool // 是否是联动任务 |
| | | IsLink bool // 是否是联动任务 |
| | | Others |
| | | } |
| | | type Others struct { |
| | |
| | | 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) |
| | |
| | | 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) { |
| | |
| | | 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) { |
| | |
| | | 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) { |
| | |
| | | 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)...) |
| | | } |
| | | } |
| | |
| | | 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 |
| | |
| | | |
| | | 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 { |
| | |
| | | |
| | | 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) |
| | | } |
| | | } |
| | |
| | | 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 { |
| | |
| | | } 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 { // 没有报警, |
| | |
| | | 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 |
| | |
| | | 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{} |
| | |
| | | } |
| | | } 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 |
| | |
| | | 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 { |
| | |
| | | |
| | | // 如果有持续时间条件维护开启一个定时器 |
| | | 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) |
| | | // 先看看定时器元素队列中是否有这条规则的定时器,如果有就不能再次创建了 |
| | |
| | | |
| | | // 给数据库的规则表达式代参 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++ |
| | | } |
| | |
| | | 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查出其周三的几个布防时间段,数组) |
| | |
| | | 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) |
| | |
| | | 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) // 得到数学公式的结果 |
| | |
| | | break |
| | | } |
| | | } |
| | | return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + flag, rule.Sort} |
| | | return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort} |
| | | } |
| | | |
| | | } |