panlei
2019-07-11 77325e345bf0e9a2c2d8f6b660ffcfb5b4f48aab
ruleserver/ruleToformula.go
@@ -163,30 +163,17 @@
// 根据摄像机id拿到摄像机所有区域
func GetPolygons(cameraId string) []protomsg.CameraPolygon {
   //var api dbapi.CameraApi
   //data := api.FindAllPolygons()
   ////logger.Info("查到的所有区域:", data)
   //// 根据id从map中拿到区域
   var cameraPolygons []protomsg.CameraPolygon
   //for _, item := range data {
   //   if item.CameraId == cameraId && item.Type != "line" {
   //      // 需要根据比例把前台画的区域的坐标转化为相应摄像机拍摄的图像的大小   x坐标分别*image.width/页面区域宽  y坐标分别*image.height/页面区域高
   //      // 前台宽高固定
   //      //logger.Println("------------符合条件的区域:",item)
   //      cameraPolygons = append(cameraPolygons, item)
   //   }
   //}
   cameraPolygons = cache.GetPolygonsByCameraId(cameraId)
   //logger.Println("根据摄像机id查到的区域", cameraPolygons, "--区域数量为:", len(cameraPolygons))
   return cameraPolygons
}
// 把sdk从数据帧上提取的按照区域分类归置
func SdkDataFormat(cameraId string, arg *SdkData, cameraPolygons []protomsg.CameraPolygon) {
   logger.Info("==================================本sdkData中解出来的目标数据=======================================")
   for _,photo := range arg.Photo{
      logger.Info("--------看看解析出来的数据---", cameraId,arg.IpcId,photo.Rects,photo.Score)
   for _, photo := range arg.Photo {
      logger.Info("--------看看解析出来的数据---", cameraId, arg.IpcId, photo.Rects, photo.Score)
   }
   for _, polygon := range cameraPolygons {
      //logger.Println("++++++在这儿看一下区域啊:", polygon.Polygon)
@@ -197,7 +184,7 @@
   }
}
// 对单帧图像的判断 是舍弃(或者说对于某些需求可以放ES数据库一份)还是返回
// 对单帧图像的判断 thisSdkDatas  当前传入的这帧数据,cacheSdkData 定时器里缓存的一帧数据 没有就返回nil  (thisSdkDatas SdkDatas, cacheSdkDatas SdkDatas)
func Judge(args *SdkDatas) {
   if len(args.Sdkdata) > 0 {
      // 拿到本摄像机的区域
@@ -250,17 +237,17 @@
         }
      }
   }
   // 作弊,直接让其比对全部底库
   // 为了测试作下弊,直接让其比对全部底库
   compareFlag = 1
   if compareFlag == 0 {
      logger.Info("没有配置对比底库参数")
      return
   }
   for j := 0; j < len(groupRule.Rules); j++ {
      // 只有是人脸对比并且配置的参数是对比底库才走(若配的对比阈值则不走)
      if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972"{
      if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" {
         for _, sdkData := range args.Sdkdata {
            if sdkData.IpcId == "812b674b-2375-4589-919a-5c1c3278a97e" { // 搜索到人脸检测的sdkdata 现在关于人脸的只有他一个sdk,全找他
            if sdkData.IpcId == "A8B73405-373D-4F23-CED2-A617EBD7EC55" { // 搜索到人脸检测的sdkdata 现在关于人脸的只有他一个sdk,全找他
               logger.Info("============================================第一关")
               for _, areaMap := range sdkData.AreaMapList {
                  // 拿区域中每个人脸特征值去对比,填充其liker
                  if groupRule.Rules[j].PolygonId == areaMap.areaId {
@@ -272,10 +259,12 @@
                           if err1 != nil {
                              logger.Error("getBaseInfo解压错误", err1)
                           }
                           logger.Info("----------------------------------------map是", m)
                           for key, val := range m {
                              baseinfo,err1 := esutil.Dbpersoninfosbyid(key)
                              logger.Info("_______________________________________对比库的返回值", key, val)
                              baseinfo, err1 := esutil.Dbpersoninfosbyid(key)
                              if err1 != nil {
                                 logger.Error("查询底库人员信息出错",err1)
                                 logger.Error("查询底库人员信息出错", err1)
                              }
                              baseinfo.CompareScore = val
                              arg.Liker = append(arg.Liker, &baseinfo)
@@ -293,15 +282,16 @@
                              for key, val := range m {
                                 baseinfo, err1 := esutil.Dbpersoninfosbyid(key)
                                 if err1 != nil {
                                    logger.Error("查询底库人员信息出错",err1)
                                    logger.Error("查询底库人员信息出错", err1)
                                 }
                                 baseinfo.CompareScore = val
                                 arg.Liker = append(arg.Liker, &baseinfo)
                              }
                           }
                        }
                        logger.Info("-------------------成功给liker赋值:", arg.Liker)
                        logger.Info("-------------------成功给liker赋值,长度为:", len(arg.Liker))
                     }
                     areaMap.filterData = areaMap.args
                  }
               }
            }
@@ -315,7 +305,7 @@
         logger.Error("比对规则有误", err.(string))
      }
   }()
   logger.Info("+++++++++++规则开始运行+++++++++++++++++当前规则--:", *groupRule)
   logger.Info("+++++++++++规则开始运行+++++++++++++++++当前大规则--:", *groupRule)
   Compare(args, groupRule)
   resultSplice := []*LittleRuleResult{}
   sdkNames := ""
