package main
|
|
import (
|
"basic.com/pubsub/protomsg.git"
|
"basic.com/valib/logger.git"
|
"encoding/base64"
|
"encoding/json"
|
"github.com/golang/protobuf/proto"
|
uuid "github.com/satori/go.uuid"
|
"ruleprocess/ruleserver"
|
"ruleprocess/structure"
|
"ruleprocess/util"
|
"strconv"
|
"time"
|
)
|
func ReadData(args *structure.SdkDatas,cameraPolygons []protomsg.CameraPolygon) {
|
for _, arg := range args.Sdkdata {
|
SdkDataFormat(args.CameraId, arg, cameraPolygons)
|
}
|
}
|
|
// 计算区域内的目标数量以及将相似度、占比、尺寸等打包
|
func CountAreaObjs(a *structure.AreaMap,arg *structure.SdkData) {
|
|
a.TargetNum = 0
|
threshold := 0.0 // 相似度
|
intersectionper := 20.0 // 占比
|
size := 0.0 // 尺寸
|
|
areaPoints := ruleserver.Json2points(a.AreaJson)
|
logger.Info("看看图片的width和height:",arg.ImageWidth,arg.ImageHeight)
|
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 obj.Score >= threshold && float64(obj.Rects.Width*obj.Rects.Height) >= size && ruleserver.PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale) >= intersectionper {
|
// 这步要备齐表达式里所需要的所有参数
|
a.TargetNum++
|
uuid := uuid.NewV4().String()
|
arg1 := structure.Arg{structure.SourceArg{obj.Id,uuid,obj.Score, ruleserver.PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), float64(obj.Rects.Width * obj.Rects.Height), a.AreaJson,obj.Type, obj.Rects, obj.Car,obj.Feature,obj.ThftRes, []*structure.BaseInfo{},"",structure.ResultMsg{}},structure.SourceArg{}}
|
//logger.Println("放进去的arg:-------", 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]
|
//logger.Println("--------------------看看区域数据:",*a)
|
}
|
|
// 把sdk从数据帧上提取的按照区域分类归置
|
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 := structure.AreaMap{CameraId: cameraId, AreaId: polygon.Id,AreaJson: polygon.Polygon, TriggerLine: polygon.TriggerLine, DirectionLine: polygon.DirectionLine}
|
// 为每个摄像机区域填充数据
|
CountAreaObjs(&areaMap,arg)
|
arg.AreaMapList = append(arg.AreaMapList, &areaMap)
|
}
|
}
|
|
|
|
// 将外部传进来的rect(top,bottom,left,right)转化为自己内部的rect(left top width height)
|
func rectFormat(rcobj *protomsg.Rect) structure.Rect {
|
//logger.Info("++++++++++++++++++++++++++++++收到的yolo的区域坐标:",rcobj)
|
rect := structure.Rect{}
|
rect.X = float64(rcobj.Left)
|
rect.Y = float64(rcobj.Top)
|
rect.Width = float64(rcobj.Right - rcobj.Left)
|
rect.Height = float64(rcobj.Bottom - rcobj.Top)
|
return rect
|
}
|
|
// 将外部传进来的sdk数据包解成 SdkDatas
|
func ParamFormat(msg []byte, args *structure.SdkDatas) protomsg.SdkMessage {
|
defer func() {
|
if err := recover(); err != nil {
|
logger.Info("解包过程的异常捕获", err.(string))
|
}
|
}()
|
// 反序列化数据得到sdk入参
|
m := protomsg.SdkMessage{}
|
err := proto.Unmarshal(msg, &m)
|
if err != nil {
|
panic("解析msg时出现错误")
|
}
|
|
// 先进行一下追踪
|
ruleserver.FaceIsSame(&m)
|
args.CameraId = m.Cid
|
args.TaskId = m.Tasklab.Taskid
|
// 把图片的二进制解压缩进行画框在压缩回去
|
bdata, err := util.UnCompress(m.Data)
|
if err != nil {
|
panic("解压缩图片时出现错误")
|
}
|
i := protomsg.Image{}
|
err = proto.Unmarshal(bdata, &i)
|
logger.Info("接到数据,摄像机为:", m.Cid, "图片的id为:", i.Id)
|
//logger.Info("----------------看看有几个算法:",len(m.Tasklab.Sdkinfos))
|
for _, sdkinfo := range m.Tasklab.Sdkinfos { // yolo算法
|
switch sdkinfo.Sdktype {
|
case "Yolo":
|
extractYolo(args,m,sdkinfo,i)
|
case "FaceDetect":
|
extractFace(args,m,sdkinfo,i)
|
case "Plate":
|
extractCar(args,m,sdkinfo,i)
|
case "HumanTrack":
|
extractTrack(args,m,sdkinfo,i)
|
}
|
}
|
return m
|
}
|
|
// 提取face
|
func extractFace(args *structure.SdkDatas,m protomsg.SdkMessage,sdkinfo *protomsg.SdkmsgWithTask,i protomsg.Image) {
|
arg := structure.SdkData{}
|
arg.TaskId = m.Tasklab.Taskid
|
arg.IpcId = sdkinfo.Ipcid
|
arg.IsYolo = false
|
arg.ImageWidth = int(i.Width)
|
arg.ImageHeight = int(i.Height)
|
if len(sdkinfo.Sdkdata) > 1 {
|
faceParam := protomsg.ParamFacePos{}
|
err := proto.Unmarshal(sdkinfo.Sdkdata, &faceParam)
|
if err != nil {
|
logger.Info("解析FACE sdk数据时出现错误", err)
|
return
|
}
|
logger.Info("--------------追踪之后人脸的个数:", len(faceParam.Faces))
|
for _, info := range faceParam.Faces {
|
//logger.Info("_______________________________________________第一次看相似值:",info.Pos.FAngle.Confidence*100)
|
photoMap := structure.PhotoMap{structure.SourcePhoto{Id: strconv.Itoa(int(info.Pos.FaceID)) , Rects: rectFormat(info.Pos.RcFace), Score: float64(info.Pos.FAngle.Confidence * 100), Type: "face", ThftRes: *(info.Result), Feature: base64.StdEncoding.EncodeToString(info.Feats)},structure.SourcePhoto{}}
|
arg.Photo = append(arg.Photo, photoMap)
|
}
|
args.Sdkdata = append(args.Sdkdata, &arg)
|
}
|
}
|
// 提取yolo
|
func extractYolo(args *structure.SdkDatas,m protomsg.SdkMessage,sdkinfo *protomsg.SdkmsgWithTask,i protomsg.Image) {
|
arg := structure.SdkData{}
|
arg.TaskId = m.Tasklab.Taskid
|
arg.IpcId = sdkinfo.Ipcid
|
arg.IsYolo = true
|
arg.ImageWidth = int(i.Width)
|
arg.ImageHeight = int(i.Height)
|
logger.Info("-----追踪之后sdkinfo.Sdkdata的长度为:----", len(sdkinfo.Sdkdata))
|
if len(sdkinfo.Sdkdata) > 1 {
|
// 大于1才有数据
|
yoloParam := protomsg.ParamYoloObj{}
|
err := proto.Unmarshal(sdkinfo.Sdkdata, &yoloParam)
|
if err != nil {
|
logger.Info("解析YOLO sdk数据时出现错误", err)
|
return
|
}
|
var yoloNum int = 0
|
for _, info := range yoloParam.Infos {
|
if info.Typ == 0 {
|
//logger.Debug("-------------yolo的坐标有几个",info.RcObj)
|
photoMap := structure.PhotoMap{structure.SourcePhoto{Rects: rectFormat(info.RcObj), Score: float64(info.Prob) * 100, Type: "yolo",Id:strconv.Itoa(int(info.ObjID))},structure.SourcePhoto{}}
|
arg.Photo = append(arg.Photo, photoMap)
|
yoloNum++
|
}
|
}
|
logger.Info("--------------追踪之后yolo的个数:", yoloNum)
|
args.Sdkdata = append(args.Sdkdata, &arg)
|
} else {
|
return
|
}
|
}
|
|
// 提取car
|
func extractCar(args *structure.SdkDatas,m protomsg.SdkMessage,sdkinfo *protomsg.SdkmsgWithTask,i protomsg.Image) {
|
arg := structure.SdkData{}
|
arg.TaskId = m.Tasklab.Taskid
|
arg.IpcId = sdkinfo.Ipcid
|
arg.IsYolo = false
|
arg.ImageWidth = int(i.Width)
|
arg.ImageHeight = int(i.Height)
|
if len(sdkinfo.Sdkdata) > 1 {
|
plateIDResult := protomsg.PlateIDResult {}
|
err := proto.Unmarshal(sdkinfo.Sdkdata, &plateIDResult )
|
if err != nil {
|
logger.Info("解析车牌数据时出现错误", err)
|
return
|
}
|
for _, info := range plateIDResult.Result {
|
logger.Info("接收车牌数据:",info.FvdConf,info.NVehicleColor1,info.NPlateFlag,info.RcCarLocation)
|
if info.NConfidence > 70 {
|
logger.Info("车牌也符合的数据",info.FvdConf,info.NVehicleColor1,info.NPlateFlag,info.RcCarLocation,info.NConfidence,)
|
photoMap := structure.PhotoMap{structure.SourcePhoto{Id: info.License,Score: float64(info.FvdConf)*100,Rects: rectFormat(info.RcCarLocation), Type: "plate", Car:info},structure.SourcePhoto{}}
|
arg.Photo = append(arg.Photo, photoMap)
|
}
|
}
|
args.Sdkdata = append(args.Sdkdata, &arg)
|
} else {
|
return
|
}
|
}
|
|
// 提取跟踪
|
func extractTrack(args *structure.SdkDatas,m protomsg.SdkMessage,sdkinfo *protomsg.SdkmsgWithTask,i protomsg.Image) {
|
arg := structure.SdkData{}
|
arg.TaskId = m.Tasklab.Taskid
|
arg.IpcId = sdkinfo.Ipcid
|
arg.IsYolo = false
|
arg.ImageWidth = int(i.Width)
|
arg.ImageHeight = int(i.Height)
|
if len(sdkinfo.Sdkdata) > 1 {
|
|
Track := protomsg.HumanTrackResult {}
|
err := proto.Unmarshal(sdkinfo.Sdkdata, &Track)
|
if err != nil {
|
logger.Info("解析跟踪目标数据时出现错误", err)
|
return
|
}
|
for _, info := range Track.Result {
|
logger.Info("接收跟踪数据:",info.Id,info.Confidence)
|
b,_ := json.Marshal(info.Feature)
|
photoMap := structure.PhotoMap{structure.SourcePhoto{Id: strconv.Itoa(int(info.Id)),Score: float64(info.Confidence)*100,Rects: rectFormat(info.RcHuman), Type: "track",Feature: base64.StdEncoding.EncodeToString(b)},structure.SourcePhoto{}}
|
arg.Photo = append(arg.Photo, photoMap)
|
}
|
args.Sdkdata = append(args.Sdkdata, &arg)
|
} else {
|
return
|
}
|
}
|
|
// 把人脸放进对应的人体
|
func FacePush2Body (photomap *structure.PhotoMap,sdkInfos []*protomsg.SdkmsgWithTask) {
|
for _,sdkinfo := range sdkInfos {
|
if sdkinfo.Sdktype == "FaceDetect" {
|
faceParam := protomsg.ParamFacePos{}
|
err := proto.Unmarshal(sdkinfo.Sdkdata, &faceParam)
|
if err != nil {
|
logger.Info("解析FACE sdk数据时出现错误", err)
|
return
|
}
|
logger.Info("--------------追踪之后人脸的个数:", len(faceParam.Faces))
|
for _, info := range faceParam.Faces {
|
percent := ruleserver.PgsInterPercent(Rect2Point(photomap.Rects),rectFormat(info.Pos.RcFace), 1, 1)
|
if percent > 99 {
|
photomap.AttachObj = structure.SourcePhoto{Id:strconv.Itoa(int(info.Pos.FaceID)),Rects: rectFormat(info.Pos.RcFace),Score: float64(info.Pos.FAngle.Confidence * 100), Type: "face", ThftRes: *(info.Result), Feature: base64.StdEncoding.EncodeToString(info.Feats)}
|
}
|
}
|
}
|
}
|
}
|
|
func Rect2Point(rect structure.Rect) []structure.Point{
|
// 按逆时针转化
|
points := []structure.Point{}
|
leftTop := structure.Point{rect.X,rect.Y}
|
points = append(points,leftTop)
|
leftBottom := structure.Point{rect.X,rect.Y+rect.Height}
|
points = append(points,leftBottom)
|
rightBottom := structure.Point{rect.X+rect.Width,rect.Y+rect.Height}
|
points = append(points,rightBottom)
|
rightTop := structure.Point{rect.X+rect.Width,rect.Y}
|
points = append(points,rightTop)
|
return points
|
}
|