3、将opengl的窗口渲染结果利用OpenCV保存成图片

opengl中有一个非常有用的函数:glReadPixels(),可以读取各种缓冲区(深度、颜色,etc)的数值。要将opengl的绘制场景保存成图片,也需要使用这个函数。

直接附上代码 

//save image
        GLubyte* pPixelData;
        pPixelData = (GLubyte*)malloc(picWidth * picHeight * 4);//分配内存
        if (pPixelData == 0)
            return 0;
        glReadBuffer(GL_FRONT);//保存窗口渲染的结果
        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);//解压窗口数据结构
        glReadPixels(0, 0, picWidth, picHeight, GL_RGBA, GL_UNSIGNED_BYTE, pPixelData);//存储像素数据

        cv::Mat img;
        std::vector<cv::Mat> imgPlanes;
        img.create(picHeight, picWidth, CV_8UC3);//确定图片通道和尺寸
        cv::split(img, imgPlanes);//将图像按照通道数拆分,三个单通道序列

        for(int i = 0; i < picHeight; i ++) {
            unsigned char* plane0Ptr = imgPlanes[0].ptr<unsigned char>(i);//B
            unsigned char* plane1Ptr = imgPlanes[1].ptr<unsigned char>(i);//G
            unsigned char* plane2Ptr = imgPlanes[2].ptr<unsigned char>(i);//R
            //opencv里面以BGR存储的,而Mac上opengl是RGBA,所以需要改变顺序保存
            for(int j = 0; j < picWidth; j ++) {
                int k = 4 * (i * picWidth + j);//RGBA数据结构,不需要A,跳过,所以步长乘以4
                plane2Ptr[j] = pPixelData[k];//R
                plane1Ptr[j] = pPixelData[k+1];//G
                plane0Ptr[j] = pPixelData[k+2];//B
            }
        }
        cv::merge(imgPlanes, img);//合并多通道图像
        cv::flip(img, img ,0); // 反转图像,因为opengl和opencv的坐标系y轴是相反的
        cv::cvtColor(img, img, cv::COLOR_RGB2GRAY);//转换为灰度图
        cv::namedWindow("openglGrab");
        cv::imshow("openglGrab", img);
        cv::waitKey();
        cv::imwrite("/Users/xxx/Documents/result/10.17/结果/"+num+".jpg", img);//保存图片

测试结果: 图片opencv                                         opengl渲染

                           

 

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,这是一个比较复杂的问题,需要涉及到Python的OpenGL编程和OpenCV图像处理库。以下是一个大致的程序框架: ```python import cv2 from OpenGL.GL import * from OpenGL.GLUT import * from OpenGL.GLU import * # 定义正方体的顶点坐标 vertices = ( (1, -1, -1), (1, 1, -1), (-1, 1, -1), (-1, -1, -1), (1, -1, 1), (1, 1, 1), (-1, -1, 1), (-1, 1, 1) ) # 定义正方体的边界 edges = ( (0, 1), (0, 3), (0, 4), (2, 1), (2, 3), (2, 7), (6, 3), (6, 4), (6, 7), (5, 1), (5, 4), (5, 7) ) # 定义摄像头对象 cap = cv2.VideoCapture(0) # 定义OpenGL窗口函数 def draw(): glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) glLoadIdentity() # 将摄像头图像作为背景 ret, frame = cap.read() if ret: cv2.imshow('frame', frame) cv2.waitKey(1) glEnable(GL_TEXTURE_2D) texid = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, texid) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, frame.shape[1], frame.shape[0], 0, GL_BGR, GL_UNSIGNED_BYTE, frame) glBegin(GL_QUADS) # 绘制正方体 for edge in edges: for vertex in edge: glTexCoord2f(0.0, 0.0) glVertex3fv(vertices[vertex]) glEnd() glDisable(GL_TEXTURE_2D) glutSwapBuffers() # 主函数 def main(): glutInit() glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH) glutInitWindowSize(800, 600) glutCreateWindow("OpenGL Window") glEnable(GL_DEPTH_TEST) glutDisplayFunc(draw) glutIdleFunc(draw) glutMainLoop() if __name__ == "__main__": main() ``` 这个程序会打开电脑自带的摄像头,将摄像头的图像作为OpenGL窗口的背景,并在窗口中绘制一个正方体。程序中使用了OpenGL的纹理功能,将摄像头图像作为纹理贴在正方体的表面上。注意,程序中的图像处理部分使用了OpenCV库,需要先安装该库才能正常运行。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值