105.jpg | 补丁 | 查看 | 原始文档 | blame | 历史 | |
go.mod | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
go.sum | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
insertdata/insertDataToEs.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
labelFilter/readyDataForLabel.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
labelFilter/req.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
labelFilter/ruleForLabel.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruleserver/geoPolygon.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruleserver/personTrack.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruleserver/readyDataForRule.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruleserver/ruleToformula.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruleserver/timeTicker.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
structure/gragh.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
structure/rule.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
util/105.jpg | 补丁 | 查看 | 原始文档 | blame | 历史 | |
util/simpleCV.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
util/simpleCV_test.go | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
105.jpgBinary 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.jpgBinary 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) }