繁体   English   中英

将IplImage IPL_DEPTH_32S转换为QImage Format_RGB32的最快方法

[英]Fastest method to convert IplImage IPL_DEPTH_32S to QImage Format_RGB32

将IplImage IPL_DEPTH_32S转换为QImage Format_RGB32的最快方法是什么?

我需要从cam捕获图片并以每秒30帧的频率在窗体上显示它。 我尝试使用QImage构造函数:

QImage qImage((uchar *) image->imageData, image->width, image->height, QImage::Format_RGB32);

但是此后图像已损坏。 因此,我该如何快速执行此操作(我认为将一个像素接一个QImage并不是一个好的决定)?

在开始之前,OpenCV 默认使用BGR格式 不是RGB! 因此,在创建QImage之前,您需要使用以下命令将IplImage转换为RGB:

cvtColor(image, image, CV_BGR2RGB);

那么你也能:

QImage qImage((uchar*) image->imageData, image->width, image->height, QImage::Format_RGB32);

请注意,如文档所述上述构造函数不会像您想的那样复制数据:

缓冲区必须在QImage的整个生命周期内保持有效

因此,如果您遇到性能问题,则不是由于转换过程引起的 这很可能是由您使用的绘制方法引起的(问题中未共享)。 总结等等,您应该QImage渲染为OpenGL纹理,然后让视频卡为您完成所有绘制。

您的问题有点误导,因为您的主要目的不是找到最快的转换方法,而是找到了可行的方法,因为您没有找到。

当您说时,请记住另一件重要的事情:

此后图像已损坏

您必须知道这是完全模糊的,并且对我们完全没有帮助,因为造成这种影响的原因有很多,而且没有源代码就无法确定您在做什么错。 共享原始图像和损坏的图像可能会为问题出在哪里提供一些线索。

现在就这样。 祝好运。

IPL_DEPTH_32S是具有32位像素的灰度级-通常用于深度数据,而不是实际的“图像”,如果您对彩色图像进行打包检查像素顺序是什么。

QImage::Format_ARGB32_Premultiplied是最快的QImage格式,因为它使用的是图形卡-请注意,数据顺序实际上是BGRA,并且A通道必须至少与像素一样大,即如果不想使用alpha,则为255。 。

cv :: cvtColor()中有一个RGB2BGRA和BGR2RGBA

前段时间,我在互联网上找到了一些有关如何执行此操作的示例。 我对示例进行了一些改进,以便于以更简单的方式复制图像。 Qt通常仅适用于char像素(其他图像格式通常称为HDR图像)。 我想知道如何在opencv中获得32位rgb的视频缓冲区...我从未见过!

如果您在opencv中有彩色图像,则可以使用此函数分配内存:

QImage* allocateqtimagefromcv(IplImage* cvimg)
    {
        //if (cvimg->nChannels==1)
        //  {
        //  return new QImage(cvimg->width,cvimg->height,QImage::Format_Indexed8);
        //  }
        if (cvimg)
            {
            return new QImage(cvimg->width,cvimg->height,QImage::Format_ARGB32);
            }
    }

只需将IplImage复制到qt图像,就可以轻松实现并使用以下功能:

void  IplImage2QImage(IplImage *iplImg,QImage* qimg)
{

char *data = iplImg->imageData;
    int channels = iplImg->nChannels;
int h = iplImg->height;
int w = iplImg->width;
for (int y = 0; y < h; y++, data += iplImg->widthStep)
{
for (int x = 0; x < w; x++)
{
char r, g, b, a = 0;
if (channels == 1)
{
r = data[x * channels];
g = data[x * channels];
b = data[x * channels];
}
else if (channels == 3)
{
r = data[x * channels + 2];
g = data[x * channels + 1];
b = data[x * channels];
}

if (channels == 4)
{
a = data[x * channels + 3];
qimg->setPixel(x, y, qRgba(r, g, b, a));
}

}
}


}

以下功能可能是更快的解决方案:

static QImage IplImage2QImage(const IplImage *iplImage)
{
  int height = iplImage->height;
  int width = iplImage->width;
  if (iplImage->depth == IPL_DEPTH_8U && iplImage->nChannels == 3)
  {
      const uchar *qImageBuffer =(const uchar*)iplImage->imageData;
      QImage img(qImageBuffer, width, height, QImage::Format_RGB888);
      return img.rgbSwapped();
  }else{
    //qWarning() << "Image cannot be converted.";
   return QImage();
  }
} 

希望我的功能有所帮助。 也许有人知道更好的方法:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM