1

trying to convert local webcam stream from cv::Mat to QImage but the output is weird. I've tried a bunch of things and searched for hours; I'm officially stuck.

here is the code snippet in question

void AppName::SlotFrameReady(cv::Mat image, qint64 captureTime, qint64 processTime)
{
  //  cv::Mat imageholder;
  //  cv::cvtColor(image, imageholder, CV_BGRA2RGBA);

 //   QImage img((const unsigned char*)(image.data), image.cols, image.rows, QImage::Format_Grayscale8);
 //    QImage img((const unsigned char*)(imageholder.data), imageholder.cols, imageholder.rows, QImage::Format_RGB32);
     QImage img((const unsigned char*)(image.data), image.cols, image.rows, image.step, QImage::Format_RGB888);

    m_VideoView->Update(&img);

}

This is what I've tried - adding image.step, tried every QImage format, tried img.invertPixels() and img.invertRGB/invertRGBA()

I've also tried creating a temporary image to run cvtColor and convert (tried CV_BGRA2RGB and BGRA2RGBA) and this gives the same result.

type() output is 24 which, if I am correct, is CV_8UC4.

If I use any sort of above I get the following (although some formats will show incorrect color instead of just grayscale. This is with RGB8888): https://i.stack.imgur.com/s7OeL.png

if I output in grayscale everything works as it should: removed link bc rep isn't enough

On mac 10.11 with QT creator 5 and opencv 3.1 if that makes a difference, thanks!

edit to clarify:

I have tried Ypnos' solution here but that makes the output a blank gray screen. The only other options I've found are variations of what I've explored above.

The one thing I haven't tried is writing the mat to a file and reading it into a qimage. My thinking is that this is very inelegant and will be too slow for my needs.

another thing to note that I stupidly forgot to include - the video view update function transforms the qimage into a qpixmap for display. could this be where the error is?

edit again: got Ypnos' solution working, was a stupid error on my part (using the mat3b/vec3b when it is a 4 channel image). However, output is still a mess.

here is updated code:

void AppName::SlotFrameReady(const cv::Mat4b &image, qint64 captureTime, qint64 processTime)
{

    QImage dest(image.cols, image.rows, QImage::Format_RGBA8888);
    for (int y = 0; y < image.rows; ++y) {
            const cv::Vec4b *srcrow = image[y];
            QRgb *destrow = (QRgb*)dest.scanLine(y);
            for (int x = 0; x < image.cols; ++x) {
                    destrow[x] = qRgba(srcrow[x][2], srcrow[x][1], srcrow[x][0], 255);
            }
         }

    m_VideoView->Update(&dest);

and the relevant section of VideoView where it is converted to PixMap and pushed to display

    QPixmap bitmap = QPixmap::fromImage(*image).transformed(transform, Qt::SmoothTransformation);
    setPixmap(bitmap); 

AND the new but still messed up output

https://i.stack.imgur.com/TNPra.png

using the FaceTime camera built into my macbook pro as well as with 2 other USB cams I've tried (logitech c270 and a no-name chinese garbage cam)

any ideas?

Community
  • 1
  • 1
  • 2
    Does [cv::Mat to QImage conversion](http://stackoverflow.com/questions/11015481/cvmat-to-qimage-conversion) help? Or maybe [this question](http://stackoverflow.com/q/5026965/2065121) too? – Roger Rowland Feb 15 '16 at 08:01
  • thanks for the reply. unfortunately not. I've tried Ypnos' solution in the second link and the output there is simply a blank gray screen. the other answers as, as far as I can tell, simply variations on what I have tried above. – quixotic120 Feb 17 '16 at 05:45
  • Have a look [here](https://asmaloney.com/2013/11/code/converting-between-cvmat-and-qimage-or-qpixmap/). This should handle all kind of conversion. – Miki Feb 17 '16 at 14:15
  • ultimately that appears to be the same solution that I've got above: QImage image( inMat.data, inMat.cols, inMat.rows, inMat.step, QImage::Format_RGB32 ); for the 8UC4 case is essentially the same as what I was trying initially. Just to be sure I went back and took out the (const unsigned char *) in mine as that was the only difference that I could see but the output was still flawed in the same way. Thanks for the suggestion anyway! – quixotic120 Feb 17 '16 at 17:54

0 Answers0