panlei
2019-11-09 573a1e019fc00e171b7df7105fe69b414a490966
把一部分判断放进中间件
1个文件已删除
6个文件已修改
194 ■■■■■ 已修改文件
algorithm/middleware/middleware.go 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/static/static.go 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleprocess 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/geoPolygon.go 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/readyDataForRule.go 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/ruleToformula.go 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/timeTicker.go 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/middleware/middleware.go
@@ -7,12 +7,14 @@
    "github.com/knetic/govaluate"
    "plugin"
    "ruleprocess/cache"
    "ruleprocess/ruleserver"
    "ruleprocess/structure"
    "sort"
    "strings"
    "time"
)
func Entrance (args *structure.SdkDatas,groupRule protomsg.GroupRule) ([]*structure.LittleRuleResult,string,string){
func Entrance (args *structure.SdkDatas,groupRule protomsg.GroupRule) (bool,string,string){
    resultSplice := []*structure.LittleRuleResult{}
    sdkNames := ""
    polygonId := ""
@@ -52,6 +54,43 @@
            }
        }
    }
    // 人脸
    for j := 0; j < len(groupRule.Rules); j++ {
        if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && groupRule.Rules[j].SdkArgAlias != "time_rule"{
            for _, sdkData := range args.Sdkdata {
                // 根据规则的sdkId查出其对应的ipcId,用ipcId去找该比对的数据
                sdk, err := cache.GetSdkById(groupRule.Rules[j].SdkId)
                if err != nil {
                    logger.Error("没查到sdk的信息---", err)
                }
                ipcId := sdk.IpcId
                sdkName := sdk.SdkName
                //logger.Info("规则的ipcId与sdkData的IpcId:", ipcId, "===", sdkData.IpcId)
                if ipcId == sdkData.IpcId {
                    //logger.Info("当前走的规则是--:", sdkName, "---","")
                    for _, areaMap := range sdkData.AreaMapList {
                        ruleResult := CallSo(sdk.Id, groupRule.Rules[j], areaMap)
                        if ruleResult.Result != "" {
                            logger.Info("人脸比对规则结果:", ruleResult.Result)
                            // 如果结果为真,把这条规则中的区域置为有效
                            if strings.Contains(ruleResult.Result, "true") {
                                areaMap.IsEffective = true
                            }
                            // 如果此结果为真且当前过的是yolo算法,应记下此规则所对应的sdkName,另外,还要去重 (后加:把此条触碰的区域id也记录下来)
                            if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) {
                                sdkNames = sdkName + " "
                            }
                            if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(polygonId, groupRule.Rules[j].PolygonId) {
                                polygonId += groupRule.Rules[j].PolygonId + ","
                            }
                            resultSplice = append(resultSplice, &ruleResult)
                        }
                    }
                }
            }
        }
    }
    // 个体静止
    for j := 0; j < len(groupRule.Rules); j++ {
        if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && groupRule.Rules[j].SdkArgAlias != "time_rule"{
            for _, sdkData := range args.Sdkdata {
@@ -148,7 +187,37 @@
            }
        }
    }
    return resultSplice,sdkNames,polygonId
    // 将数组按sort排序
    sort.Sort(ruleserver.ResultList(resultSplice))
    // 排序后取各自的结果和连接符拼出规则表达式得出结果
    completeFormula := ""
    for _, va := range resultSplice {
        completeFormula = completeFormula + va.Result
    }
    if strings.HasPrefix(completeFormula, "&&") || strings.HasPrefix(completeFormula, "||") || strings.HasPrefix(completeFormula, ">=") || strings.HasPrefix(completeFormula, "<=") || strings.HasPrefix(completeFormula, "==") || strings.HasPrefix(completeFormula, "!=") || strings.HasPrefix(completeFormula, ">") || strings.HasPrefix(completeFormula, "<") {
        // 以这些开头的基本是联动任务
        if strings.HasPrefix(completeFormula, "&&") || strings.HasPrefix(completeFormula, "||") || strings.HasPrefix(completeFormula, ">=") || strings.HasPrefix(completeFormula, "<=") || strings.HasPrefix(completeFormula, "==") || strings.HasPrefix(completeFormula, "!=") {
            completeFormula = completeFormula[2:]
        }
        if strings.HasPrefix(completeFormula, ">") || strings.HasPrefix(completeFormula, "<") {
            completeFormula = completeFormula[1:]
        }
        logger.Info("-------------------看看拔毛后的表达式:", completeFormula)
        //expression, _ := govaluate.NewEvaluableExpression(completeFormula)
        //result, _ := expression.Evaluate(nil) // 得到数学公式的结果
        //return result.(bool)
    }
    if completeFormula != "" {
        logger.Info("结果公式-----------:", completeFormula)
        expression, err2 := govaluate.NewEvaluableExpression(completeFormula)
        if strings.HasPrefix(completeFormula, "&&") || strings.HasPrefix(completeFormula, "||") || err2 != nil {
            panic("规则有误,得到的数学公式不可解析")
        }
        result, _ := expression.Evaluate(nil) // 得到数学公式的结果
        return result.(bool),sdkNames,polygonId
    } else {
        return false,sdkNames,polygonId
    }
}
func timeRuleResult(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
algorithm/static/static.go
@@ -8,7 +8,21 @@
    "ruleprocess/structure"
    "strconv"
)
//个体静止算法
var StaticMap = make(map[string]CameraArea)
type CameraArea struct {
    targets  []Obj
    duration int
    cache    structure.ResultMsg
}
type Obj struct {
    id           string
    location     []structure.Rect
    staticStatus int
}
func Entrance(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    for _,obj := range am.FilterData {
        var flag bool = true
@@ -63,3 +77,24 @@
        return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
    }
}
// 判断两个矩形的重合度,把面积更大的做分母
func PgsInterPercent(pgpts []structure.Point, box structure.Rect, widthScale float64, heightScale float64) (percent float64) {
    areapts, areaBox := ruleserver.GetLocation(box, 10)
    var count = 0
    for _, pts := range areapts {
        if ruleserver.PintIsInPolygon(pts, pgpts, widthScale, heightScale) {
            count++
        }
    }
    perInterBox := float64(count) / float64(len(areapts)) // 重合面积占矩形的比例
    areaInter := perInterBox * areaBox
    areaPg := ruleserver.ComputePolygonArea(pgpts)
    perInterPg := areaInter / areaPg // 重合面积占多边形区域的比例
    // 哪个占的比例小按哪个计算,比如人站起来了,大框套住了小框
    if perInterBox < perInterPg {
        return (perInterBox * 100)
    }
    return (perInterPg * 100)
}
ruleprocess
Binary files differ
ruleserver/geoPolygon.go
@@ -20,12 +20,6 @@
    return num1
}
//Point 坐标点
type Point struct {
    X float64 `json:"x"`
    Y float64 `json:"y"`
}
//Rect 检测目标
type Rect struct {
    X      float64
@@ -43,7 +37,7 @@
//PintIsInPolygon 判断点是否在多边形内部
//point为要判断的坐标点
//polygon是多边形各点数组
func pintIsInPolygon(point structure.Pointfloat, polygon []Point, widthScale float64, heightScale float64) bool {
func PintIsInPolygon(point structure.Pointfloat, polygon []structure.Point, widthScale float64, heightScale float64) bool {
    var nCross int = 0
    for i := 0; i < len(polygon); i++ {
@@ -73,7 +67,7 @@
}
//GetLocation 将一个给定起始坐标,宽度长度的矩形区域均分为n方份并返回中心坐标(n为单边平分数值)和面积
func getLocation(rect structure.Rect, n int) ([]structure.Pointfloat, float64) {
func GetLocation(rect structure.Rect, n int) ([]structure.Pointfloat, float64) {
    xArr := make([]float64, n) // 用切片不用数组,数组不能用变量定义长度
    yArr := make([]float64, n)
    pointArr := make([]structure.Pointfloat, 0, n*n)
@@ -92,7 +86,7 @@
}
//ComputePolygonArea 计算任意多边形面积
func computePolygonArea(polygon []Point) float64 {
func ComputePolygonArea(polygon []structure.Point) float64 {
    pointNum := len(polygon)
    var s float64 = 0
    if pointNum < 3 {
@@ -106,18 +100,18 @@
}
//PgsInterPercent calculate percent of two polygon intersection  计算两个多边形的重叠占比
func PgsInterPercent(pgpts []Point, box structure.Rect, widthScale float64, heightScale float64) (percent float64) {
func PgsInterPercent(pgpts []structure.Point, box structure.Rect, widthScale float64, heightScale float64) (percent float64) {
    areapts, areaBox := getLocation(box, 10)
    areapts, areaBox := GetLocation(box, 10)
    var count = 0
    for _, pts := range areapts {
        if pintIsInPolygon(pts, pgpts, widthScale, heightScale) {
        if PintIsInPolygon(pts, pgpts, widthScale, heightScale) {
            count++
        }
    }
    perInterBox := float64(count) / float64(len(areapts)) // 重合面积占矩形的比例
    areaInter := perInterBox * areaBox
    areaPg := computePolygonArea(pgpts)
    areaPg := ComputePolygonArea(pgpts)
    perInterPg := areaInter / areaPg // 重合面积占多边形区域的比例
    // 哪个占的比例大按哪个计算
    if perInterBox > perInterPg {
ruleserver/readyDataForRule.go
@@ -123,14 +123,14 @@
// 将字符串格式的坐标序列化为Point格式
func Json2points(areaPoints string) []Point {
    var pts []Point
func Json2points(areaPoints string) []structure.Point {
    var pts []structure.Point
    if areaPoints == "[]" || areaPoints == "" {
        logger.Error("=====================此区域为全部区域")
        pts = append(pts, Point{0, 0})
        pts = append(pts, Point{0, 540})
        pts = append(pts, Point{960, 540})
        pts = append(pts, Point{960, 0})
        pts = append(pts, structure.Point{0, 0})
        pts = append(pts, structure.Point{0, 540})
        pts = append(pts, structure.Point{960, 540})
        pts = append(pts, structure.Point{960, 0})
    } else {
        err := json.Unmarshal([]byte(areaPoints), &pts)
        if err != nil {
ruleserver/ruleToformula.go
@@ -9,7 +9,6 @@
    "ruleprocess/structure"
    "sort"
    "strconv"
    "strings"
    "sync"
)
@@ -77,7 +76,7 @@
    }
}
func CallMiddleware(args *structure.SdkDatas,rule protomsg.GroupRule) ([]*structure.LittleRuleResult, string, string){
func CallMiddleware(args *structure.SdkDatas,rule protomsg.GroupRule) (bool, string, string){
    p,err :=  plugin.Open("./algorithm/middleware.so")
    if err != nil {
        panic(err)
@@ -86,7 +85,7 @@
    if err1 != nil {
        panic("没有找到中间件入口函数")
    }
    a,b,c := f.(func(args *structure.SdkDatas,rule protomsg.GroupRule)([]*structure.LittleRuleResult, string, string))(args,rule)
    a,b,c := f.(func(args *structure.SdkDatas,rule protomsg.GroupRule)(bool, string, string))(args,rule)
    return a,b,c
}
@@ -99,39 +98,13 @@
    logger.Info("+++++++++++规则开始运行+++++++++++++++++当前大规则--:", (*groupRule).GroupText)
    //logger.Warn("传进去之后是什么德行:",args.RuleResult["yolo"])
    Compare(args, groupRule)
    resultSplice := []*structure.LittleRuleResult{}
    result := false
    sdkNames := ""
    polygonId := ""
    resultSplice,sdkNames,polygonId = CallMiddleware(args,*groupRule)
    // 将数组按sort排序
    sort.Sort(resultList(resultSplice))
    // 排序后取各自的结果和连接符拼出规则表达式得出结果
    completeFormula := ""
    for _, va := range resultSplice {
        completeFormula = completeFormula + va.Result
    }
    if strings.HasPrefix(completeFormula, "&&") || strings.HasPrefix(completeFormula, "||") || strings.HasPrefix(completeFormula, ">=") || strings.HasPrefix(completeFormula, "<=") || strings.HasPrefix(completeFormula, "==") || strings.HasPrefix(completeFormula, "!=") || strings.HasPrefix(completeFormula, ">") || strings.HasPrefix(completeFormula, "<") {
        // 以这些开头的基本是联动任务
        if strings.HasPrefix(completeFormula, "&&") || strings.HasPrefix(completeFormula, "||") || strings.HasPrefix(completeFormula, ">=") || strings.HasPrefix(completeFormula, "<=") || strings.HasPrefix(completeFormula, "==") || strings.HasPrefix(completeFormula, "!=") {
            completeFormula = completeFormula[2:]
        }
        if strings.HasPrefix(completeFormula, ">") || strings.HasPrefix(completeFormula, "<") {
            completeFormula = completeFormula[1:]
        }
        logger.Info("-------------------看看拔毛后的表达式:", completeFormula)
        //expression, _ := govaluate.NewEvaluableExpression(completeFormula)
        //result, _ := expression.Evaluate(nil) // 得到数学公式的结果
        //return result.(bool)
    }
    if completeFormula != "" {
        logger.Info("结果公式-----------:", completeFormula)
        expression, err2 := govaluate.NewEvaluableExpression(completeFormula)
        if strings.HasPrefix(completeFormula, "&&") || strings.HasPrefix(completeFormula, "||") || err2 != nil {
            panic("规则有误,得到的数学公式不可解析")
        }
        result, _ := expression.Evaluate(nil) // 得到数学公式的结果
    // 把一帧数据和一组规则发给算法部分,得出判断结果
    result,sdkNames,polygonId = CallMiddleware(args,*groupRule)
        if result.(bool) {
    if result {
            // 最后过持续时间等时间维度的条件   把时间规则位置调整到这个位置是为了缓存数据
            cacheId := ""
            for j := 0; j < len(groupRule.Rules); j++ {
@@ -153,7 +126,7 @@
                }
            }
            // 进行定时器的处理和判断
            timeFlag := TimerAlarm(&label, groupRule.GroupId, result.(bool))
        timeFlag := TimerAlarm(&label, groupRule.GroupId, result)
            if timeFlag == "01" || timeFlag == "10" || timeFlag == "11" || cacheId != ""{ // 没有定时器或者满足定时器条件
                // 打人脸标签和yolo标签
                // 最后成功报警才把符合条件的人脸数据塞进结果标签里
@@ -237,11 +210,8 @@
        } else {
            // 结果为假时也要走,有杀死定时器的操作
            TimerAlarm(&label, groupRule.GroupId, result.(bool))
        TimerAlarm(&label, groupRule.GroupId, result)
            //fmt.Println(timeFlag)
            return false,[]int{}
        }
    } else {
        return false,[]int{}
    }
}
ruleserver/timeTicker.go
@@ -148,8 +148,8 @@
func (p SubList) Less(i, j int) bool { return p[i].Sort < p[j].Sort }
// 结构体根据某字段排序
type resultList []*structure.LittleRuleResult
type ResultList []*structure.LittleRuleResult
func (p resultList) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
func (p resultList) Len() int           { return len(p) }
func (p resultList) Less(i, j int) bool { return p[i].Sort < p[j].Sort }
func (p ResultList) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
func (p ResultList) Len() int           { return len(p) }
func (p ResultList) Less(i, j int) bool { return p[i].Sort < p[j].Sort }