Qt и обработка изображений - PullRequest
10 голосов
/ 25 февраля 2011

Как кто-то может использовать Qt для обработки изображений?Есть ли для этого библиотеки или плагины для Qt?

Спасибо.

Ответы [ 3 ]

10 голосов
/ 25 февраля 2011

Qt скорее предназначен для разработки графических пользовательских интерфейсов (GUI). Тем не менее, он поставляется с множеством дополнительных библиотек, включая библиотеку, предназначенную для обработки изображений 1002 *. Однако, если вы хотите серьезно, я бы порекомендовал выделенную библиотеку, например OpenCV .

2 голосов
/ 26 февраля 2011

Я использовал Qt для GUI плюс LTIlib для обработки изображений.

Сам Qt не очень поможет при обработке любого изображения, но есть пара независимых библиотек, которые вы можете использовать лучше всего для своих нужд. Имейте в виду, что Qt по сути предназначен для создания графического интерфейса. Очень хорошо, если не лучше, создавать окна, кнопки, представления деревьев и т. Д., Но не ожидайте, что оно будет настолько всеобъемлющим, что может делать все.

Пожалуйста, дайте нам знать более точно, что вы имеете в виду, когда говорите «обработка изображений». Это огромное правление с сотнями или тысячами возможных целей и подходов ...

EDIT:

Вот небольшой отрывок или то, что я делал с Qt + LTI. См. LTI документацию для всех доступных операторов. Раньше я делал свертки, самокорреляции, базовую эрозию / расширение и многое другое.

#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(  );
}

Снова отредактируйте:

Я нашел другой образец, который может быть более интересным для вас ...

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 ) );

Остальное похоже на первый пример. Надеюсь, это поможет.

0 голосов
/ 25 февраля 2011

Обработка изображений - довольно общий термин. Посмотрите на VTK и ITK от Kitware. Также Freemat (клон Matlab) основан на Qt. Qt популярен среди количественных ученых, я ожидаю, что существует немало библиотек и продуктов, основанных на Qt.

...