panlei
2019-07-30 c620c6eed928d0f308bee212c40ca67abde9baeb
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
package ruleserver
 
import (
    "basic.com/pubsub/protomsg.git"
    "github.com/golang/protobuf/proto"
    "ruleprocess/logger"
)
 
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 = 5
// 检查是否前后两次的数据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 = 5
                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(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)
                            //}
                            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}
                            }
                            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 FaceIsInPond(cameraId string, sdkinfor *protomsg.SdkmsgWithTask) string {
    if TrackPond[cameraId] != nil {
        logger.Info("----马前炮:", TrackPond[cameraId], "=====", len(TrackPond[cameraId].Faces))
        faceParam := protomsg.ParamFacePos{}
        err := proto.Unmarshal(sdkinfor.Sdkdata, &faceParam)
        if err != nil {
            logger.Info("解析face sdk数据时出现错误", err)
        }
        logger.Info("================追踪之前人脸的个数:", len(faceParam.Faces))
        var facesTemp = faceParam.Faces // 先把数据转存一份,不然一会儿数据删减之后找不到原始数据,不能让缓存数据更新了
        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))
        sdkinfor.Sdkdata, err = proto.Marshal(&faceParam)
        if err != nil {
            logger.Error("yolo序列化错误", err)
        }
        logger.Info("跟之前相同,清空yolo数据")
        // 反向循环 ,看那些缓存有而数据没有的就删除数据更新缓存
        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 {
        return "false"
    }
    return "false"
}