Monday, March 1, 2010

Merging Qt and Eigen

Again in ViBOT, image segmentation assignment, Matlab is really slow, wait minutes for results...

So I decided to try to use Qt for the GUI and OS abstraction layer together with Eigen which is another amazing template-based library for matrix manipulation. The important code to write was to link both libraries, taking advantage of Qt's amazing QImage class which is able to open several file formats and perform low-level pixel access. In a few words, I had to put all the image information contained in QImage into a Eigen's matrix.

Luckily, this task is very simple. Here there is some code:

#ifndef MIMG_H#define MIMG_HUSING_PART_OF_NAMESPACE_EIGEN#include <QImage>#include <Eigen/Core>#include <Eigen/Array>//general type, maybe float or double neededtypedef MatrixXf    MImgType;class MImg{public: //creates an all-black image MImg(unsigned int h, unsigned int w); //creates image from QImage MImg( const QImage &img ); MImgType    R,G,B;  //each component         //made public for faster access unsigned int    getHeight(); unsigned int    getWidth(); QImage *    toQImage();  //convert to QImage /**   Maximizes dynamic range of three channels   independently!  **/ void    maximizeIndependentDynamicRange();private: unsigned int mH,mW; //height, width};#endif // MIMG_H

#include "mimg.h"MImg::MImg(unsigned int h, unsigned int w){  R = MImgType::Zero(h,w);  G = MImgType::Zero(h,w);  B = MImgType::Zero(h,w);  mH = h;  mW = w;}MImg::MImg( const QImage &img ){  int w = img.width();  int h = img.height();  R = MImgType::Zero(h,w);  G = MImgType::Zero(h,w);  B = MImgType::Zero(h,w);   //now copy values..    for (int y=0; y < h; y++)        for (int x=0; x < w; x++)        {            QRgb color = img.pixel(x,y);            R(y,x) = qRed(color)/255.0;            G(y,x) = qGreen(color)/255.0;            B(y,x) = qBlue(color)/255.0;        }  return img;}void    MImg::maximizeIndependentDynamicRange(){  double  min, max;  min = R.minCoeff(); max = R.maxCoeff();  R = (R.cwise() - min) / (max - min);  min = G.minCoeff(); max = G.maxCoeff();  G = (G.cwise() - min) / (max - min);  min = B.minCoeff(); max = B.maxCoeff();  B = (B.cwise() - min) / (max - min);}unsigned int    MImg::getHeight() {  return mH;}unsigned int    MImg::getWidth() {  return mW;}

It is important to mention that this code only handles RGB and won't care about grayscale images or any other type of colour models. The advantage of having the image in this matrix form is that Eigen provides an easy syntax for matrix manipulation, along with many modules performing least squares, Cholesky, diagonalization, etc.

1. I'm a kinbd of new in C++ and I'm doing a project using Qt. And I also have need to use Eigen, but I don't know how exactly to add eigen to the include path. Can you give me a help with this?

2. I think the best place is Eigen's documentation, take a look at the beginning of this tutorial: http://eigen.tuxfamily.org/dox-devel/TutorialCore.html

3. I wanna use Qt and Eigen API. How can I write makefile for running this.