将IplImage IPL_DEPTH_32S转换为QImage Format_RGB32的最快方法是什么?
我需要从凸轮上抓取图片并在频率为30帧/秒的表格上显示。我试着使用QImage构造函数:
QImage qImage((uchar *) image->imageData, image->width, image->height, QImage::Format_RGB32);
但此后图像已损坏。那么,我怎么能快速做到这一点(我认为逐像素放入QImage并不是一个好的决定)?
答案 0 :(得分:3)
在开始之前,OpenCV默认使用 BGR格式。不是RGB!因此,在创建QImage
之前,您需要将IplImage
转换为RGB:
cvtColor(image, image, CV_BGR2RGB);
然后你可以:
QImage qImage((uchar*) image->imageData, image->width, image->height, QImage::Format_RGB32);
请注意the constructor above不会像您想象的那样复制数据,正如文档所述:
缓冲区必须在QImage的整个生命周期内保持有效
因此,如果您有性能问题不是因为转换过程。这很可能是由您使用的绘图方法引起的(在问题中没有共享)。总结一下等等等等等等,你应该render the QImage
to an OpenGL texture让视频卡为你做所有的绘图。
你的问题有点误导,因为你的主要目标不是找到最快的转换方法,而是实际上有效的方法,因为你的方法没有。
当你说:
时,要记住另一件重要的事情图像在此之后被破坏
你必须知道这是完全模糊的,它根本没有帮助我们,因为造成这种影响有很多原因,如果没有源代码就无法确定你做错了什么。共享原始图像和损坏的图像可能会提供问题所在的一些线索。
现在就是这样。祝你好运。
答案 1 :(得分:0)
IPL_DEPTH_32S
是具有32位像素的灰度 - 通常用于深度数据而不是实际的“图像”,如果您打包彩色图像以检查像素排序是什么。
QImage::Format_ARGB32_Premultiplied
是最快的QImage格式,因为它是显卡使用的 - 请注意数据顺序实际上是BGRA,A通道必须至少与像素一样大,如果你不是想要使用alpha。
cv :: cvtColor()中有RGB2BGRA和BGR2RGBA
答案 2 :(得分:0)
前段时间我在互联网上找到了一些如何做到这一点的例子。我对如何以更简单的方式复制图像进行了一些改进。 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();
}
}
希望我的功能有所帮助。也许有人知道更好的方法:)