Fastest method to convert IplImage IPL_DEPTH_32S to QImage Format_RGB32

六眼飞鱼酱① 提交于 2019-12-20 06:49:14

问题


What is the fastest method to convert IplImage IPL_DEPTH_32S to QImage Format_RGB32?

I need to catch pictures from cam and show it on form with frequency 30 frames in second. I tried to use QImage constructor:

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

but image was corrupted after this. So, how can I do this fast (I think putting pixel by pixel into QImage is not a good decision)?


回答1:


Before I start, OpenCV uses the BGR format by default. Not RGB! So before creating the QImage you need to convert your IplImage to RGB with:

cvtColor(image, image, CV_BGR2RGB);

Then you can:

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

Note that the constructor above doesn't copy the data as you might be thinking, as the docs states:

The buffer must remain valid throughout the life of the QImage

So if you are having performance issues are not because of the conversion procedure. It is most probably caused by the drawing method you are using (which wasn't shared in the question). To summarize a lot of blah blah blah, you should render the QImage to an OpenGL texture and let the video card do all the drawing for you.

Your question is a bit misleading because your primary objective is not to find the fastest conversion method, but one that actually works since yours don't.

Another important thing to keep in mind, when you said:

image was corrupted after this

you must know that this is completely vague, and it doesn't help us at all because there is a number of causes for this effect, and without the source code is impossible to tell with certainty what are you doing wrong. Sharing the original and the corrupted image might gives some clues to where the problem is.

That's it for now. Good luck.




回答2:


IPL_DEPTH_32S is greyscale with a 32bit pixel - normally used for depth data rather than an actual 'image', if you are packign a colour image into check what the pixel ordering is.

QImage::Format_ARGB32_Premultiplied is the fastest QImage format because its what the graphics card uses - note that the data order is actually BGRA and the A channel must be at least as large as the pixel, ie 255 if you don't want to use alpha.

There is a RGB2BGRA and BGR2RGBA in cv::cvtColor()




回答3:


Time ago I found some examples in the internet of how to do that. I improved the examples a bit for how to copy the images in a more easy way. Qt works normally only with char pixels (other image formats are normally called HDR images). I was wondering how you get a video buffer of 32 bit rgb in opencv... I have never seen that !

If you have a color image in opencv you could use this function to allocate memory:

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);
            }
    }

to just copy the IplImage to the qt image you could go the easy way and use this function:

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));
}

}
}


}

the following function could be a quicker solution:

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();
  }
} 

hope my function helped. Maybe someone know better ways of doing that :)



来源:https://stackoverflow.com/questions/11371540/fastest-method-to-convert-iplimage-ipl-depth-32s-to-qimage-format-rgb32

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!