带有 OpenGL 和 Kinect v2 的 QT5:错误的图像呈现

Posted

技术标签:

【中文标题】带有 OpenGL 和 Kinect v2 的 QT5:错误的图像呈现【英文标题】:QT5 with OpenGL and Kinect v2: wrong image presentation 【发布时间】:2017-02-02 11:33:06 【问题描述】:

我想在 Qt 小部件中通过 openGl 显示来自 kinect v2 传感器的彩色图像。问题是,这张图片的呈现方式不正确。

这是我获取颜色框架的代码:

类:

cv::Mat                     ColorMap;
std::vector<BYTE>           colorBuffer;
int                         color_width;
int                         color_height;

代码:

if(colorBuffer.empty())
   colorBuffer.resize(color_height * color_width * 4 * sizeof(unsigned char));

hr = ColorFrame->CopyConvertedFrameDataToArray((UINT)colorBuffer.size(),
                             &colorBuffer[0], ColorImageFormat::ColorImageFormat_Bgra );

ColorMap = cv::Mat( color_height, color_width, CV_8UC4, &colorBuffer[0]);

这意味着,我将颜色信息作为带有 alpha 通道的 BGR 格式并将其复制到具有 4 个通道 (BRGA) 的矩阵中,并且每个通道具有从 0 到 255 的 8Bit。对吗?

在下一步中,我将其调整为与小部件相同的大小:

    Kinect->CreateFrame();
    cv::Mat GUIColorImage;
    Kinect->ColorMap.copyTo(GUIColorImage);
    cv::resize(GUIColorImage,GUIColorImage,
    cv::Size(ui->Left_Widget_Color->width(),ui->Left_Widget_Color->height()));

比我尝试了两种转换方法: 1.转换为BGR 2.转换成8UC3(8位,无符号字符,3通道(和BGR一样?))

1:GUIColorImage.convertTo(GUIColorImage,CV_BGRA2BGR);

2:GUIColorImage.convertTo(GUIColorImage,CV_8UC3);

但没有任何解决方案有效。

转换后,我尝试在 openGl 上显示它:

LeftWidgetColor.UpdateImage(GUIColorImage);

LeftWidgetColor 是一个 QOpenGLWidget:

标题:

class RenderWidget : public QOpenGLWidget

    Q_OBJECT
public:
    RenderWidget(QWidget *parent);
    ~RenderWidget();
    void UpdateImage(cv::Mat newimage);
    void initializeGL();
    void paintGL();

private:
    int                 width;
    int                 height;
    GLuint              texture;
    cv::Mat             image;

signals:
    void info(QString msg);
    void error(QString msg);
    void DepthValueAt(cv::Point2i DepthPosition);

protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
;

代码:

RenderWidget::RenderWidget(QWidget *parent) : QOpenGLWidget(parent)

    width = this->size().width();
    height = this->size().height();
    texture = 0;
    initializeGL();


RenderWidget::~RenderWidget()

    glDeleteTextures(1, &texture);



void RenderWidget::initializeGL()

    //Background Color is black
    glClearColor(0,0,0,1);

    //Storage of Pixelmode for two-dimensional textures
    glPixelStorei (GL_UNPACK_ALIGNMENT, 1);

    //Create texture
    glGenTextures(1, &texture);

    glViewport(0, 0, width, height);




void RenderWidget::paintGL()

    // Clear the screen and depth buffer (with black)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Select the model view matrix and reset it
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glTranslatef(0.0f, 0.0f, 0.0f);

    // Abort drawing if OpenCV was unable to open the camera
    if (image.empty())
    
        return;
    
    glEnable(GL_TEXTURE_RECTANGLE_ARB);

    // Typical texture generation using data from the bitmap
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);

    // Transfer image data to the GPU
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
                 3, image.cols, image.rows, 0,
                 GL_BGR, GL_UNSIGNED_BYTE, image.data);


    if (glGetError() != GL_NO_ERROR)
    
    

    // Draw a 2D face with texture
    glBegin(GL_QUADS);
        glTexCoord2f(0, 0);                   glVertex2f(1, 1);
        glTexCoord2f(image.cols, 0);          glVertex2f(-1, 1);
        glTexCoord2f(image.cols, image.rows); glVertex2f(-1, -1);
        glTexCoord2f(0, image.rows);          glVertex2f(1, -1);
    glEnd();

glDisable(GL_TEXTURE_RECTANGLE_ARB);


void RenderWidget::UpdateImage(cv::Mat newimage)

    newimage.copyTo(image);
    update();

我猜问题出在:

glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
             3, image.cols, image.rows, 0,
             GL_BGR, GL_UNSIGNED_BYTE, image.data);

但我找不到。我已将 3 通道、BGR、8 位 = 1 字节声明为无符号。有人知道错误在哪里吗?

如果我通过 imshow(openCv 类)显示它,它工作正常。

【问题讨论】:

***.com/questions/5026965/… 嗨塞巴斯蒂安,谢谢你的回答。我在您的链接中找到了解决方案,原因如下:***.com/questions/22174002/… 【参考方案1】:

我的错误是,我使用了cv::Mat::convertTo(): 但here 他们写道,convertTo() 不应用于转换格式(仅用于更改数据类型)。 cv::cvtColor 是正确的功能,对我来说效果很好。所以我改变了转换:

GUIColorImage.convertTo(GUIColorImage,CV_BGRA2BGR);

cv::cvtColor(GUIColorImage,GUIColorImage,CV_BGRA2BGR);

【讨论】:

以上是关于带有 OpenGL 和 Kinect v2 的 QT5:错误的图像呈现的主要内容,如果未能解决你的问题,请参考以下文章

Kinect For Windows V2开发日志二:Kinect V2的基本参数

Kinect v2(Microsoft Kinect for Windows v2 )配置移动电源解决方案

Processing教程:如何使用Kinect V2做交互设计 - 获取Kinect全部图像信息

Kinect for Xbox one(v2) + Ubuntu 14.04 +ROS

Kinect V2 基础教程之彩色图像

c_cpp 使用PCLVisualizer和Kinect v2 Grabber绘制点云