panlei
2019-10-09 49eaf6fcf782ea66cce284ca910bff7455e67e4b
把结构体提出来单独模块儿
2个文件已删除
2个文件已添加
13个文件已修改
636 ■■■■ 已修改文件
105.jpg 补丁 | 查看 | 原始文档 | blame | 历史
go.mod 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
go.sum 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
insertdata/insertDataToEs.go 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
labelFilter/readyDataForLabel.go 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
labelFilter/req.go 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
labelFilter/ruleForLabel.go 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/geoPolygon.go 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/personTrack.go 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/readyDataForRule.go 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/ruleToformula.go 309 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/timeTicker.go 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
structure/gragh.go 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
structure/rule.go 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
util/105.jpg 补丁 | 查看 | 原始文档 | blame | 历史
util/simpleCV.go 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
util/simpleCV_test.go 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
105.jpg
Binary files differ
go.mod
@@ -5,7 +5,7 @@
require (
    basic.com/dbapi.git v0.0.0-20190822081128-ce924b8a905f
    basic.com/pubsub/cache.git v0.0.0-20190718093725-6a413e1d7d48
    basic.com/pubsub/protomsg.git v0.0.0-20190824080957-7b44351cb40b
    basic.com/pubsub/protomsg.git v0.0.0-20190905061607-7b96dafe8f99
    basic.com/pubsub/sdkcompare.git v0.0.0-20190715013640-f536a4647d00
    basic.com/valib/deliver.git v0.0.0-20190531095353-25d8c3b20051
    basic.com/valib/gopherdiscovery.git v0.0.0-20190605034340-15d89d8b4e28
go.sum
@@ -1,21 +1,9 @@
basic.com/dbapi.git v0.0.0-20190701055817-73bca225181f h1:CVB4pmUXTPPFN7w/DQfU1YWg2Tp2gG93TTr1M5W86sE=
basic.com/dbapi.git v0.0.0-20190701055817-73bca225181f/go.mod h1:eDXPnxaz6jZPDvBSk7ya7oSASWPCuUEgRTJCjsfKt/Q=
basic.com/dbapi.git v0.0.0-20190724082851-b6ae90344405 h1:BJzdtGipKxQAaptrwUNOVQZ3Qx4jbeAf72wkqBmm5vE=
basic.com/dbapi.git v0.0.0-20190724082851-b6ae90344405/go.mod h1:eDXPnxaz6jZPDvBSk7ya7oSASWPCuUEgRTJCjsfKt/Q=
basic.com/dbapi.git v0.0.0-20190822081128-ce924b8a905f h1:m7ONW0VqagpmWppr6GSa2Gykid202vCbV9worYCM+pg=
basic.com/dbapi.git v0.0.0-20190822081128-ce924b8a905f/go.mod h1:eDXPnxaz6jZPDvBSk7ya7oSASWPCuUEgRTJCjsfKt/Q=
basic.com/pubsub/cache.git v0.0.0-20190712095028-e73efb4afc3b h1:UAasACFqEYUBCuZkkdxYVc1QmSyB7McvNHS36QxDJp4=
basic.com/pubsub/cache.git v0.0.0-20190712095028-e73efb4afc3b/go.mod h1:gHLJZz2ee1cGL0X0ae69fs56bAxkDgEQwDhhXZJNUcY=
basic.com/pubsub/cache.git v0.0.0-20190718024458-be52360c4814 h1:KoSik/aiJNDt3d+qRKExLW4pNHZ7vU1wXHhWXxZi4qo=
basic.com/pubsub/cache.git v0.0.0-20190718024458-be52360c4814/go.mod h1:gHLJZz2ee1cGL0X0ae69fs56bAxkDgEQwDhhXZJNUcY=
basic.com/pubsub/cache.git v0.0.0-20190718093725-6a413e1d7d48 h1:BBA30Rgljn6MRieC4gUncETJDyna3ObyubTo9HEQ2M0=
basic.com/pubsub/cache.git v0.0.0-20190718093725-6a413e1d7d48/go.mod h1:gHLJZz2ee1cGL0X0ae69fs56bAxkDgEQwDhhXZJNUcY=
basic.com/pubsub/protomsg.git v0.0.0-20190801122504-ad6c105f7a2b h1:2eskhTo22eo07AmAj3xVo31U/+qRFf6P1qhlfxoaFOc=
basic.com/pubsub/protomsg.git v0.0.0-20190801122504-ad6c105f7a2b/go.mod h1:un5NV5VWQoblVLZfx1Rt5vyLgwR0jI92d3VJhfrJhWU=
basic.com/pubsub/protomsg.git v0.0.0-20190822060153-dc8ca60fc531 h1:XsygHuAqvEovNNOiG80qLoV9OtdcN8IPP+xv/Ajx+Eg=
basic.com/pubsub/protomsg.git v0.0.0-20190822060153-dc8ca60fc531/go.mod h1:un5NV5VWQoblVLZfx1Rt5vyLgwR0jI92d3VJhfrJhWU=
basic.com/pubsub/protomsg.git v0.0.0-20190824080957-7b44351cb40b h1:sstFc5QNzIuMnRANTpWn+2LGQnHwyQ8kG0TvZDZMw2s=
basic.com/pubsub/protomsg.git v0.0.0-20190824080957-7b44351cb40b/go.mod h1:un5NV5VWQoblVLZfx1Rt5vyLgwR0jI92d3VJhfrJhWU=
basic.com/pubsub/protomsg.git v0.0.0-20190905061607-7b96dafe8f99 h1:YSmWZPp/mHoq+/L5d0iTsqjiCcVwZqEQRQAXxQFSbvY=
basic.com/pubsub/protomsg.git v0.0.0-20190905061607-7b96dafe8f99/go.mod h1:un5NV5VWQoblVLZfx1Rt5vyLgwR0jI92d3VJhfrJhWU=
basic.com/pubsub/sdkcompare.git v0.0.0-20190715013640-f536a4647d00 h1:sK+Tx7rvM9J2WnNIwrzMDjZSylWiKNfQO0prUBfKsDk=
basic.com/pubsub/sdkcompare.git v0.0.0-20190715013640-f536a4647d00/go.mod h1:8by33F9E1w17Pw/rDgJGJXAo122w0wDENG14hiMS+RE=
basic.com/valib/deliver.git v0.0.0-20190531095353-25d8c3b20051 h1:9flC2o3kasaM2Y6I+mY+mxmve/pyAY/UzGQZLT3lFHM=
insertdata/insertDataToEs.go
@@ -2,6 +2,7 @@
import (
    "basic.com/valib/logger.git"
    "ruleprocess/structure"
    "encoding/base64"
    "encoding/json"
    "errors"
@@ -66,7 +67,7 @@
    IsAckAlarm      int                    `json:"isAckAlarm"`
    IsCollect       int                    `json:"isCollect"`
    IsDelete        int                    `json:"isDelete"`
    BaseInfo        []*ruleserver.BaseInfo `json:"baseInfo"`
    BaseInfo        []*structure.BaseInfo `json:"baseInfo"`
}
//  yolo行为的数据结构
@@ -105,8 +106,8 @@
// 一个face对多个规则组的归置人脸的结构体
type FaceAndRules struct {
    ruleserver.Arg
    rules []ruleserver.Result
    structure.Arg
    rules []structure.Result
}
// 往ES插数据
@@ -133,7 +134,7 @@
//    //    ChangeStatusYolo(msg)
//    //}
//}
func InsertToEs(msg ruleserver.ResultMsg) {
func InsertToEs(msg structure.ResultMsg) {
    defer func() {
        if err := recover(); err != nil {
            logger.Error("es模块儿的异常捕获:",err)
@@ -164,8 +165,8 @@
}
// 往es中插入人脸数据
func InsertFace(msg ruleserver.ResultMsg, linkId string) {
    if msg.RuleResult["face"] != nil && len(msg.RuleResult["face"].([]ruleserver.FaceResult)) > 0 {
func InsertFace(msg structure.ResultMsg, linkId string) {
    if msg.RuleResult["face"] != nil && len(msg.RuleResult["face"].([]structure.FaceResult)) > 0 {
        logger.Info("往ES插人脸数据")
        faces := []*FaceAndRules{}
        faces = PutFace(faces,msg)
@@ -191,7 +192,7 @@
                err = proto.Unmarshal(bdata, &i)
                if imgMaxUrl == "" {
                    bigPhotoUrl := make(map[string]interface{})
                    bigPhotoUrl, err = util.DrawPolygonOnImageForFace(msg.Cid, i, msg.RuleResult["face"].([]ruleserver.FaceResult), weedfsUrl)
                    bigPhotoUrl, err = util.DrawPolygonOnImageForFace(msg.Cid, i, msg.RuleResult["face"].([]structure.FaceResult), weedfsUrl)
                    logger.Debug("========大图路径:", bigPhotoUrl)
                    imgMaxUrl = bigPhotoUrl["fileUrl"].(string)
                    picTime = i.Timestamp
@@ -283,9 +284,9 @@
}
// 归置人脸
func PutFace(faces []*FaceAndRules,msg ruleserver.ResultMsg)[]*FaceAndRules{
    if msg.RuleResult["face"] != nil && len(msg.RuleResult["face"].([]ruleserver.FaceResult)) > 0 {
        for _, faceResult := range msg.RuleResult["face"].([]ruleserver.FaceResult) {
func PutFace(faces []*FaceAndRules,msg structure.ResultMsg)[]*FaceAndRules{
    if msg.RuleResult["face"] != nil && len(msg.RuleResult["face"].([]structure.FaceResult)) > 0 {
        for _, faceResult := range msg.RuleResult["face"].([]structure.FaceResult) {
            faces = hebingFace(faces, faceResult)
        }
        return faces
@@ -293,7 +294,7 @@
        return nil
    }
}
func hebingFace(faces []*FaceAndRules, faceResult ruleserver.FaceResult) []*FaceAndRules{
func hebingFace(faces []*FaceAndRules, faceResult structure.FaceResult) []*FaceAndRules{
    for _, arg := range faceResult.Args {
        // 拿到每一张人脸
        logger.Info("归置人脸时相似者的数量:",len(arg.Liker))
@@ -321,18 +322,18 @@
            }
        }
        if !flag {
            faces = append(faces, &FaceAndRules{arg, []ruleserver.Result{faceResult.Result}})
            faces = append(faces, &FaceAndRules{arg, []structure.Result{faceResult.Result}})
        }
    }
    return faces
}
// 往es中插入yolo数据
func InsertYolo(msg ruleserver.ResultMsg, linkId string) {
    if msg.RuleResult["yolo"] != nil && len(msg.RuleResult["yolo"].([]ruleserver.Result)) > 0 {
func InsertYolo(msg structure.ResultMsg, linkId string) {
    if msg.RuleResult["yolo"] != nil && len(msg.RuleResult["yolo"].([]structure.Result)) > 0 {
        // 先判断一下数据带的规则标签是否有可以插入的
        flag := false
        for _, res := range msg.RuleResult["yolo"].([]ruleserver.Result) {
        for _, res := range msg.RuleResult["yolo"].([]structure.Result) {
            //logger.Info("定时器打的数字标签:",res.Others.TimeLabel)
            if res.Others.TimeLabel == "01" || res.Others.TimeLabel == "10" {
                flag = true
@@ -343,7 +344,7 @@
            var sdkNames string = ""
            alarmRules := []AlarmRule{}
            url := []string{}
            for _, yoloResult := range msg.RuleResult["yolo"].([]ruleserver.Result) {
            for _, yoloResult := range msg.RuleResult["yolo"].([]structure.Result) {
                if yoloResult.Others.TimeLabel == "01" || yoloResult.Others.TimeLabel == "10" {
                    // 拼出sdkname
                    //logger.Info("应该进来才对的")
@@ -367,7 +368,7 @@
                            }
                            i := protomsg.Image{}
                            err = proto.Unmarshal(bdata, &i)
                            resp1, err1 := util.DrawPolygonOnImageForYolo(msg1.Cid, i, msg1.RuleResult["yolo"].([]ruleserver.Result), weedfsUrl)
                            resp1, err1 := util.DrawPolygonOnImageForYolo(msg1.Cid, i, msg1.RuleResult["yolo"].([]structure.Result), weedfsUrl)
                            if err1 != nil {
                                logger.Error("缓存数据画框或上传图片服务器出错", err)
                            } else {
@@ -381,7 +382,7 @@
                }
            }
            linkFlag := false
            for _, yoloResult := range msg.RuleResult["yolo"].([]ruleserver.Result) {
            for _, yoloResult := range msg.RuleResult["yolo"].([]structure.Result) {
                if (yoloResult.Others.TimeLabel == "01" || yoloResult.Others.TimeLabel == "10") && yoloResult.Others.LinkCache != nil && len(yoloResult.Others.LinkCache) > 1 {
                    linkId := uuid.NewV4().String()
                    for _, msg2 := range yoloResult.Others.LinkCache {
labelFilter/readyDataForLabel.go
@@ -1,9 +1,9 @@
package labelFilter
import (
    "ruleprocess/cache"
    "basic.com/valib/logger.git"
    "ruleprocess/ruleserver"
    "ruleprocess/cache"
    "ruleprocess/structure"
    "time"
)
@@ -13,14 +13,14 @@
    CameraAddr    string
    TaskId        string
    Time          string
    Persons       []ruleserver.FaceResult
    Persons       []structure.FaceResult
    DefenceLevel  []int32
}
// 把数据装配到label
func (label *Label)DataFormatToLabel(result ruleserver.ResultMsg) {
    logger.Debug("face结果:",result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]ruleserver.FaceResult)) > 0)
    logger.Debug("yolo结果:",result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]ruleserver.Result)) > 0)
    if (result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]ruleserver.FaceResult)) > 0) || (result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]ruleserver.Result)) > 0) {
func (label *Label)DataFormatToLabel(result structure.ResultMsg) {
    logger.Debug("face结果:",result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]structure.FaceResult)) > 0)
    logger.Debug("yolo结果:",result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]structure.Result)) > 0)
    if (result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]structure.FaceResult)) > 0) || (result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]structure.Result)) > 0) {
        logger.Info("---------------标签过滤器赋值")
        label.CameraId = result.Cid
        camera, err := cache.GetCameraById(result.Cid)
@@ -31,14 +31,14 @@
        label.CameraAddr = camera.Addr
        label.TaskId = result.Tasklab.Taskid
        label.Time = time.Now().Format("2006-01-02 15:04:05")
        if result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]ruleserver.FaceResult)) > 0 {
            for _,faceGroup := range result.RuleResult["face"].([]ruleserver.FaceResult) {
        if result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]structure.FaceResult)) > 0 {
            for _,faceGroup := range result.RuleResult["face"].([]structure.FaceResult) {
                label.Persons = append(label.Persons,faceGroup)
                label.DefenceLevel = append(label.DefenceLevel,faceGroup.AlarmLevel)
            }
        }
        if result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]ruleserver.Result)) > 0 {
            for _,yoloGroup := range result.RuleResult["yolo"].([]ruleserver.Result) {
        if result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]structure.Result)) > 0 {
            for _,yoloGroup := range result.RuleResult["yolo"].([]structure.Result) {
                label.DefenceLevel = append(label.DefenceLevel,yoloGroup.AlarmLevel)
            }
        }
