[英]QT5 with OpenGL and Kinect v2: wrong image presentation
I would like to show a color image from the kinect v2 sensor over openGl in a Qt widget.我想在 Qt 小部件中通过 openGl 显示来自 kinect v2 传感器的彩色图像。 The problem is, that the presentation of this image is incorrect.
问题是,此图像的呈现方式不正确。
Here is the code where I get the color frame:这是我获取颜色框架的代码:
class:班级:
cv::Mat ColorMap;
std::vector<BYTE> colorBuffer;
int color_width;
int color_height;
code:代码:
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]);
That means, I get the color information as BGR Format with an alpha channel and copy it to a matrix with 4 channels, (BRGA) and each channel has 8Bit from 0 to 255. Correct?这意味着,我以带有 alpha 通道的 BGR 格式获取颜色信息,并将其复制到具有 4 个通道的矩阵 (BRGA) 中,并且每个通道具有从 0 到 255 的 8Bit。正确吗?
In the next step, I resize it as the same size as the widget:在下一步中,我将其调整为与小部件相同的大小:
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()));
Than I've tried two convert methods: 1. convert to BGR 2. convert to 8UC3 (8-Bit, unsigned char, 3 channels (the same as BGR?))比我尝试过两种转换方法:1. 转换为 BGR 2. 转换为 8UC3(8 位,无符号字符,3 个通道(与 BGR 相同?))
1: GUIColorImage.convertTo(GUIColorImage,CV_BGRA2BGR);
1:
GUIColorImage.convertTo(GUIColorImage,CV_BGRA2BGR);
2: GUIColorImage.convertTo(GUIColorImage,CV_8UC3);
2:
GUIColorImage.convertTo(GUIColorImage,CV_8UC3);
But no solutions works.但没有任何解决方案有效。
After the conversion, I try to display it over openGl with:转换后,我尝试通过 openGl 显示它:
LeftWidgetColor.UpdateImage(GUIColorImage);
LeftWidgetColor is a QOpenGLWidget: LeftWidgetColor 是一个 QOpenGLWidget:
header:标题:
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);
};
code:代码:
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();
}
I guess the problem is in:我想问题出在:
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,
3, image.cols, image.rows, 0,
GL_BGR, GL_UNSIGNED_BYTE, image.data);
But I can't find it.但我找不到。 I've declared 3-channels, BGR, 8-Bit = 1 Byte as unsigned.
我已将 3-channels, BGR, 8-Bit = 1 Byte 声明为无符号。 Does someone know where the mistake is?
有人知道错误在哪里吗?
If i show it over imshow (openCv class), it works fine.如果我通过 imshow(openCv 类)显示它,它工作正常。
My Mistake was, that I used cv::Mat::convertTo():
but here they wrote, that convertTo() should not used to convert the format (Only to change the data type).我的错误是,我使用了
cv::Mat::convertTo():
但在这里他们写道,convertTo() 不应该用于转换格式(仅用于更改数据类型)。 cv::cvtColor is the right function and it works well for me. cv::cvtColor 是正确的函数,对我来说效果很好。 So I've changed the conversion from:
所以我改变了转换:
GUIColorImage.convertTo(GUIColorImage,CV_BGRA2BGR);
to到
cv::cvtColor(GUIColorImage,GUIColorImage,CV_BGRA2BGR);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.