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?