This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Eigen Matrix to QImage

Tags: None
(comma "," separated)
linello
Registered Member
Posts
56
Karma
0
OS

Eigen Matrix to QImage

Mon Jan 16, 2012 8:40 am
Hi,

Maybe this forum is not for this kind of question because it regards Qt.

How is possible to map a current memory area contained by a MatrixXi to a QImage using a QImage::Format_RGB32?

The constructor in QImage accept an unsigned char* as first pointer to the data and then matrix width and height, as well as a format specifier.

Code: Select all
QImage ( uchar * data, int width, int height, Format format );


but the cast from int to unsigned char give me some problem and I really don't know actually if this makes sense.

I would like to show the content of a matrix of integers [0,255] using a QImage on a Qt Widget.

Any hint is appreciated, thanks!
Andre
Registered Member
Posts
90
Karma
1

Re: Eigen Matrix to QImage

Mon Jan 16, 2012 11:33 am
Well, RGB32 uses 3 8-bit values per pixel, one for each channel, whereas your matrix only contains one value per pixel. If you just cast your data, you will probably get senseless results, as it will be 8-bit masks of your values (first 8 bits, second 8 bits, etc.). On the other hand, Qt saves 8-bit images with indexed colors, so it will not be possible to set the values directly. I'd suggest a loop over the pixels setting the values iteratively. It's not as efficient, but probably makes more sense.


'And all those exclamation marks, you notice? Five? A sure sign of someone who wears his underpants on his head.' ~Terry Pratchett

'It's funny. All you have to do is say something nobody understands and they'll do practically anything you want them to.' ~J.D. Salinger
linello
Registered Member
Posts
56
Karma
0
OS

Re: Eigen Matrix to QImage

Mon Jan 16, 2012 2:07 pm
Thank you, your suggestion has clarified me the situation and helped me to understand how to do.

To overcome the limitation of obtaining a color image from double data, I wrote a simple map function (which emulates the classical octave jet colormap)


Code: Select all
// Convert a double in [0,1] to a qRbg value
uint MatrixPaintWidget::doubleToJetMap(double x)
{
    double  r = 255*((x >= 0.375 & x < 0.625) * (4.0 * x - 1.5) + (x >= 0.625 & x < 0.875) + (x >= 0.875) * (-4.0 * x + 4.5));
    double g = 255*((x >= 0.125 & x < 0.375) * (4.0 * x - 0.5) + (x >= 0.375 & x < 0.625) + (x >= 0.625 & x < 0.875) * (-4.0 * x + 3.5));
    double b = 255*((x < 0.125) * (4.0 * x + 0.5) + (x >= 0.125 & x < 0.375) + (x >= 0.375 & x < 0.625) * (-4.0 * x + 2.5));

    return qRgb((int)r,(int)g,(int)b);
}


With this map, transforming a MatrixXd to a coloured RGB QImage is quite simple using two for loops.

Code: Select all
QImage eigenToQImage(const Eigen::MatrixXd &m)
{
    QImage I(m.cols(),m.rows(),QImage::Format_RGB32);

    for ( int i=0; i<m.cols(); i++ )
    {
        for ( int j=0; j<m.rows(); j++)
            I.setPixel(j,i, doubleToJetMap(m.coeffRef(i,j)));
    }
    return I;
}


I hope this can be useful to others (important, for the image to extend on the full colormap, matrix values must lie in the interval [0,1]


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]