panlei
2019-11-01 e6982607fbbeaa96d3d14409df780266646b793d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
package ruleserver
 
import (
    "basic.com/pubsub/protomsg.git"
    "github.com/golang/protobuf/proto"
    "basic.com/valib/logger.git"
    "ruleprocess/structure"
)
 
var TrackPond = make(map[string]*PersonTrack)
 
type PersonTrack struct {
    Faces []*Face // 人脸的数组  改为数量
    Yolo  int     // yolo对象的id数组 改为数量
}
type Face struct {
    Id    uint64
    Score float32
}
 
var num int = 25
// 检查是否前后两次的数据id是否完全相同(人脸)
func FaceIsSame(msg *protomsg.SdkMessage) {
    logger.Debug("+++++++++++++++++++++人脸追踪开始+++++++++++++++摄像机id为:", msg.Cid, "---缓存池为:", TrackPond)
    for _, sdkinfo := range msg.Tasklab.Sdkinfos { // 遍历各算法的sdkData
        if sdkinfo.Sdktype == "FaceDetect" { // 人脸检测
            logger.Info("数据长度为:", len(sdkinfo.Sdkdata))
            if len(sdkinfo.Sdkdata) > 1 {
                num = 25
                FaceIsInPond(msg.Cid, sdkinfo)
            } else {
                if num > 0 { // 连续num次没有数据才算是没有数据,不然只算作丢帧
                    logger.Info("我认为你只是丢帧了,此时的num值为:",num)
                    num--
                } else {
                    if TrackPond[msg.Cid] != nil {
                        logger.Info("如果不为空:", TrackPond[msg.Cid])
                        TrackPond[msg.Cid].Faces = nil
                    } else {
                        TrackPond[msg.Cid] = &PersonTrack{Faces: nil}
                        logger.Info("如果为空:", TrackPond[msg.Cid])
                    }
                    logger.Info("摄像机:" + msg.Cid + "-没有人脸,被重置为空")
                    continue
                }
            }
        }
    }
    logger.Debug("--------------------------------人脸追踪结束--------------------------------------")
}
 
//  追踪人体,检查数量是否一致
func BodyIsSame(args *structure.SdkDatas,msg *protomsg.SdkMessage) bool{
    logger.Debug("+++++++++++++++++++++人体追踪开始+++++++++++++++摄像机id为:", msg.Cid, "---缓存池为:", TrackPond)
    for _, sdkinfo := range msg.Tasklab.Sdkinfos { // 遍历各算法的sdkData
        if sdkinfo.Sdktype == "Yolo" {
                    if len(sdkinfo.Sdkdata) > 1 {
                        yoloParam := protomsg.ParamYoloObj{}
                        err := proto.Unmarshal(sdkinfo.Sdkdata, &yoloParam)
                        if err != nil {
                            logger.Info("解析yolo数据时出现错误", err)
                            continue
                        }
                        var yoloNum int = 0
                        for i := 0; i < len(yoloParam.Infos); i++ {
                            if yoloParam.Infos[i].Typ == 0 {
                                yoloNum++
                            }
                        }
                        if TrackPond[msg.Cid] != nil {
                            logger.Info("================追踪之前yolo的个数:", yoloNum, "现在缓存池中记录的个数:", TrackPond[msg.Cid].Yolo)
                        } else {
                            logger.Info("================追踪之前yolo的个数:", yoloNum, "还没有这个摄像机的缓存")
                        }
                        if yoloParam.Infos != nil && TrackPond[msg.Cid] != nil && yoloNum == TrackPond[msg.Cid].Yolo { // yolo的如果数量相同则视为不变、把yolo的sdkData清空
                            yoloParam.Infos = (yoloParam.Infos)[0:0]
                            sdkinfo.Sdkdata, err = proto.Marshal(&yoloParam)
                            if err != nil {
                                logger.Error("yolo序列化错误", err)
                            }
                            delete(args.RuleResult,"yolo")
                            logger.Info("清除yolo标签,",args.RuleResult["yolo"])
                            logger.Info("跟之前相同,清空yolo数据,人体追踪结束")
                            return true
                        } else {
                            if TrackPond[msg.Cid] != nil {
                                logger.Info("更新当前摄像机缓存池中的yolo个数:", yoloNum)
                                TrackPond[msg.Cid].Yolo = yoloNum
                            } else {
                                logger.Info("新建当前摄像机缓存池中的yolo个数:", yoloNum)
                                TrackPond[msg.Cid] = &PersonTrack{Yolo: yoloNum}
                            }
                            logger.Debug("---------------------------------人体追踪结束--------------------------------------")
                            return false
                        }
                    } else {
                        if TrackPond[msg.Cid] != nil {
                            TrackPond[msg.Cid].Yolo = 0
                        } else {
                            TrackPond[msg.Cid] = &PersonTrack{Yolo: 0}
                        }
                        logger.Info("摄像机:" + msg.Cid + "-没有yolo,被重置为0")
                        continue
            }
        }
    }
    logger.Debug("---------------------------------人体追踪结束--------------------------------------")
    return false
}
func TrackOrNot(label map[string]interface{}) bool{
    if label["yolo"] != nil && len(label["yolo"].([]structure.Result)) > 0 {
        for _,res := range label["yolo"].([]structure.Result) {
            if res.TimeLabel == "10" {
                return true
            }
        }
    }
    return false
}
 
