panlei
2019-06-25 34b957a021cba44dfbae128a555cdc4dbc82079c
ruleserver/ruleToformula.go
@@ -3,6 +3,7 @@
import (
   "encoding/json"
   "fmt"
   "log"
   "sort"
   "strconv"
   "strings"
@@ -60,6 +61,12 @@
   score      float64 // 区域内的目标的相似度
   proportion float64 // 区域内的目标的占比
   size       float64 // 区域内的目标的尺寸
   liker      []LikePerson
}
type LikePerson struct {
   Id    string  // 与之相似的底库人员的id
   Score float64 // 与底库人员的相似值
}
// 每个区域内的图片数据集合
@@ -83,7 +90,8 @@
// sdk输出的图片上单个目标的数据
type PhotoMap struct {
   Rects Rect    // 矩形区域参数
   Score float64 // 相似度得分
   Score float64 // 相似度得分(有多大程度像一个目标。人脸,人体或车等等)
   Liker []LikePerson // 如果是人脸的话尤其是比对,应存下他跟底库的人员的相似情况 yolo的话给nil就行
}
// 从通道中获取的sdk输出的图像数据(目前主要是yolo算法的数据)
@@ -110,7 +118,7 @@
type Result struct {
   TaskId      string // 任务id
   RuleGroupId string // 规则组id
   AlarmLevel  int32 // 报警等级
   AlarmLevel  int32  // 报警等级
   RuleText    string // 文字版规则组
}
@@ -175,9 +183,10 @@
         intersectionper <= PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale) {
         // 这步要备齐表达式里所需要的所有参数
         a.targetNum++
         arg := Arg{score: obj.Score, proportion: PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), size: float64(obj.Rects.Width * obj.Rects.Height)}
         a.args = append(a.args, arg)
         a.filterData = append(a.filterData, arg)
         arg1 := Arg{score: obj.Score, proportion: PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), size: float64(obj.Rects.Width * obj.Rects.Height)}
         log.Println("放进去的arg:-------",arg1)
         a.args = append(a.args, arg1)
         a.filterData = append(a.filterData, arg1)
      }
   }
   a.time = time.Unix(time.Now().Unix(), 0).String()[11:16]
@@ -188,11 +197,17 @@
// 将字符串格式的坐标序列化为Point格式
func Json2points(areaPoints string) []Point {
   var pts []Point
   err := json.Unmarshal([]byte(areaPoints), &pts)
   if err != nil {
      fmt.Println("json.Unmarshal错误", err)
      panic("序列化坐标异常,程序退出")
   if areaPoints == "" {
      pts = append(pts, Point{0, 0})
      pts = append(pts, Point{0, 540})
      pts = append(pts, Point{960, 540})
      pts = append(pts, Point{960, 0})
   } else {
      err := json.Unmarshal([]byte(areaPoints), &pts)
      if err != nil {
         fmt.Println("json.Unmarshal错误", err)
         panic("序列化坐标异常,程序退出")
      }
   }
   return pts
}
@@ -295,6 +310,7 @@
func singleTask(aml *AreaMapList, arg *ArgsFromSdk, groupRule *protomsg.GroupRule, taskId string) bool {
   var completeFormula string = ""
   for _, areaMap := range aml.areaMapList {
      //fmt.Println("当前规则组为---------:",groupRule)
      for j := 0; j < len(groupRule.Rules); j++ {
         // 先过完条件数据
         filterRule(groupRule.Rules[j], &areaMap)
@@ -311,9 +327,8 @@
         flag := splice1(&areaMap)
         if flag != "" {
            fmt.Println("强行拼凑一个人数是否大于0的结果", flag)
            completeFormula = completeFormula + groupRule.Rules[j].RuleWithPre + "" + flag
            completeFormula = flag
         }
      }
      for j := 0; j < len(groupRule.Rules); j++ {
         // 这步过的是时间规则(时间段等)
@@ -334,7 +349,7 @@
   if completeFormula != "" {
      expression, _ := govaluate.NewEvaluableExpression(completeFormula)
      result, _ := expression.Evaluate(nil) // 得到数学公式的结果
      fmt.Println("这帧图像在任务下的除了持续时间外的一整条规则下的判断结果", result)
      //fmt.Println("这帧图像在任务下的除了持续时间外的一整条规则下的判断结果", result)
      // 由于天然或的关系,满足一个就该报警,即该帧数据对于某个任务的某个规则组应该报警
      if !result.(bool) { // 如果不符合条件,应该重置定时器元素,等符合时再开启,把key中包含任务id的timeEle都重置
         for k, timeEle := range TimeEleList {
@@ -356,7 +371,7 @@
         if flag {
            fmt.Println("定时器报警了")
            // 过完规则后打个标签,告诉调用者本帧数据针对哪个任务哪组规则报警了
            arg.RuleResult = append(arg.RuleResult, Result{taskId, groupRule.GroupId,groupRule.AlarmLevel,groupRule.GroupText})
            arg.RuleResult = append(arg.RuleResult, Result{taskId, groupRule.GroupId, groupRule.AlarmLevel, groupRule.GroupText})
            return true
         } else {
            return false
@@ -404,17 +419,19 @@
         }
         // 先清空过滤后的数据,再往里塞本次过滤后的数据
         am.filterData = am.filterData[0:0]
         log.Println("看一下当前小规则:",*rule)
         for _, arg := range args {
            var formula string
            if rule.SdkArgAlias == "score" {
               formula = strconv.FormatFloat(arg.score, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
            } else if rule.SdkArgAlias == "proportion" {
               formula = strconv.FormatFloat(arg.proportion, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
               fmt.Println("占比的字符串公式:--------",formula)
            } else {
               formula = strconv.FormatFloat(arg.size, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
            }
            expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
            result, _ := expression.Evaluate(nil)          // 得到数学公式的结果
            result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
            if result.(bool) {
               am.filterData = append(am.filterData, arg) // 得到符合条件的过滤数据
            }
@@ -447,14 +464,17 @@
      }
   }
}
// 冗余拼接
func splice1 (am *AreaMap) string {
func splice1(am *AreaMap) string {
   args := am.targetNum
   formula := strconv.Itoa(args) + " "  + ">" + "0"
   log.Println("看看区域内目标数量:----------",args)
   formula := strconv.Itoa(args) + " " + ">" + "0"
   expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
   result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
   return strconv.FormatBool(result.(bool))
}
// 给数据库的规则表达式代参 args: 一条子规则,区域数据
func transferParameters(rule *protomsg.Rule, am *AreaMap) string {
   if rule.PolygonId == am.areaId { // 首先规则所对应的区域id要跟区域数据的id对的上
@@ -484,11 +504,13 @@
      } else if rule.SdkId == "FaceDetect" { // 人脸检测
         if rule.Operator == "==" || rule.Operator == ">=" || rule.Operator == "<=" || rule.Operator == "<" || rule.Operator == ">" || rule.Operator == "!=" {
            // 如果是不规矩的连接符统统返回false 规则也只能判断人脸的相似度,所以不存在别的连接符
            return "false"
         } else {
            return "false"
         }
      } else {
      } else if rule.SdkId == "FaceCompare"{
         // 只需要过滤阈值,过滤完后数组长度大于0即为报警,但如何对每一张都报警呢
      }