0

I'm using the code suggested in ( how to convert an opencv cv::Mat to qimage ) to display a cv::Mat in my Qt application. However, I'm getting strange results. The black parts are displayed as black, but all other values are inverted.

Conversion code:

QImage ImgConvert::matToQImage(Mat_<double> src)
{
    double scale = 255.0;

    QImage dest(src.cols, src.rows, QImage::Format_ARGB32);
    for (int y = 0; y < src.rows; ++y) {
            const double *srcrow = src[y];
            QRgb *destrow = (QRgb*)dest.scanLine(y);
            for (int x = 0; x < src.cols; ++x) {
                    unsigned int color = srcrow[x] * scale;
                    destrow[x] = qRgba(color, color, color, 255);
            }
    }
    return dest;
}

Display code:

void MainWindow::redraw()
{
    static QImage image = ImgConvert::matToQImage(im);

    static QGraphicsPixmapItem item( QPixmap::fromImage(image));
    static QGraphicsScene* scene = new QGraphicsScene;
    scene->addItem(&item);

    ui->graphicsView->setScene(scene);
    ui->graphicsView->repaint();
}

Right now I'm using if(color>0) color = 255-color; to correct for this effect, but I'd much rather understand where it's coming from.

Also, a second mini-question: if I remove the static declarations in redraw(), the image gets removed from memory immediately when the method exits. Is this the best way to fix this, and am I going to have any unintended side effects if I display multiple frames?

Community
  • 1
  • 1
Ryan Kennedy
  • 3,275
  • 4
  • 30
  • 47
  • 1
    Internally opencv::Mat is BGR and QImage ARGB32 is BGRA so you can just copy groups of 3bytes then set the 'a' on the destination – Martin Beckett Nov 17 '12 at 23:16
  • Hang on, I don't think grayscale images should be converted using QRgb and QImage::Format_ARGB32. Is not that only for color images, say cv::Mat3b? – Barney Szabolcs Nov 18 '12 at 00:21

2 Answers2

1

I don't know. Setting an array first for me sounds like a cleaner way, see https://stackoverflow.com/a/3387400/1705967 , that could give you ideas.

Although I also use Ypnos's solution with a great success on color images. :)

Ah, and as for the second question, don't worry about the QPixmap. It makes the image data private (clones when necessary) as I have experienced so you won't overwrite it by mistake.

Community
  • 1
  • 1
Barney Szabolcs
  • 11,846
  • 12
  • 66
  • 91
0

In case anyone is having this problem, I quickly and dirtily fixed it by subtracting the pixel value to 256:

QImage ImgConvert::matToQImage(Mat_<double> src)
{
    double scale = 255.0;

    QImage dest(src.cols, src.rows, QImage::Format_ARGB32);
    for (int y = 0; y < src.rows; ++y) {
            const double *srcrow = src[y];
            QRgb *destrow = (QRgb*)dest.scanLine(y);
            for (int x = 0; x < src.cols; ++x) {
                    unsigned int color = 256 - (srcrow[x] * scale);
                    destrow[x] = qRgba(color, color, color, 255);
            }
    }
    return dest;
}

This will slightly corrupt the image, though, modifying by 1 its bright. My purpose was visualizing so the difference was negligible to the eye, however for certain applications in image processing this corruption might be critical. I could not find why was this happening and as I was in a hurry I did not look any further.

chechopeefe
  • 178
  • 9
  • This is basically what I did, except without modifying the brightness. Check out my note in the original question... technically I fixed the problem, but if I don't understand why it works then it's a hack. I wanted someone to explain why that hack works/is necessary. – Ryan Kennedy Apr 26 '13 at 15:20