// 过滤掉那些已在缓存中且分值更低的人脸,更新缓存(没有的加上,分值更新为更高的,多的删除)
func FaceIsInPond(cameraId string, sdkinfor *protomsg.SdkmsgWithTask) {
    if TrackPond[cameraId] != nil {
        logger.Info("----马前炮:", TrackPond[cameraId], "=====", len(TrackPond[cameraId].Faces))
        for _,face := range TrackPond[cameraId].Faces  {
            logger.Info("缓存中存储的face数据:",face.Id,face.Score)
        }
        faceParam := protomsg.ParamFacePos{}
        err := proto.Unmarshal(sdkinfor.Sdkdata, &faceParam)
        if err != nil {
            logger.Info("解析face sdk数据时出现错误", err)
        }
        logger.Info("================追踪之前人脸的个数:", len(faceParam.Faces))
        for _,face := range faceParam.Faces  {
            logger.Info("新来的的face数据:",face.Pos.FaceID,face.Pos.FAngle.Confidence)
        }
        var facesTemp []protomsg.ResultFaceDetect
        for _,face := range faceParam.Faces {
            facesTemp = append(facesTemp,*face) // 先把数据转存一份,不然一会儿数据删减之后找不到原始数据,不能让缓存数据更新了
        }
 
        for i := 0; i < len(faceParam.Faces); {
            faceFlag := false
            for _, val := range TrackPond[cameraId].Faces {
                if faceParam.Faces[i].Pos.FaceID == val.Id && faceParam.Faces[i].Pos.FAngle.Confidence <= val.Score { // 在池子里并且分值更低,是要抛弃的数据
                    faceFlag = true
                    //return "true"
                    logger.Info("分值为:",faceParam.Faces[i].Pos.FAngle.Confidence,"--缓存的分值为:",val.Score,"此数据由于在池子中且分值更低,是要被抛弃的数据")
                    faceParam.Faces = append(faceParam.Faces[:i], faceParam.Faces[i+1:]...)
                    break
                }
                if faceParam.Faces[i].Pos.FaceID == val.Id && faceParam.Faces[i].Pos.FAngle.Confidence > val.Score { // 在池子里并且分值更高,更新缓存
                    faceFlag = true
                    logger.Info("分值由", val.Score, "更新为:", faceParam.Faces[i].Pos.FAngle.Confidence, "此数据由于在池子中且分值更高,是要被传递下去的数据")
                    val.Score = faceParam.Faces[i].Pos.FAngle.Confidence
                }
            }
            if !faceFlag { // 此人脸不在池子中
                logger.Info("此人脸不在池子中,往池子中添加数据更新缓存")
                TrackPond[cameraId].Faces = append(TrackPond[cameraId].Faces, &Face{faceParam.Faces[i].Pos.FaceID, faceParam.Faces[i].Pos.FAngle.Confidence})
                i++
            }
        }
        logger.Info("反序列化重新装配之前人脸的个数:",len(faceParam.Faces))
        logger.Info("临时存储的新来数据:")
        for _, temp := range facesTemp {
            logger.Info("临时存储的新来的的face数据:",temp.Pos.FaceID,temp.Pos.FAngle.Confidence)
        }
        sdkinfor.Sdkdata, err = proto.Marshal(&faceParam)
        if err != nil {
            logger.Error("人脸序列化错误", err)
        }
        // 反向循环 ,看那些缓存有而数据没有的就删除数据更新缓存
        for i := 0; i < len(TrackPond[cameraId].Faces); {
            flag := false
            for _, temp := range facesTemp {
                if TrackPond[cameraId].Faces[i].Id == temp.Pos.FaceID {
                    flag = true
                }
            }
            if flag {
                i++
            } else {
                // 此数据在缓存中但不在来的数据帧中,删除此数据更新缓存
                logger.Info("删除池子中的数据更新缓存")
                TrackPond[cameraId].Faces = append(TrackPond[cameraId].Faces[:i], TrackPond[cameraId].Faces[i+1:]...)
            }
        }
    } else {
        TrackPond[cameraId] = &PersonTrack{Faces: nil} 
    }
}