Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt and image processing [closed]

How can someone use Qt for image processing? Are there libraries or plugins for Qt for this purpose?

Thanks.

like image 776
Simplicity Avatar asked Feb 25 '11 19:02

Simplicity


People also ask

How do you convert QImage to QPixmap?

A QPixmap object can be converted into a QImage using the toImage() function. Likewise, a QImage can be converted into a QPixmap using the fromImage(). If this is too expensive an operation, you can use QBitmap::fromImage() instead.

How do you save in QImage?

Simply call the save() function to save a QImage object.


2 Answers

Qt is rather meant for developing graphical user interfaces (GUIs). However, it comes with a lot of supplementary libraries, including one dedicated to image processing. However, if you want to get serious, I would recommend a dedicated library such as OpenCV.

like image 103
Greg Avatar answered Sep 21 '22 12:09

Greg


I did use Qt for GUI plus LTIlib for image processing.

Qt itself won't be very helpful for processing any image, but there are a couple of independent libraries that you can use best fitting your needs. Bear in mind that Qt is essentially meant to be a GUI framework. It is very very good, if not the best, to make windows, buttons, tree views, etc. but don't expect it to be so comprehensive that can do everything.

Please let us to know more preciselly what you mean when you say "image processing". It is a vast reign with hundreds or thousands of possible goals and approaches...

EDIT:

Here is a small excerpt or what I used to do with Qt+LTI. See LTI documentation for all operators available. I used to do convolutions, self-correlations, basic erosion/dilation and a lot more.

#include    <ltiDilation.h>
#include    <ltiErosion.h>

#include    <ltiBinaryKernels.h>

#include    <ltiFastRelabeling.h>
#include    <ltiLabelAdjacencyMap.h>

void QLTIDialog::init()
{
    viewLayout = new QGridLayout( frmView, 1, 1, 4, 4, "viewLayout" );

    view= new QImageLabel( frmView, "view" );
    viewLayout->addWidget( view, 0, 0 );

    frmView->setUpdatesEnabled( false );

    view->image( &qimg );
}


void QLTIDialog::btnOpen_clicked()
{
    QString fn= QFileDialog::getOpenFileName(
                    "",
                    tr( "All files (*.*)" ),
                    this,
                    tr( "Open image" ),
                    tr( "Select image file" ) );
    if ( !fn.isEmpty(  ) )
    {
        if ( !qimg.load( fn ) )
        {
            QMessageBox::critical( this, tr( "Fatal error" ),
                QString( tr( "Unable to open %1" ) ).arg( fn ),
                tr( "Exit" ) );

            return;
        }

        view->update(  );

        setCaption( fn );
    }
}


void QLTIDialog::btnProcess_clicked()
{
    lti::image      img;
    lti::channel8   tmp0,
                    h, s, v;

    // Taking QImage data, as in the wiki.
    img.useExternData( qimg.width(  ), qimg.height(  ), ( lti::rgbPixel * )qimg.bits(  ) );

    // Converting to HSV gives-me best results, but it can be left out.
    lti::splitImageToHSV    hsv;
    hsv.apply( img, h, s, v );

    // I do some manipulation over the channels to achieve my objects positions.
    lti::maskFunctor< lti::channel8::value_type > masker;
    masker.invert( v, tmp0 );
    masker.algebraicSum( s, tmp0 );

    // Show the resulting processed image (ilustrative)...
    QLTIDialog  *dh= new QLTIDialog;
    dh->showImage( tmp0 );

    // Apply relabeling (example). Any other operator can be used.
    lti::fastRelabeling::parameters flPar;
    flPar.sortSize= true;
    flPar.minimumObjectSize= 25;
    flPar.fourNeighborhood= true;
    flPar.minThreshold= 40;
    lti::fastRelabeling fr( flPar );
    fr.apply( tmp0 );

    lti::image              imgLam;
    lti::labelAdjacencyMap  lam;
    lam.apply( tmp0, imgLam );

    // By hand copy to QImage.
    lti::image::iterator iit= imgLam.begin(  );
    lti::rgbPixel   *pix= ( lti::rgbPixel * )qimg.bits(  );
    for ( ; iit != imgLam.end(  ); ++iit, ++pix )
        *pix= *iit;

    view->update(  );
}


void QLTIDialog::showImage( lti::image &img )
{
    qimg= QImage( reinterpret_cast< uchar * >( &( *img.begin(  ) ) ),
                    img.rows(  ), img.columns(  ), 32, ( QRgb * )NULL,
                    0, QImage::LittleEndian ).copy(  );

    QDialog::show(  );
}


void QLTIDialog::showImage( lti::channel8 &ch )
{
    lti::image  img;
    img.castFrom( ch );

    qimg= QImage( reinterpret_cast< uchar * >( &( *img.begin(  ) ) ),
                    img.rows(  ), img.columns(  ), 32, ( QRgb * )NULL,
                    0, QImage::LittleEndian ).copy(  );

    QDialog::show(  );
}

EDIT Again:

I found another sample that may be more interesting to you...

lti::image      img;
lti::channel8   chnl8( false, imgH, imgW ), h, s, v;

// Pass image data to LTI.
img.useExternData( imgH, imgW, ( lti::rgbPixel * )pixels );

// I got better results in HSV for my images.
lti::splitImageToHSV    hsv;
hsv.apply( img, h, s, v );

// Segmentation.
lti::channel8::iterator it= chnl8.begin(  );
lti::channel8::iterator hit= h.begin(  ),
            sit= s.begin(  ),
            vit= v.begin(  );

for ( ; it != chnl8.end(  ); ++it, ++hit, ++sit, ++vit )
{
    int tmp= *sit * 2;
    tmp-=   *hit - 320 + *vit;
    *it= ( *hit > 40 && tmp > 460 ? 1 : 0 );
}

// Distinguish connected objects.
lti::imatrix    objs;

std::vector< lti::geometricFeatureGroup0 >  objF;

lti::geometricFeaturesFromMask::parameters  gfPar;
gfPar.merge=            true;   // Join close objects.
gfPar.minimumDistance=  lti::point( 24, 24 );
gfPar.minimumMergedObjectSize=  2;  // Exclude small ones.
gfPar.nBest=            800;    // Limit no. of objects.

lti::geometricFeaturesFromMask  gf( gfPar );
gf.apply( chnl8, objs, objF );

points.clear(  );

for( std::vector< lti::geometricFeatureGroup0 >::const_iterator gfg0= objF.begin(  );
        gfg0 != objF.end(  ); ++gfg0 )
    points.push_back( Point( gfg0->cog.x, gfg0->cog.y ) );

The rest is like the first example. Hope it helps.

like image 20
j4x Avatar answered Sep 24 '22 12:09

j4x