Ask Your Question
0

8UC4 Mat to qimage

asked 2016-02-17 12:15:10 -0600

quixotic120 gravatar image

updated 2016-02-17 13:26:12 -0600

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-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 flags. I

edit retag flag offensive close merge delete

Comments

1

Well, I'm afraid I don't know much about QT, but I have some suggestions.

First, check to see if the Mat is continuous (the isContinuous function). If it's not, for example if you pass in a sub-matrix, then you need to make a local copy that is.

Second, is step the correct value? I think you should be passing image.step1(). Step is basically an array of int[dims].

Give those a try and see if that helps.

Tetragramm gravatar imageTetragramm ( 2016-02-17 19:36:19 -0600 )edit

The isContinuous function returns true. step1() changes the image slightly but it still very distorted like the attached screenshots. So unfortunately I'm still stuck but thanks for the suggestions!

quixotic120 gravatar imagequixotic120 ( 2016-02-18 12:59:49 -0600 )edit

tried reverting from opencv3 to opencv2 installed via homebrew (OS X pkg manager), output was the same. Also tried answer posted and it did not work, see comment below. still works if I make the Qimage Format_Grayscale8. I have no idea what else to try but figured I'd post an update! continues with all cameras tried which makes me believe it is a programmatic error.

quixotic120 gravatar imagequixotic120 ( 2016-02-27 17:18:23 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
-1

answered 2016-02-23 22:46:43 -0600

sai kethamakka gravatar image

updated 2016-02-23 22:58:04 -0600

cv::Mat tmp(qImage.height(), qImage.width(), CV_8UC4, (void*) qImage.bits(), qImage.bytesPerLine());
cv::cvtColor(tmp, cvImage, CV_RGBA2RGB);

This code worked for me to convert QImage to 8UC4 cv::Mat, hope it helps. And reversing from Mat to QImage,

QImage tmp((unsigned char*) cvImage.data, cvImage.size().width, cvImage.size().height, cvImage.step, QImage::Format_RGB888);
qImage = tmp.rgbSwapped().convertToFormat(QImage::Format_ARGB32_Premultiplied);

Edited: Conversion from 8UC4 to QImage

edit flag offensive delete link more

Comments

This is the opposite of what he wants to do, but if this works, then it means they store data the same way. So why didn't his first code snippet work?

Tetragramm gravatar imageTetragramm ( 2016-02-23 22:54:14 -0600 )edit

Just to make sure, is that using the post cvtColor RGB image? That would only be 8UC3. Just want to make sure you're giving him the right formats.

Tetragramm gravatar imageTetragramm ( 2016-02-24 07:01:53 -0600 )edit

this results in essentially the same output. I made the following changes:

    QImage tmp((unsigned char*) image.data, image.size().width, image.size().height, image.step, QImage::Format_RGBA8888);
    QImage img = tmp.rgbSwapped().convertToFormat(QImage::Format_ARGB32_Premultiplied);

mainly changed variable names to work with my code and changed rgb8888 to rgba8888 as the image is 8UC4 and rgb8888 crashes at runtime

quixotic120 gravatar imagequixotic120 ( 2016-02-27 17:08:12 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-02-17 12:14:32 -0600

Seen: 2,468 times

Last updated: Feb 23 '16