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

PyOpenGL多人体3D关键点可视化闪烁问题求助

问题根源与解决方案

核心闪烁原因

你的代码在遍历多个人体的循环里,每绘制一个人体就调用pygame.display.flip()和pygame.time.wait(10),这会导致屏幕逐次刷新单个人体的画面,视觉上就会出现明显闪烁。正确逻辑是绘制完所有人体后再统一刷新一次屏幕。

关键修复与优化点

  • 不要把points和lines函数定义放在主循环内,每次循环重新定义函数完全没必要,会严重拖慢运行效率。
  • 移除重复的GL状态启用代码,将状态初始化放在循环外,避免重复调用。
  • 启用GL_DEPTH_TEST深度测试,解决3D场景中物体遮挡关系错误的问题。
  • 修正循环变量错误:遍历bodies_list时,应该使用当前body对应的关键点数据,而非固定的keypoints_3d。
  • 优化骨骼连线逻辑:按标准人体关键点的骨骼连接关系绘制(而非原始代码中前5个点依次连接的错误逻辑)。

修正后的完整代码

import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
import time

# 定义标准人体骨骼连接(可根据你的关键点顺序调整)
SKELETON_CONNECTIONS = [
    (0, 1), (1, 2), (2, 3), (3, 4),  # 右臂
    (0, 5), (5, 6), (6, 7), (7, 8),  # 左臂
    (0, 9), (9, 10), (10, 11), (11, 12), # 右腿
    (0, 13), (13, 14), (14, 15), (15, 16), # 左腿
    (0, 17), (17, 18), (18, 19), (19, 20), # 头部
]

def init_gl():
    # 初始化GL状态,仅执行一次
    glEnable(GL_POINT_SMOOTH)
    glEnable(GL_BLEND)
    glEnable(GL_FRAMEBUFFER_SRGB)
    glEnable(GL_DEPTH_TEST)  # 启用深度测试,解决3D遮挡问题
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glPointSize(10)
    glClearColor(0.1, 0.1, 0.1, 1.0)  # 设置深色背景
    # 设置透视投影
    gluPerspective(45, (800/600), 0.1, 50.0)
    glTranslatef(0.0, 0.0, -5)  # 将场景拉远,避免画面拥挤

def draw_points(keypoints_3d):
    glBegin(GL_POINTS)
    glColor3d(1, 1, 1)
    for pt in keypoints_3d:
        glVertex3d(pt[0]/100, pt[1]/100, pt[2]/100)
    glEnd()

def draw_skeleton(keypoints_3d):
    glBegin(GL_LINES)
    glColor3d(1, 1, 1)
    for start_idx, end_idx in SKELETON_CONNECTIONS:
        # 检查索引有效性,避免数组越界
        if start_idx < len(keypoints_3d) and end_idx < len(keypoints_3d):
            start_pt = keypoints_3d[start_idx]
            end_pt = keypoints_3d[end_idx]
            glVertex3d(start_pt[0]/100, start_pt[1]/100, start_pt[2]/100)
            glVertex3d(end_pt[0]/100, end_pt[1]/100, end_pt[2]/100)
    glEnd()

def main():
    pygame.init()
    display = (800, 600)
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
    init_gl()

    while True:
        time_temp = time.time()
        
        # 事件处理
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                return
        
        # 清除颜色与深度缓冲区
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        
        # 绘制所有人体:一次性完成所有绘制后再刷新屏幕
        for body in bodies_list:
            # 替换为你实际的关键点获取方式,比如body.keypoints_3d
            current_keypoints = body.keypoints_3d
            draw_points(current_keypoints)
            draw_skeleton(current_keypoints)
        
        # 仅在所有绘制完成后刷新一次屏幕
        pygame.display.flip()
        pygame.time.wait(10)

if __name__ == "__main__":
    # 替换为你的人体数据列表
    bodies_list = []
    main()

额外优化建议

  • 若需要区分不同人体,可在绘制单个人体前调用glColor3d()设置不同RGB颜色值。
  • 对于大量人体的场景,建议使用顶点数组(glVertexPointer)或VAO/VBO替代glBegin/glEnd的即时模式,能大幅提升绘制性能。
  • 确保关键点坐标范围合理,避免因数值过大导致画面显示异常。

内容的提问来源于stack exchange,提问作者GOPI KRISHNA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 14:37:13