labelFilter/req.go
@@ -1,16 +1,16 @@
package labelFilter
import (
    "basic.com/valib/logger.git"
    "fmt"
    "github.com/golang/protobuf/proto"
    "nanomsg.org/go-mangos"
    "nanomsg.org/go-mangos/protocol/rep"
    "nanomsg.org/go-mangos/protocol/req"
    "nanomsg.org/go-mangos/transport/ipc"
    "nanomsg.org/go-mangos/transport/tcp"
    "os"
    "github.com/golang/protobuf/proto"
    "basic.com/valib/logger.git"
    "ruleprocess/ruleserver"
    "ruleprocess/structure"
    "time"
)
@@ -53,7 +53,7 @@
    }
}
func Push(url string,data ruleserver.ResultMsg) {
func Push(url string,data structure.ResultMsg) {
    var sock mangos.Socket
    var err error
    var msg []byte
labelFilter/ruleForLabel.go
@@ -3,14 +3,14 @@
import (
    "basic.com/dbapi.git"
    "basic.com/pubsub/protomsg.git"
    "github.com/knetic/govaluate"
    "basic.com/valib/logger.git"
    "ruleprocess/ruleserver"
    "github.com/knetic/govaluate"
    "ruleprocess/structure"
    "strconv"
    "time"
)
func Judge(msg ruleserver.ResultMsg) {
func Judge(msg structure.ResultMsg) {
    // 装配成自己可以识别的数据
    label := new(Label)
    label.DataFormatToLabel(msg)
@@ -311,7 +311,7 @@
}
// 调用目标服务器的插入接口
func pushData(urls []*protomsg.PushUrl, data ruleserver.ResultMsg) {
func pushData(urls []*protomsg.PushUrl, data structure.ResultMsg) {
    for _, url := range urls {
        logger.Debug("看看推送地址:",url.Url)
        Push("tcp://192.168.1.123:40012", data)
ruleserver/geoPolygon.go
@@ -2,6 +2,7 @@
import (
    "math"
    "ruleprocess/structure"
)
func min(num1 float64, num2 float64) float64 {
@@ -72,7 +73,7 @@
}
//GetLocation 将一个给定起始坐标,宽度长度的矩形区域均分为n方份并返回中心坐标(n为单边平分数值)和面积
func getLocation(rect Rect, n int) ([]Pointfloat, float64) {
func getLocation(rect structure.Rect, n int) ([]Pointfloat, float64) {
    xArr := make([]float64, n) // 用切片不用数组,数组不能用变量定义长度
    yArr := make([]float64, n)
    pointArr := make([]Pointfloat, 0, n*n)
@@ -105,7 +106,7 @@
}
//PgsInterPercent calculate percent of two polygon intersection  计算两个多边形的重叠占比
func PgsInterPercent(pgpts []Point, box Rect, widthScale float64, heightScale float64) (percent float64) {
func PgsInterPercent(pgpts []Point, box structure.Rect, widthScale float64, heightScale float64) (percent float64) {
    areapts, areaBox := getLocation(box, 10)
    var count = 0
ruleserver/personTrack.go
@@ -4,6 +4,7 @@
    "basic.com/pubsub/protomsg.git"
    "github.com/golang/protobuf/proto"
    "basic.com/valib/logger.git"
    "ruleprocess/structure"
)
var TrackPond = make(map[string]*PersonTrack)
@@ -104,8 +105,8 @@
    return false
}
func TrackOrNot(label map[string]interface{}) bool{
    if label["yolo"] != nil && len(label["yolo"].([]Result)) > 0 {
        for _,res := range label["yolo"].([]Result) {
    if label["yolo"] != nil && len(label["yolo"].([]structure.Result)) > 0 {
        for _,res := range label["yolo"].([]structure.Result) {
            if res.TimeLabel == "10" {
                return true
            }
ruleserver/readyDataForRule.go
@@ -14,6 +14,7 @@
    "net"
    "ruleprocess/cache"
    "basic.com/valib/logger.git"
    "ruleprocess/structure"
    "strconv"
    "time"
)
@@ -151,7 +152,7 @@
}
// 给目标填充liker
func (arg *Arg) fillLiker(tableId []string, compareThreshold float32) {
func fillLiker(tableId []string, compareThreshold float32,arg *structure.Arg) {
    //bytes := bigCache.GetComparePersonBaseInfo(tableId, arg.Feature, compareThreshold)
    comArg := &protomsg.CompareArgs{
        TableIds:tableId,
@@ -196,7 +197,7 @@
                logger.Error("根据id查询底库信息出错!", err, "--返回值长度为:", len(table))
            }
            logger.Debug("看看这个base的对比值是多少:", Decimal(m[baseinfo.Id].CompareScore))
            base := BaseInfo{TableId: baseinfo.TableId, TableName: table[0].TableName, BwType: table[0].BwType, CompareScore: Decimal(m[baseinfo.Id].CompareScore), PersonId: baseinfo.Id, PersonName: baseinfo.PersonName, PersonPicUrl: baseinfo.PersonPicUrl, PhoneNum: baseinfo.PhoneNum, Sex: baseinfo.Sex, IdCard: baseinfo.IdCard, MonitorLevel: baseinfo.MonitorLevel, Content: baseinfo.Reserved}
            base := structure.BaseInfo{TableId: baseinfo.TableId, TableName: table[0].TableName, BwType: table[0].BwType, CompareScore: Decimal(m[baseinfo.Id].CompareScore), PersonId: baseinfo.Id, PersonName: baseinfo.PersonName, PersonPicUrl: baseinfo.PersonPicUrl, PhoneNum: baseinfo.PhoneNum, Sex: baseinfo.Sex, IdCard: baseinfo.IdCard, MonitorLevel: baseinfo.MonitorLevel, Content: baseinfo.Reserved}
            //os.Exit(1)
            arg.Liker = append(arg.Liker, &base)
        }
@@ -205,7 +206,7 @@
}
// 人脸比对
func Compare(args *SdkDatas, groupRule *protomsg.GroupRule) {
func Compare(args *structure.SdkDatas, groupRule *protomsg.GroupRule) {
    compareFlag := 0
    var tableIds []string
    var threshold float32 = 50 // 默认阈值为50
@@ -242,9 +243,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 {
@@ -255,14 +256,14 @@
                                //    }
                                //}
                                if compareFlag == 1 {
                                    arg.fillLiker(nil, threshold)
                                    fillLiker(nil, threshold, arg)
                                }
                                if compareFlag == 2 {
                                    arg.fillLiker(tableIds, threshold)
                                    fillLiker(tableIds, threshold, arg)
                                }
                                //logger.Info("-------------------成功给liker赋值,长度为:", len(arg.Liker))
                            }
                            areaMap.filterData = areaMap.args
                            areaMap.FilterData = areaMap.Args
                            //logger.Info("=======第一次看args:",(areaMap.filterData))
                        }
                        //logger.Info("-------------------------------人脸对比之后的目标数量",len(areaMap.args))
@@ -275,45 +276,45 @@
}
// 计算区域内的目标数量以及将相似度、占比、尺寸等打包
func (a *AreaMap) CountAreaObjs(arg *SdkData) {
func CountAreaObjs(a *structure.AreaMap,arg *structure.SdkData) {
    a.targetNum = 0
    a.TargetNum = 0
    threshold := 80.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++
            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{}}
            a.TargetNum++
            arg1 := structure.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, []*structure.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
    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
    //logger.Println("--------------------看看区域数据:",*a)
}
// 把sdk从数据帧上提取的按照区域分类归置
func SdkDataFormat(cameraId string, arg *SdkData, cameraPolygons []protomsg.CameraPolygon) {
func SdkDataFormat(cameraId string, arg *structure.SdkData, cameraPolygons []protomsg.CameraPolygon) {
    logger.Info("==================================本sdkData中解出来的目标数据=======================================")
    for _, photo := range arg.Photo {
        logger.Info("--------解析出来的数据---", cameraId, arg.IpcId, photo.Rects, photo.Score)
    }
    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 := structure.AreaMap{CameraId: cameraId, AreaId: polygon.Id, AreaJson: polygon.Polygon, TriggerLine: polygon.TriggerLine, DirectionLine: polygon.DirectionLine}
        // 为每个摄像机区域填充数据
        areaMap.CountAreaObjs(arg)
        CountAreaObjs(&areaMap,arg)
        arg.AreaMapList = append(arg.AreaMapList, &areaMap)
    }
}
ruleserver/ruleToformula.go
@@ -2,6 +2,7 @@
import (
    "ruleprocess/cache"
    "ruleprocess/structure"
    "basic.com/valib/logger.git"
    "sort"
    "strconv"
@@ -13,114 +14,10 @@
    "github.com/knetic/govaluate"
)
// 每个目标的参数:相似度,占比,尺寸
type Arg struct {
    Id         uint64
    Score      float64 // 区域内的目标的相似度
    Proportion float64 // 区域内的目标的占比
    Size       float64 // 区域内的目标的尺寸
    IsYolo     bool    // 是否是yolo数据
    Location   Rect    // 记下每个目标的位置参数,最后给结果装配人脸数据的时候用的到
    Feature    []byte
    ThftRes    protomsg.ThftResult
    Liker      []*BaseInfo
}
// 每个区域内的图片数据集合
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   // 是否静止
}
// sdk输出的图片上单个目标的数据
type PhotoMap struct {
    Id      uint64
    Rects   Rect    // 矩形区域参数
    Score   float64 // 相似度得分(有多大程度像一个目标。人脸,人体或车等等)
    IsYolo  bool    // 是否是yolo数据
    ThftRes protomsg.ThftResult
    Feature []byte
}
// 每个算法对于当前帧画面自己提取的数据
type SdkData struct {
    TaskId      string
    IpcId       string
    IsYolo      bool
    Photo       []PhotoMap // yolo算法结构,也可以存人脸的数据,毕竟人脸中能用规则来测的还是那些参数
    KeepRight   bool       // 是否靠右行 算法判断的与上一帧图像的比较结果
    IsStatic    bool       // 是否静止
    ImageWidth  int        // 摄像机拍摄的图像宽 像素
    ImageHeight int        // 摄像机拍摄的图像高 像素
    AreaMapList []*AreaMap // 本sdk提取的数据按照区域划分后的数据集合
}
// 从算法模块儿拿来的对一帧图像各个算法提取的数据集合
type SdkDatas struct {
    CameraId   string
    TaskId     string
    Sdkdata    []*SdkData
    RuleResult map[string]interface{} // 过完规则后打的标签 face: []FaceResult, yolo: []Result
}
type ResultMsg struct {
    *protomsg.SdkMessage
    RuleResult map[string]interface{} // 过完规则后打的标签 face: []FaceResult, yolo: []Result
}
type TargetInfo struct {
    Rect
    TargetId    uint64
    TargetScore float64
}
// 过规则库打上的标签
type Result struct {
    TaskId       string // 任务id
    SdkName      string
    RuleGroupId  string // 规则组id
    DefenceState bool   // 是否布防
    AlarmLevel   int32  // 报警等级
    RuleText     string // 文字版规则组
    Location     []TargetInfo // 目标的坐标
    AlarmPolygon string // 触发的报警框
    IsLink         bool   // 是否是联动任务
    Others
}
type Others struct {
    CacheData []ResultMsg //(本组规则中含有持续时间的规则开启的定时器缓存的数据帧)
    LinkCache []ResultMsg
    TimeLabel string
}
// 过规则库打上的标签
type FaceResult struct {
    Result
    Args []Arg
}
type LittleRuleResult struct {
    SdkName string // 记录下此结果是哪个sdk的结果
    Result  string // 已包含了前置连接符
    Sort    int32
}
var rw sync.RWMutex // 读写锁
// 对单帧图像的判断 thisSdkDatas  当前传入的这帧数据,cacheSdkData 定时器里缓存的一帧数据 没有就返回nil  (thisSdkDatas SdkDatas, cacheSdkDatas SdkDatas)
func Judge(args *SdkDatas, message *protomsg.SdkMessage) {
func Judge(args *structure.SdkDatas, message *protomsg.SdkMessage) {
    defer func() {
        if err := recover(); err != nil {
            logger.Error("规则模块儿的异常捕获:",err)
@@ -139,8 +36,8 @@
        //logger.Println("看下摄像机下的任务组:",taskRuleList)
        // 得到属于该摄像机的若干组任务的完整规则(跟每一条完整规则比较之后得出本张图像对于某个规则是否报警的结果。放进map,比如本帧图像的id,所碰撞成功的规则id)
        args.RuleResult = make(map[string]interface{})
        args.RuleResult["yolo"] = []Result{}
        args.RuleResult["face"] = []FaceResult{}
        args.RuleResult["yolo"] = []structure.Result{}
        args.RuleResult["face"] = []structure.FaceResult{}
        //logger.Warn("传进去之前是什么德行:",args.RuleResult["yolo"])
        if taskGroup != nil && len(taskGroup.GroupRules) > 0 {
            // 先过独立,再过联动
@@ -149,7 +46,7 @@
                taskId := taskGroup.TaskId
                //logger.Println("------------本组任务下的规则组的数量:",len(ruleList))
                temp := group.Rules // temp为一组完整规则 在此需要判断规则是否是联动规则
                label := Others{}
                label := structure.Others{}
                if len(temp) > 0 {
                    if group.SetType != "linkTask" {
                        // 独立任务的处理
@@ -162,7 +59,7 @@
                taskId := taskGroup.TaskId
                //logger.Println("------------本组任务下的规则组的数量:",len(ruleList))
                temp := group.Rules // temp为一组完整规则 在此需要判断规则是否是联动规则
                label := Others{}
                label := structure.Others{}
                if len(temp) > 0 {
                    if group.SetType == "linkTask" {
                        // groupId中含有link则为联动任务
@@ -174,7 +71,7 @@
    }
}
func RunRule(args *SdkDatas, groupRule *protomsg.GroupRule, taskId string, message *protomsg.SdkMessage, label Others) (bool,[]int) {
func RunRule(args *structure.SdkDatas, groupRule *protomsg.GroupRule, taskId string, message *protomsg.SdkMessage, label structure.Others) (bool,[]int) {
    defer func() {
        if err := recover(); err != nil {
            logger.Error("比对规则有误", err.(string))
@@ -183,7 +80,7 @@
    logger.Info("+++++++++++规则开始运行+++++++++++++++++当前大规则--:", (*groupRule).GroupText)
    //logger.Warn("传进去之后是什么德行:",args.RuleResult["yolo"])
    Compare(args, groupRule)
    resultSplice := []*LittleRuleResult{}
    resultSplice := []*structure.LittleRuleResult{}
    sdkNames := ""
    polygonId := ""
    // 先过完条件规则
@@ -205,7 +102,7 @@
                        logger.Info("条件规则结果:", ruleResult.Result)
                        // 如果结果为真,把这条规则中的区域置为有效
                        if strings.Contains(ruleResult.Result,"true") {
                            areaMap.isEffective = true
                            areaMap.IsEffective = true
                        }
                        // 如果此结果为真且当前过的是yolo算法,应记下此规则所对应的sdkName,另外,还要去重 (后加:把此条触碰的区域id也记录下来)
                        if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) {
@@ -235,7 +132,7 @@
                    ruleResult := transferParameters(groupRule.Rules[j], areaMap)
                    if ruleResult.Result != "" {
                        if strings.Contains(ruleResult.Result,"true") {
                            areaMap.isEffective = true
                            areaMap.IsEffective = true
                        }
                        logger.Info("数量规则结果:", ruleResult.Result)
                        if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) {
@@ -264,7 +161,7 @@
                    ruleResult := timeRuleResult(groupRule.Rules[j], areaMap)
                    if ruleResult.Result != "" {
                        if strings.Contains(ruleResult.Result,"true") {
                            areaMap.isEffective = true
                            areaMap.IsEffective = true
                        }
                        logger.Info("时间规则结果:", ruleResult.Result)
                        if strings.Contains(ruleResult.Result, "true") && ipcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && !strings.Contains(sdkNames, sdkName) {
@@ -331,7 +228,7 @@
                // 打人脸标签和yolo标签
                // 最后成功报警才把符合条件的人脸数据塞进结果标签里
                // 配了人脸的算法才把人脸的数据甩出来打标签
                faces := []Arg{}
                faces := []structure.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" {
@@ -341,7 +238,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)...)
                            }
                        }
@@ -353,7 +250,7 @@
                //}
                logger.Warn("___________________________________________________________________________终于走完万里长征")
                // 把他们的位置数据也传下去
                locations := []TargetInfo{}
                locations := []structure.TargetInfo{}
                for _, sdkData := range args.Sdkdata {
                    if sdkData.IpcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && sdkNames != "" { // 把yolo数据的各个目标的坐标输出方便后面画框
                        for _, areaMap := range sdkData.AreaMapList {
@@ -370,12 +267,12 @@
                }
                var labelTypes []int // 0为yolo标签,1为face标签 2为两者标签
                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"].([]structure.Result), structure.Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, locations, polygonId, islink,label,})
                    labelTypes = append(labelTypes,0)
                    //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, []TargetInfo{}, polygonId, islink,label,}, faces})
                    args.RuleResult["face"] = append(args.RuleResult["face"].([]structure.FaceResult), structure.FaceResult{structure.Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, []structure.TargetInfo{}, polygonId, islink,label,}, faces})
                    //logger.Info("-------------------face结果标签", len(args.RuleResult["face"].([]FaceResult)))
                    labelTypes = append(labelTypes,1)
                }
@@ -395,10 +292,10 @@
    }
}
func putFaceToResult(am *AreaMap, faceList []Arg) []Arg {
    faces := []Arg{}
    if len(am.filterData) > 0 {
        for _, data := range am.filterData {
func putFaceToResult(am *structure.AreaMap, faceList []structure.Arg) []structure.Arg {
    faces := []structure.Arg{}
    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 {
@@ -414,11 +311,11 @@
    return faces
}
func putYolosToResult(am *AreaMap) []TargetInfo {
    locations := []TargetInfo{}
    if len(am.filterData) > 0 {
        for _, data := range am.filterData {
            location := TargetInfo{}
func putYolosToResult(am *structure.AreaMap) []structure.TargetInfo {
    locations := []structure.TargetInfo{}
    if len(am.FilterData) > 0 {
        for _, data := range am.FilterData {
            location := structure.TargetInfo{}
            location.Rect = data.Location
            location.TargetId = data.Id
            location.TargetScore = data.Score
@@ -430,7 +327,7 @@
}
// 联动任务的处理
func LinkTask(args *SdkDatas, groupRule *protomsg.GroupRule, taskId string, message *protomsg.SdkMessage, label Others) {
func LinkTask(args *structure.SdkDatas, groupRule *protomsg.GroupRule, taskId string, message *protomsg.SdkMessage, label structure.Others) {
    // new一个定时器,如果以此groupId为标志的定时器不存在的话
    logger.Info("------------------------------------------当前是联动任务,规则是:", groupRule.GroupText)
    var flag bool = true
@@ -461,7 +358,7 @@
                }
            }
            if flag1 {
                TimeEleList[groupRule.GroupId].RuleResults = append(TimeEleList[groupRule.GroupId].RuleResults, &RuleResult{groupRule.Rules[j].CameraId, groupRule.Rules[j].Sort, "", groupRule.Rules[j].RuleWithPre, ResultMsg{}})
                TimeEleList[groupRule.GroupId].RuleResults = append(TimeEleList[groupRule.GroupId].RuleResults, &RuleResult{groupRule.Rules[j].CameraId, groupRule.Rules[j].Sort, "", groupRule.Rules[j].RuleWithPre, structure.ResultMsg{}})
            }
        }
    }
@@ -478,19 +375,19 @@
                tempMap := make(map[string]interface{})
                for k, result := range args.RuleResult {
                    if k == "yolo" {
                        tempMap[k] = []Result{}
                        for _, res := range result.([]Result) {
                            tempMap[k] = append(tempMap[k].([]Result), res)
                        tempMap[k] = []structure.Result{}
                        for _, res := range result.([]structure.Result) {
                            tempMap[k] = append(tempMap[k].([]structure.Result), res)
                        }
                    }
                    if k == "face" {
                        tempMap[k] = []FaceResult{}
                        for _, res := range result.([]FaceResult) {
                            tempMap[k] = append(tempMap[k].([]FaceResult), res)
                        tempMap[k] = []structure.FaceResult{}
                        for _, res := range result.([]structure.FaceResult) {
                            tempMap[k] = append(tempMap[k].([]structure.FaceResult), res)
                        }
                    }
                }
                va.CacheData = ResultMsg{message, tempMap}
                va.CacheData = structure.ResultMsg{message, tempMap}
                logger.Info("这个摄像机--", args.CameraId, "--被赋予了result", va.Result)
            }
        }
@@ -520,19 +417,19 @@
                    rw.RLock()
                    if TimeEleList[groupRule.GroupId] != nil {  // 极偶尔有情况会等于nil,不知道为啥,做个判断以防宕机
                        // 把数组里缓存的数据取出来一起报警
                        label.LinkCache = []ResultMsg{}
                        label.LinkCache = []structure.ResultMsg{}
                        for _, ruleRes := range TimeEleList[groupRule.GroupId].RuleResults {
                            label.LinkCache = append(label.LinkCache, ruleRes.CacheData)
                        }
                        logger.Debug("联动任务缓存了几个数据", len(label.LinkCache))
                        for i := 0; i < len(args.RuleResult["yolo"].([]Result)); i++ {
                            if args.RuleResult["yolo"].([]Result)[i].RuleGroupId == groupRule.GroupId { // 把联动数据追加上
                                args.RuleResult["yolo"].([]Result)[i].Others.LinkCache = label.LinkCache
                        for i := 0; i < len(args.RuleResult["yolo"].([]structure.Result)); i++ {
                            if args.RuleResult["yolo"].([]structure.Result)[i].RuleGroupId == groupRule.GroupId { // 把联动数据追加上
                                args.RuleResult["yolo"].([]structure.Result)[i].Others.LinkCache = label.LinkCache
                            }
                        }
                        for i := 0; i < len(args.RuleResult["face"].([]FaceResult)); i++ {
                            if args.RuleResult["face"].([]FaceResult)[i].RuleGroupId == groupRule.GroupId { // 把联动数据追加上
                                args.RuleResult["face"].([]FaceResult)[i].Others.LinkCache = label.LinkCache
                        for i := 0; i < len(args.RuleResult["face"].([]structure.FaceResult)); i++ {
                            if args.RuleResult["face"].([]structure.FaceResult)[i].RuleGroupId == groupRule.GroupId { // 把联动数据追加上
                                args.RuleResult["face"].([]structure.FaceResult)[i].Others.LinkCache = label.LinkCache
                            }
                        }
                    }
@@ -544,15 +441,15 @@
            // 倒是把打的组规则标签给去掉了啊
            for _,val := range labelTypes {
                if val == 0 {
                    if len(args.RuleResult["yolo"].([]Result)) >= 1 {
                        lens := len(args.RuleResult["yolo"].([]Result))-1
                        args.RuleResult["yolo"] = args.RuleResult["yolo"].([]Result)[0:lens]
                    if len(args.RuleResult["yolo"].([]structure.Result)) >= 1 {
                        lens := len(args.RuleResult["yolo"].([]structure.Result))-1
                        args.RuleResult["yolo"] = args.RuleResult["yolo"].([]structure.Result)[0:lens]
                    }
                }
                if val == 1 {
                    if len(args.RuleResult["face"].([]FaceResult)) >= 1 {
                        lens := len(args.RuleResult["face"].([]FaceResult))-1
                        args.RuleResult["face"] = args.RuleResult["face"].([]FaceResult)[0:lens]
                    if len(args.RuleResult["face"].([]structure.FaceResult)) >= 1 {
                        lens := len(args.RuleResult["face"].([]structure.FaceResult))-1
                        args.RuleResult["face"] = args.RuleResult["face"].([]structure.FaceResult)[0:lens]
                    }
                }
            }
@@ -581,34 +478,34 @@
}
// 过滤规则先筛选出符合条件的目标数量
func filterRule(rule *protomsg.Rule, am *AreaMap) LittleRuleResult {
func filterRule(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    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.RuleWithPre == "||" {
                    return LittleRuleResult{}
                    return structure.LittleRuleResult{}
                } else {
                    //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 structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
                }
            }
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" { // 人脸检测
@@ -616,18 +513,18 @@
                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 []*Arg
                        logger.Info("-----------------------过规则之前区域内的人脸数量为:",am.TargetNum)
                        var args []*structure.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
@@ -644,39 +541,39 @@
                            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 structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                        } else {
                            return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                        }
                    }
                } else if rule.SdkArgAlias == "" { // 什么参数都不配的情况
                    if am.targetNum > 0 {
                        return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                    if am.TargetNum > 0 {
                        return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                    } else {
                        return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                        return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                    }
                }
            }
        }
    } 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
                var args []*structure.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
@@ -693,31 +590,31 @@
                    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 structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                } else {
                    return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                    return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                }
            } else if rule.SdkArgAlias == "" {
                if am.targetNum > 0 {
                    return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                if am.TargetNum > 0 {
                    return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                } else {
                    return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                    return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                }
            }
        }
    }
    return LittleRuleResult{}
    return structure.LittleRuleResult{}
}
// 如果有持续时间条件维护开启一个定时器
func duration(rule *protomsg.Rule, groupId string, am *AreaMap, args *SdkDatas, message *protomsg.SdkMessage) {
    if rule.PolygonId == am.areaId { // 首先规则所对应的区域id要跟区域数据的id对的上  配置的算法要对的上
func duration(rule *protomsg.Rule, groupId string, am *structure.AreaMap, args *structure.SdkDatas, message *protomsg.SdkMessage) {
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上  配置的算法要对的上
        if rule.SdkArgAlias == "duration" { //
            logger.Info("当前小规则是:---------", rule)
            // 先看看定时器元素队列中是否有这条规则的定时器,如果有就不能再次创建了
@@ -732,7 +629,7 @@
            if flag {
                timeLength, _ := strconv.Atoi(rule.SdkArgValue)
                timeEle := TimeElement{N: timeLength, InitN: timeLength, AlarmFlag: false, BufferFlag: 10, CacheSdkData: ResultMsg{message, args.RuleResult}} // 扔进去一个定时器元素(并缓存当前画面帧数据)
                timeEle := TimeElement{N: timeLength, InitN: timeLength, AlarmFlag: false, BufferFlag: 10, CacheSdkData: structure.ResultMsg{message, args.RuleResult}} // 扔进去一个定时器元素(并缓存当前画面帧数据)
                //TimeEleList = make(map[string]timeElement)
                TimeEleList[groupId+"+"+rule.Id] = &timeEle // 定时器元素以当前持续时间小规则id为键
                logger.Info("创建了计数器")
@@ -743,17 +640,17 @@
}
// 给数据库的规则表达式代参 args: 一条子规则,区域数据
func transferParameters(rule *protomsg.Rule, am *AreaMap) LittleRuleResult {
    if rule.PolygonId == am.areaId { // 首先规则所对应的区域id要跟区域数据的id对的上
func transferParameters(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    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 structure.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++
                }
@@ -761,14 +658,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 structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + " " + strconv.FormatBool(result.(bool)), rule.Sort}
            // 加上关于算法的判断条件,不能只有关于规则的,有的算法本身就是一个规则,如个体静止,靠右行,所以,拿到当前子规则的sdkid来判断是否是那些特殊的规则
        }
    }
    return LittleRuleResult{}
    return structure.LittleRuleResult{}
}
func timeRuleResult(rule *protomsg.Rule, am *AreaMap) LittleRuleResult {
    if rule.PolygonId == am.areaId { // 首先规则所对应的区域id要跟区域数据的id对的上
func timeRuleResult(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "time_rule" { // 判断是否符合时间规
            //logger.Info("----------当前时间规则:---------", rule)
            // 根据放值字段里存的时间规则的id去另一个表里查需要比对的时间段(比如当前时间是周三,应根据区域id查出其周三的几个布防时间段,数组)
@@ -783,11 +680,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)
@@ -796,18 +693,18 @@
                        break
                    }
                }
                return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + flag, rule.Sort}
                return structure.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)                      // 得到数学公式的结果
@@ -816,10 +713,10 @@
                        break
                    }
                }
                return LittleRuleResult{am.sdkName, rule.RuleWithPre + "" + flag, rule.Sort}
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
        }
    }
    return LittleRuleResult{}
    return structure.LittleRuleResult{}
}
ruleserver/timeTicker.go
@@ -3,6 +3,7 @@
import (
    "fmt"
    "basic.com/valib/logger.git"
    "ruleprocess/structure"
    "strings"
    "time"
)
@@ -18,7 +19,7 @@
    InitN        int       // 赋值后就不变的初始值
    BufferFlag   int       // 缓冲容错位 连续n帧false才为false
    AlarmFlag    bool      // 报警标志位 定时器开启后第一次报警时会被置为true 往后再来报警也不会插进ES
    CacheSdkData ResultMsg // 定时器的缓存数据 持续时间类的开启定时器时要缓存一帧
    CacheSdkData structure.ResultMsg // 定时器的缓存数据 持续时间类的开启定时器时要缓存一帧
    GroupId      string    // 联动规则需要记录下此时的规则组id
    RuleResults  []*RuleResult
}
@@ -28,7 +29,7 @@
    Sort        int32     // 摄像机在规则组中序号
    Result      string    // 摄像机过滤数据得出的结果
    RuleWithPre string    // 摄像机之间的连接符
    CacheData   ResultMsg // 缓存当前帧数据
    CacheData   structure.ResultMsg // 缓存当前帧数据
}
func TimeTicker() {
@@ -69,7 +70,7 @@
}
// 判断是否符合定时器条件
func TimerAlarm(oth *Others, groupId string, result bool) (string) {
func TimerAlarm(oth *structure.Others, groupId string, result bool) (string) {
    var flagTime string //
    // 判断有无此规则组的定时器
    flag := false
@@ -93,7 +94,7 @@
                        logger.Debug("———————————-------------首次符合持续时间规则并报警")
                        flagTime = "10"
                        timeEle.AlarmFlag = true
                        oth.CacheData = []ResultMsg{}
                        oth.CacheData = []structure.ResultMsg{}
                        oth.CacheData = append(oth.CacheData,timeEle.CacheSdkData)
                        oth.TimeLabel = flagTime
                    }
@@ -147,7 +148,7 @@
func (p SubList) Less(i, j int) bool { return p[i].Sort < p[j].Sort }
// 结构体根据某字段排序
type resultList []*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) }
structure/gragh.go
New file
@@ -0,0 +1,21 @@
package structure
//Point 坐标点
type Point struct {
    X float64 `json:"x"`
    Y float64 `json:"y"`
}
//Rect 检测目标
type Rect struct {
    X      float64
    Y      float64
    Width  float64
    Height float64
}
//Pointfloat 坐标点
type Pointfloat struct {
    X float64 `json:"x"`
    Y float64 `json:"y"`
}
structure/rule.go
New file
@@ -0,0 +1,132 @@
package structure
import "basic.com/pubsub/protomsg.git"
// 每个目标的参数:相似度,占比,尺寸
type Arg struct {
    Id         uint64
    Score      float64 // 区域内的目标的相似度
    Proportion float64 // 区域内的目标的占比
    Size       float64 // 区域内的目标的尺寸
    IsYolo     bool    // 是否是yolo数据
    Location   Rect    // 记下每个目标的位置参数,最后给结果装配人脸数据的时候用的到
    Feature    []byte
    ThftRes    protomsg.ThftResult
    Liker      []*BaseInfo
}
// 每个区域内的图片数据集合
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   // 是否静止
}
// sdk输出的图片上单个目标的数据
type PhotoMap struct {
    Id      uint64
    Rects   Rect    // 矩形区域参数
    Score   float64 // 相似度得分(有多大程度像一个目标。人脸,人体或车等等)
    IsYolo  bool    // 是否是yolo数据
    ThftRes protomsg.ThftResult
    Feature []byte
}
// 每个算法对于当前帧画面自己提取的数据
type SdkData struct {
    TaskId      string
    IpcId       string
    IsYolo      bool
    Photo       []PhotoMap // yolo算法结构,也可以存人脸的数据,毕竟人脸中能用规则来测的还是那些参数
    KeepRight   bool       // 是否靠右行 算法判断的与上一帧图像的比较结果
    IsStatic    bool       // 是否静止
    ImageWidth  int        // 摄像机拍摄的图像宽 像素
    ImageHeight int        // 摄像机拍摄的图像高 像素
    AreaMapList []*AreaMap // 本sdk提取的数据按照区域划分后的数据集合
}
// 从算法模块儿拿来的对一帧图像各个算法提取的数据集合
type SdkDatas struct {
    CameraId   string
    TaskId     string
    Sdkdata    []*SdkData
    RuleResult map[string]interface{} // 过完规则后打的标签 face: []FaceResult, yolo: []Result
}
type ResultMsg struct {
    *protomsg.SdkMessage
    RuleResult map[string]interface{} // 过完规则后打的标签 face: []FaceResult, yolo: []Result
}
// 过规则库打上的标签
type Result struct {
    TaskId       string // 任务id
    SdkName      string
    RuleGroupId  string // 规则组id
    DefenceState bool   // 是否布防
    AlarmLevel   int32  // 报警等级
    RuleText     string // 文字版规则组
    Location     []TargetInfo // 目标的坐标
    AlarmPolygon string // 触发的报警框
    IsLink       bool   // 是否是联动任务
    Others
}
type Others struct {
    CacheData []ResultMsg //(本组规则中含有持续时间的规则开启的定时器缓存的数据帧)
    LinkCache []ResultMsg
    TimeLabel string
}
type TargetInfo struct {
    Rect
    TargetId    uint64
    TargetScore float64
}
// 过规则库打上的标签
type FaceResult struct {
    Result
    Args []Arg
}
type LittleRuleResult struct {
    SdkName string // 记录下此结果是哪个sdk的结果
    Result  string // 已包含了前置连接符
    Sort    int32
}
type TimeRange struct {
    Start string `json:"start"`
    End   string `json:"end"`
}
type Day struct {
    Day       int         `json:"day"`        // 标示当前星期几
    TimeRange []TimeRange `json:"time_range"` // 当天的几个时间段
}
type BaseInfo struct {
    TableId      string  `json:"tableId"`
    TableName    string  `json:"tableName"`
    BwType       string  `json:"bwType"`
    CompareScore float64 `json:"compareScore"`
    PersonId     string  `json:"personId"`
    PersonName   string  `json:"personName"`
    PersonPicUrl string  `json:"personPicUrl"`
    PhoneNum     string  `json:"phoneNum"`
    Sex          string  `json:"sex"`
    IdCard       string  `json:"idCard"`
    MonitorLevel string  `json:"monitorLevel"`
    Content      string  `json:"content"`
}
util/105.jpg
Binary files differ
util/simpleCV.go
@@ -11,6 +11,7 @@
    "ruleprocess/cache"
    "basic.com/valib/logger.git"
    "ruleprocess/ruleserver"
    "ruleprocess/structure"
    "strings"
)
@@ -155,7 +156,7 @@
    }
}
func DrawPolygonOnImageForYolo(cameraId string, img protomsg.Image, results []ruleserver.Result,url string) (maps map[string]interface{}, err0 error) {
func DrawPolygonOnImageForYolo(cameraId string, img protomsg.Image, results []structure.Result,url string) (maps map[string]interface{}, err0 error) {
    rook, _ := gocv.NewMatFromBytes(int(img.Height), int(img.Width), gocv.MatTypeCV8UC3, img.Data)
    //rook := gocv.IMRead("/home/user/workspace/ruleprocess/util/105.jpg",gocv.IMReadColor)
@@ -187,7 +188,7 @@
    return
}
func DrawPolygonOnImageForFace(cameraId string, img protomsg.Image, results []ruleserver.FaceResult,url string) (maps map[string]interface{}, err0 error) {
func DrawPolygonOnImageForFace(cameraId string, img protomsg.Image, results []structure.FaceResult,url string) (maps map[string]interface{}, err0 error) {
    rook, _ := gocv.NewMatFromBytes(int(img.Height), int(img.Width), gocv.MatTypeCV8UC3, img.Data)
    //rook := gocv.IMRead("/home/user/workspace/ruleprocess/util/105.jpg",gocv.IMReadColor)
util/simpleCV_test.go
@@ -5,9 +5,9 @@
)
func TestDrawPolygonOnImage(t *testing.T)  {
    resp,err := DrawPolygonOnImage()
    if err != nil {
        t.Error("画框或者上传有问题")
    }
    t.Log("------=============",resp)
    //resp,err := DrawPolygonOnImage()
    //if err != nil {
    //    t.Error("画框或者上传有问题")
    //}
    //t.Log("------=============",resp)
}