You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何针对特定Object ID关联性别检测以实现精准男女计数?

实现思路与代码修改方案

核心目标是将每个跟踪到的Object ID与对应的性别信息绑定,仅在人员首次被检测到(新ID注册)时执行性别检测,在人员离开(ID注销)时更新男女总计数,彻底避免逐帧重复统计的问题。

1. 初始化必要的状态变量

在循环开始前,定义几个关键变量来存储跟踪状态和统计数据:

# 存储每个Object ID对应的性别信息
id_gender_map = {}
# 记录上一帧的跟踪ID集合,用于对比新增/注销的ID
previous_ids = set()
# 男女总计数
total_male = 0
total_female = 0
# 统计会话内出现的总唯一人数(替代原来的totalppl)
total_unique_ppl = set()

2. 识别新增与注销的Object ID

每次调用ct.update(rects)后,对比当前帧和上一帧的ID集合,找出新增(人员进入)和注销(人员离开)的ID:

objects, intervals = ct.update(rects)
current_ids = set(objects.keys())

# 计算新增ID(当前有但上一帧没有的)和注销ID(上一帧有但当前没有的)
new_ids = current_ids - previous_ids
removed_ids = previous_ids - current_ids

3. 为新增ID绑定性别并更新计数

对于新增的ID,我们需要找到它对应的人脸区域,执行一次性别检测,然后将结果存入映射表,并更新男女计数:

# 先计算当前所有人脸rect的质心,方便和新增ID的质心匹配
rect_centroids = []
for (x1, y1, x2, y2) in rects:
    cx = (x1 + x2) // 2
    cy = (y1 + y2) // 2
    rect_centroids.append( ((x1, y1, x2, y2), (cx, cy)) )

# 处理新增ID
for obj_id in new_ids:
    obj_centroid = objects[obj_id]
    # 找到距离当前ID质心最近的人脸rect(匹配跟踪到的ID对应的人脸)
    min_dist = float('inf')
    matched_rect = None
    for rect, rect_c in rect_centroids:
        dist = ((obj_centroid[0] - rect_c[0])**2 + (obj_centroid[1] - rect_c[1])**2)**0.5
        if dist < min_dist:
            min_dist = dist
            matched_rect = rect
    
    if matched_rect and run_age_gender:
        x, y, x2, y2 = matched_rect
        w = x2 - x
        h = y2 - y
        cropped_image = frame[y:y+h, x:x+w]
        if cropped_image.size > 0:
            age_inference.infer(cropped_image)
            age, gender = age_inference.get_age_gender_data()
            # 将性别与ID绑定
            id_gender_map[obj_id] = gender
            # 更新总计数
            if gender == 'Male':
                total_male += 1
            elif gender == 'Female':
                total_female += 1
            # 更新总唯一人数
            total_unique_ppl.add(obj_id)
            # 更新UI显示
            self.ui.male_count.setText(str(total_male))
            self.ui.female_count.setText(str(total_female))
            self.ui.ppltextbox.setPlainText(str(len(total_unique_ppl)))

4. 处理注销ID并更新计数

当ID被注销(人员离开)时,从映射表中移除该ID的性别信息,并相应减少对应性别的计数:

# 处理注销ID
for obj_id in removed_ids:
    if obj_id in id_gender_map:
        gender = id_gender_map.pop(obj_id)
        # 更新总计数
        if gender == 'Male':
            total_male -= 1
        elif gender == 'Female':
            total_female -= 1
        # 更新UI显示
        self.ui.male_count.setText(str(total_male))
        self.ui.female_count.setText(str(total_female))

5. 更新上一帧ID集合

最后,在每帧结束前更新previous_ids,为下一次对比做准备:

previous_ids = current_ids.copy()

额外优化建议

  • 避免重复检测:除非跟踪到的人脸出现大幅偏移或丢失后重新识别,否则不需要对已绑定性别的ID重复执行性别检测,这样能减少推理开销。
  • 性别检测容错:如果某次性别检测失败(比如人脸区域过小),可以在后续帧中尝试重新检测该ID对应的人脸,直到成功绑定性别。
  • 修正总时长统计:原来的totaltime统计逻辑会逐帧累加每个ID的时间,导致重复计算。建议在Centroid Tracker中为每个ID维护单独的停留时长,当ID注销时,将其时长累加到总时长中。

内容的提问来源于stack exchange,提问作者Shweta Katti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 16:07:47