from PyQt5.QtWidgets import QApplication, QOpenGLWidget # 导入 QApplication 和 QOpenGLWidget 类 from OpenGL.GL import * # 导入 OpenGL 库中的所有函数和常量 from OpenGL.GLU import * # 导入 OpenGL 工具库中的所有函数和常量 import cv2 # 导入 OpenCV 库 import numpy as np # 导入 NumPy 库 class MyGLWidget(QOpenGLWidget): # 定义一个继承自 QOpenGLWidget 的类 def __init__(self): # 构造函数 super().__init__() # 调用父类构造函数 self.setWindowTitle("QOpenGLWidget Example") # 设置窗口标题 self.resize(800, 600) # 设置窗口大小 self.texture = None # 初始化纹理变量 self.capture = cv2.VideoCapture(0) # 打开默认摄像头 def initializeGL(self): # 初始化 OpenGL 环境 glClearColor(0.0, 0.0, 0.0, 1.0) # 设置清除颜色为黑色 self.texture = glGenTextures(1) # 生成一个纹理 ID def resizeGL(self, w, h): # 处理窗口大小变化 glViewport(0, 0, w, h) # 设置视口大小 glMatrixMode(GL_PROJECTION) # 设置当前矩阵模式为投影矩阵 glLoadIdentity() # 重置投影矩阵 gluPerspective(45, w / h, 1, 100) # 设置透视投影矩阵 glMatrixMode(GL_MODELVIEW) # 设置当前矩阵模式为模型视图矩阵 glLoadIdentity() # 重置模型视图矩阵 def paintGL(self): # 绘制 OpenGL 场景 ret, frame = self.capture.read() # 读取摄像头帧 if ret: frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 转换图像颜色通道顺序从 BGR 到 RGB frame = np.flipud(frame) # 上下翻转图像,因为 OpenGL 的纹理坐标系与图像坐标系不同 image_data = frame.tobytes() # 将图像数据转换为字节格式 height, width, channels = frame.shape # 获取图像的高、宽和通道数 glBindTexture(GL_TEXTURE_2D, self.texture) # 绑定纹理 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) # 设置纹理 S 方向的环绕方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) # 设置纹理 T 方向的环绕方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) # 设置纹理缩小过滤方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) # 设置纹理放大过滤方式 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_data) # 指定纹理图像 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # 清除颜色缓冲区和深度缓冲区 glLoadIdentity() # 重置当前模型视图矩阵 glTranslatef(0.0, 0.0, -5.0) # 平移场景以便看到绘制的对象 glEnable(GL_TEXTURE_2D) # 启用二维纹理 glBegin(GL_QUADS) # 开始绘制四边形 glTexCoord2f(0.0, 0.0) # 指定纹理坐标 (0, 0) glVertex3f(-1.0, -1.0, 0.0) # 指定第一个顶点 glTexCoord2f(1.0, 0.0) # 指定纹理坐标 (1, 0) glVertex3f(1.0, -1.0, 0.0) # 指定第二个顶点 glTexCoord2f(1.0, 1.0) # 指定纹理坐标 (1, 1) glVertex3f(1.0, 1.0, 0.0) # 指定第三个顶点 glTexCoord2f(0.0, 1.0) # 指定纹理坐标 (0, 1) glVertex3f(-1.0, 1.0, 0.0) # 指定第四个顶点 glEnd() # 结束绘制 glDisable(GL_TEXTURE_2D) # 禁用二维纹理 self.update() # 触发窗口重绘 if __name__ == '__main__': app = QApplication([]) # 创建应用程序对象 widget = MyGLWidget() # 创建 MyGLWidget 实例 widget.show() # 显示窗口 app.exec_() # 进入应用程序主循环