@@ -329,7 +319,7 @@
         }
         ipcId := sdk.IpcId
         sdkName := sdk.SdkName
         logger.Info("规则的ipcId与sdkData的IpcId:",ipcId,"===",sdkData.IpcId)
         if ipcId == sdkData.IpcId {
            logger.Info("当前走的规则的算法是--:", sdkName, "---")
            for _, areaMap := range sdkData.AreaMapList {
@@ -404,7 +394,8 @@
         ipcId := sdk.IpcId
         if ipcId == sdkData.IpcId {
            for _, areaMap := range sdkData.AreaMapList {
               duration(groupRule.Rules[j], &areaMap)
               // 去开启一个定时器
               duration(groupRule.Rules[j], groupRule.GroupId, &areaMap, args)
            }
         }
      }
@@ -440,63 +431,54 @@
         // 给这帧数据打上规则组标签
         //args.RuleResult = append(args.RuleResult, Result{TaskId: taskId, RuleGroupId: groupRule.GroupId})
         for k, timeEle := range TimeEleList {
            if strings.Contains(k, taskId) {
            if strings.Contains(k, groupRule.GroupId) {
               timeEle.N = timeEle.InitN // 重置定时器
            }
         }
         logger.Info("-------------------重置可能存在的定时器并返回false---------------")
         logger.Info("-------------------重置相关的定时器并返回false---------------")
         return false
      } else {
         // 最后成功报警才把符合条件的人脸数据塞进结果标签里
         faces := []Arg{}
         for _, sdkData := range args.Sdkdata {
            for _, areaMap := range sdkData.AreaMapList {
               for j := 0; j < len(groupRule.Rules); j++ {
                  faces = append(faces, putFaceToResult(groupRule.Rules[j], &areaMap)...)
               }
            }
         }
         // 配了人脸的算法才把人脸的数据甩出来打标签
         flag11 := false
         for j := 0; j < len(groupRule.Rules); j++ {
            if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" || groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" {
               flag11 = true
            }
         }
         if flag11 {
            args.RuleResult["face"] = faces
         }
         // 去看池子里是否有与本帧数据有关的定时器,如果有,看此时是否走到0,没有此定时器或有定时器走到0的话返回成功报警
         // 判断持续时间条件,去看池子里是否有与本帧数据有关的定时器,如果有,看此时是否走到0,没有此定时器或有定时器走到0的话返回成功报警
         var flag bool = true
         for k, timeEle := range TimeEleList {
            if strings.Contains(k, taskId) {
               if timeEle.N != 0 { // 跟这个任务有关的定时器要全部等于0
            if strings.Contains(k, groupRule.GroupId) {
               if timeEle.N != 0 { // 这组规则的定时器要全部等于0
                  logger.Info("———————————-------------不冤,你是被定时器打败的:")
                  flag = false
               }
            }
         }
         if flag {
            // 最后成功报警才把符合条件的人脸数据塞进结果标签里
            // 配了人脸的算法才把人脸的数据甩出来打标签
            logger.Info("------------------------------最后一关")
            faces := []Arg{}
            faceFlag := false
            for j := 0; j < len(groupRule.Rules); j++ {
               if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" || groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" {
                  faceFlag = true
               }
            }
            for _, sdkData := range args.Sdkdata {
               if sdkData.IpcId == "A8B73405-373D-4F23-CED2-A617EBD7EC55" && faceFlag { // sdkData里有人脸数据且配置了算法才把符合条件的数据塞进标签里去
                  for _, areaMap := range sdkData.AreaMapList {
                     faces = append(faces, putFaceToResult(&areaMap)...)
                  }
               }
            }
            if faceFlag {
               args.RuleResult["face"] = faces
            }
            logger.Warn("___________________________________________________________________________终于走完万里长征")
            // 把他们的位置数据也传下去
            locations := []Rect{}
            for _, sdkData := range args.Sdkdata {
               for _, areaMap := range sdkData.AreaMapList {
                  for j := 0; j < len(groupRule.Rules); j++ {
                     locations = append(locations, putYolosToResult(groupRule.Rules[j], &areaMap)...)
               if sdkData.IpcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && sdkNames != "" { // 把yolo数据的各个目标的坐标输出方便后面画框
                  for _, areaMap := range sdkData.AreaMapList {
                     locations = append(locations, putYolosToResult(&areaMap)...)
                  }
               }
            }
            //// 配了人脸的算法才把人脸的数据甩出来打标签
            //flag11 := false
            //for j := 0; j < len(groupRule.Rules); j++ {
            //   if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" || groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a971" {
            //      flag11 = true
            //   }
            //}
            //if flag11 {
            //   args.RuleResult["face"] = faces
            //}
            if sdkNames != "" {
               args.RuleResult["yolo"] = append(args.RuleResult["yolo"].([]Result), Result{taskId, sdkNames, groupRule.GroupId, groupRule.AlarmLevel, groupRule.GroupText, locations})
               logger.Info("-------------------yolo结果标签", args.RuleResult["yolo"].([]Result))
@@ -513,27 +495,41 @@
      return false
   }
}
func putFaceToResult(rule *protomsg.Rule, am *AreaMap) []Arg {
   faces := []Arg{}
   if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" || rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" {
      if len(am.filterData) > 0 {
         for _, data := range am.filterData {
            faces = append(faces, data)
func TimerAlarm(groupId string) (int){
   var flagTime int = 0
   for k, timeEle := range TimeEleList {
      if strings.Contains(k, groupId) {
         if timeEle.N == 0 && !timeEle.AlarmFlag { // 这组规则的定时器要全部等于0   暂且认为一组规则只有一个定时器
            logger.Info("———————————-------------首次符合持续时间规则并报警")
            flagTime = 1
            timeEle.AlarmFlag = true
         }
         if timeEle.N == 0 && timeEle.AlarmFlag {
            logger.Info("-------------------------符合持续时间规则但并不是首次,不报警")
            flagTime = 2
         }
      }
   }
   return flagTime
}
func putFaceToResult(am *AreaMap) []Arg {
   faces := []Arg{}
   if len(am.filterData) > 0 {
      for _, data := range am.filterData {
         faces = append(faces, data)
      }
   }
   //logger.Println("-----------------------------------------------听说你是空的?",faces)
   return faces
}
func putYolosToResult(rule *protomsg.Rule, am *AreaMap) []Rect {
func putYolosToResult(am *AreaMap) []Rect {
   locations := []Rect{}
   if rule.SdkId != "812b674b-2375-4589-919a-5c1c3278a97e" && rule.SdkId != "812b674b-2375-4589-919a-5c1c3278a972" {
      if len(am.filterData) > 0 {
         for _, data := range am.filterData {
            locations = append(locations, data.Location)
         }
   if len(am.filterData) > 0 {
      for _, data := range am.filterData {
         locations = append(locations, data.Location)
      }
   }
   //logger.Println("-----------------------------------------------听说你是空的?",faces)
@@ -551,12 +547,6 @@
   areaPoints := Json2points(a.areaJson)
   widthScale := float64(arg.ImageWidth / 960)
   heigthScale := float64(arg.ImageHeight / 540)
   // for _, sdkInfo := range arg.SdkMessage.Tasklab.Sdkinfos {
   //    if sdkInfo.Sdktype == "yolo" {
   //       //sdkInfo.Sdkdata.
   //    }
   // }
   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) {
@@ -594,17 +584,6 @@
// 以摄像机id查出跟其相关的所有任务下的所有规则组
func GetRuleGroup(cameraId string) []*protomsg.TaskGroupArgs {
   // 查询数据库
   // 第一步查出跟这个摄像机相关的group_id(大规则)
   //var api dbapi.CameraTaskArgsApi
   //
   ////logger.Info("所有规则:", all)
   //var taskArgs []*protomsg.TaskGroupArgs
   //for _, camArg := range all {
   //   if camArg.CameraId == cameraId {
   //      taskArgs = camArg.TaskArgs
   //   }
   //}
   all := cache.GetCameraTaskRulesByCameraId(cameraId)
   return all
}
@@ -674,9 +653,9 @@
            if result.(bool) {
               logger.Info("___________________________________________________________________联动任务报警")
               args.RuleResult["yolo"] = append(args.RuleResult["yolo"].([]Result), Result{taskId, "", groupRule.GroupId, groupRule.AlarmLevel, groupRule.GroupText, []Rect{}})
               logger.Info("-------------------yolo结果标签", args.RuleResult["yolo"].([]Result))
               logger.Info("-------------------yolo结果标签有几个", len(args.RuleResult["yolo"].([]Result)))
               if args.RuleResult["face"] != nil {
                  logger.Info("-------------------face结果标签", args.RuleResult["face"].([]Arg))
                  logger.Info("-------------------face结果标签有几个", len(args.RuleResult["face"].([]Arg)))
               }
               //os.Exit(0)
            }
@@ -688,7 +667,7 @@
      logger.Info("这帧图像在任务下的一整条规则下(联动任务下就是跟本摄像机像相关的小规则)的判断结果为false")
      // 所以也要去结果数组里放值或更新
      for _, va := range timeEle.RuleResults {
         if args.CameraId != "" && va.CameraId == args.CameraId { // arg.CameraId 随便找一个数据
         if args.CameraId != "" && va.CameraId == args.CameraId {
            va.Result = strconv.FormatBool(isOk)
         }
      }
@@ -704,7 +683,7 @@
      if rule.PolygonId == am.areaId { // 算法和区域都得对的上
         if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && rule.SdkArgAlias != "time_rule" {
            // 只需要过滤阈值,过滤完后数组长度大于0即为报警,但要考虑如何对每一张都报警呢
            // 只需要过滤阈值,过滤完后数组长度大于0即为报警
            argValue, err := strconv.ParseFloat(rule.SdkArgValue, 64)
            if err != nil {
               logger.Error("规则配置的阈值非法")
@@ -752,6 +731,7 @@
                  }
                  // 先清空过滤后的数据,再往里塞本次过滤后的数据
                  am.filterData = am.filterData[0:0]
                  //logger.Info("-----------------------人脸过滤的args:", args)
                  for _, arg := range args {
                     var formula string
                     if rule.SdkArgAlias == "score" {
@@ -835,14 +815,14 @@
   }
}
// 都过滤完条件之后看看是否要创建一个定时器元素 创建定时器的条件:是否有靠右行,个体静止等自带定时器含义的算法以及是否有持续时间
func duration(rule *protomsg.Rule, am *AreaMap) {
// 如果有持续时间条件维护开启一个定时器
func duration(rule *protomsg.Rule, groupId string, am *AreaMap, args *SdkDatas) {
   if rule.PolygonId == am.areaId { // 首先规则所对应的区域id要跟区域数据的id对的上  配置的算法要对的上
      if rule.SdkArgAlias == "duration" { //
         // 先看看定时器元素队列中是否有这个摄像机这个区域的定时器,如果有就不能再次创建了
         var flag bool = true
         for k, _ := range TimeEleList {
            if k == am.taskId+" "+am.sdkId+" "+am.areaId {
            if k == groupId+" "+rule.Id {
               flag = false // 有就置为false
               logger.Info("有这个定时器,不再创建了:")
            }
@@ -850,29 +830,14 @@
         if flag {
            timeLength, _ := strconv.Atoi(rule.SdkArgValue)
            timeEle := TimeElement{N: timeLength, InitN: timeLength} // 扔进去一个定时器元素
            timeEle := TimeElement{N: timeLength, InitN: timeLength, AlarmFlag: false, CacheSdkData: *args} // 扔进去一个定时器元素(并缓存当前画面帧数据)
            //TimeEleList = make(map[string]timeElement)
            TimeEleList[am.taskId+" "+am.sdkId+" "+am.areaId] = &timeEle // 定时器元素以摄像机id拼接区域id为键
            TimeEleList[groupId+" "+rule.Id] = &timeEle // 定时器元素以摄像机id拼接区域id为键
            logger.Info("创建了计数器并且计数器集合为:", TimeEleList)
         }
      }
   }
}
//// 冗余拼接一个目标数量大于0
//func splice1(am *AreaMap) string {
//   var num int = 0
//   for _, data := range am.filterData {
//      if data.isYolo {
//         num++
//      }
//   }
//   logger.Println("看看区域内符合条件的目标数量:----------", num)
//   formula := strconv.Itoa(num) + " " + ">" + "0"
//   expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
//   result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
//   return strconv.FormatBool(result.(bool))
//}
// 给数据库的规则表达式代参 args: 一条子规则,区域数据
func transferParameters(rule *protomsg.Rule, am *AreaMap) LittleRuleResult {
@@ -989,14 +954,6 @@
// 取出某个时间规则的第几天的规则段集合
func GetTimeById(id string, index int) []TimeRange {
   //var cameraTimeRule protomsg.CameraTimerule
   //var api dbapi.CameraApi
   //_, rules := api.FindAllTimeRules()
   //for _, rule := range rules {
   //   if rule.Id == id {
   //      cameraTimeRule = rule
   //   }
   //}
   _, cameraTimeRule := cache.GetTimeRuleById(id)
   var timeRangeList []day
   err := json.Unmarshal([]byte(cameraTimeRule.TimeRule), &timeRangeList)