67 lines
3.7 KiB
Python
67 lines
3.7 KiB
Python
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_() # 进入应用程序主循环
|