Ask Your Question

Revision history [back]

8UC4 Mat to qimage

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. This may be outside the scope of this forum, if so I am sorry but I have not been able to find a solution elsewhere.

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

}

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 RGBA8888): http://i.imgur.com/79k3q8U.png

if I output in grayscale everything works as it should: http://i.imgur.com/8b4APE0.png

I have tried a solution from Ypnos on stackexhange but that output is still a mess.

here is that 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

http://i.imgur.com/1jlmfRQ.png

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) all give the same output

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.

any ideas? On mac 10.11 with QT creator 5 and opencv 3.1.0. current compile flags are:

--with-contrib --with-opengl --with-qt5 --without-opencl

However I also had compiled it with flags

--with-tbb --with-contrib --with-cuda --with-opengl --with-qt5 --with-ffmpeg --with-python3 --without-opencl

but that gave the same output. I tried removing and recompiling OpenCV at one point which is why I have the new flags

8UC4 Mat to qimage

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. This may be outside the scope of this forum, if so I am sorry but I have not been able to find a solution elsewhere.

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

}

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 RGBA8888): http://i.imgur.com/79k3q8U.png

if I output in grayscale everything works as it should: http://i.imgur.com/8b4APE0.png

I have tried a solution from Ypnos on stackexhange but that output is still a mess.

here is that 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

http://i.imgur.com/1jlmfRQ.png

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) all give the same output

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.

any ideas? On mac 10.11 with QT creator 5 and opencv 3.1.0. current compile flags are:

--with-contrib --with-opengl --with-qt5 --without-opencl

However I also had compiled it with flags

--with-tbb --with-contrib --with-cuda --with-opengl --with-qt5 --with-ffmpeg --with-python3 --without-opencl

However I also had compiled it with flags

--with-contrib --with-opengl --with-qt5 --without-opencl

but that gave the same output. I tried removing and recompiling OpenCV at one point which is why I have the new flagsflags. I