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
相关产品推荐
相关产品推荐

