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-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
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.
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!
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.