Пример #1
0
void ROIFinder::_findAreas( PixelViewports& resultPVPs )
{
    LBASSERT( _areasToCheck.empty() );

    Area area( PixelViewport( 0, 0, _w, _h ));
    area.pvp  = _getObjectPVP( area.pvp, &_mask[0] );

    if( area.pvp.w <= 0 || area.pvp.h <= 0 )
        return;

    area.hole = _emptyFinder.getLargestEmptyArea( area.pvp );

    if( area.hole.getArea() == 0 )
        resultPVPs.push_back( area.pvp );
    else
        _areasToCheck.push_back( area );

    // try to split areas
    while( !_areasToCheck.empty() )
    {
        Area curArea = _areasToCheck.back();
        _areasToCheck.pop_back();

        uint8_t n = _splitArea( curArea );
        LBASSERT( n >= 2 && n <= 4 );

        for( uint8_t i = 0; i < n; i++ )
        {
            LBASSERT( _finalAreas[i].valid );
            LBASSERT( _finalAreas[i].pvp.hasArea( ));

            if( _finalAreas[i].hole.getArea() == 0 )
                resultPVPs.push_back( _finalAreas[i].pvp );
            else
                _areasToCheck.push_back( _finalAreas[i] );
        }
    }

    // correct position and sizes
    for( uint32_t i = 0; i < resultPVPs.size(); i++ )
    {
#ifndef NDEBUG
        // fill temporary array with found regions to
        // dump it later in _dumpDebug
        _fillWithColor( resultPVPs[i], &_tmpMask[0],
                        uint8_t( 255 - i*200/resultPVPs.size( )));
#endif

        PixelViewport& pvp = resultPVPs[i];
        pvp.x += _pvp.x;
        pvp.y += _pvp.y;

        pvp.apply( Zoom( GRID_SIZE, GRID_SIZE ));
    }

}
Пример #2
0
PixelViewports ROIFinder::findRegions( const uint32_t         buffers,
                                       const PixelViewport&   pvp,
                                       const Zoom&            zoom,
                                       const uint32_t         stage,
                                       const uint128_t&       frameID,
                                       util::ObjectManager&   glObjects )
{
    PixelViewports result;
    result.push_back( pvp );

    LBLOG( LOG_ASSEMBLY ) << "ROIFinder::getObjects " << pvp << ", buffers "
                          << buffers << std::endl;

    if( zoom != Zoom::NONE )
    {
        LBWARN << "R-B optimization impossible when zoom is used"
               << std::endl;
        return result;
    }

#ifdef EQ_ROI_USE_TRACKER
    uint8_t* ticket;
    if( !_roiTracker.useROIFinder( pvp, stage, frameID, ticket ))
        return result;
#endif

    _pvpOriginal = pvp;
    _resize( _getBoundingPVP( pvp ));

    // go through depth buffer and check min/max/BG values
    // render to and read-back usefull info from FBO
    _readbackInfo( glObjects );
    glObjects.clear();

    // Analyze readed back data and find regions of interest
    _init( );

    _emptyFinder.update( &_mask[0], _wb, _hb );
    _emptyFinder.setLimits( 200, 0.002f );

    result.clear();
    _findAreas( result );

#ifdef EQ_ROI_USE_TRACKER
    _roiTracker.updateDelay( result, ticket );
#endif

    return result;
}
Пример #3
0
void ROITracker::updateDelay( const PixelViewports& pvps,
                              const uint8_t* ticket )
{
    LBASSERT( _needsUpdate );
    LBASSERTINFO( ticket == _ticket, "Wrong ticket" );

    if( ticket != _ticket )
    {
        LBERROR << "Wrong ticket" << std::endl;
        return;
    }

    uint32_t totalAreaFound = 0;
    for( uint32_t i = 0; i < pvps.size(); i++ )
        totalAreaFound += pvps[ i ].getArea();

    Area& area = (*_curFrame)[ _lastStage ].areas.back();
    if( totalAreaFound < area.pvp.getArea()*4/5 )
    {
        // ROI cutted enough, reset failure statistics
        area.lastSkip = 0;
    }else
    {
        // disable ROI for next frames, if it was failing before, 
        // increase number of frames to skip
        area.lastSkip = LB_MIN( area.lastSkip*2 + 1, 64 );
        area.skip     = area.lastSkip;
    }
    _needsUpdate = false;
}
Пример #4
0
Images FrameData::startReadback( const Frame& frame,
                                 util::ObjectManager& glObjects,
                                 const DrawableConfig& config,
                                 const PixelViewports& regions )
{
    if( _impl->data.buffers == Frame::BUFFER_NONE )
        return Images();

    const Zoom& zoom = frame.getZoom();
    if( !zoom.isValid( ))
    {
        LBWARN << "Invalid zoom factor, skipping frame" << std::endl;
        return Images();
    }

    const eq::PixelViewport& framePVP = getPixelViewport();
    const PixelViewport      absPVP   = framePVP + frame.getOffset();
    if( !absPVP.isValid( ))
        return Images();

    Images images;

    // readback the whole screen when using textures
    if( getType() == eq::Frame::TYPE_TEXTURE )
    {
        Image* image = newImage( getType(), config );
        if( image->startReadback( getBuffers(), absPVP, zoom, glObjects ))
            images.push_back( image );
        image->setOffset( 0, 0 );
        return images;
    }
    //else read only required regions

#if 0
    // TODO: issue #85: move automatic ROI detection to eq::Channel
    PixelViewports regions;
    if( _impl->data.buffers & Frame::BUFFER_DEPTH && zoom == Zoom::NONE )
        regions = _impl->roiFinder->findRegions( _impl->data.buffers, absPVP,
                                                 zoom, frame.getAssemblyStage(),
                                                 frame.getFrameID(), glObjects);
    else
        regions.push_back( absPVP );
#endif

    LBASSERT( getType() == eq::Frame::TYPE_MEMORY );
    const eq::Pixel& pixel = getPixel();

    for( uint32_t i = 0; i < regions.size(); ++i )
    {
        PixelViewport pvp = regions[ i ] + frame.getOffset();
        pvp.intersect( absPVP );
        if( !pvp.hasArea( ))
            continue;

        Image* image = newImage( getType(), config );
        if( image->startReadback( getBuffers(), pvp, zoom, glObjects ))
            images.push_back( image );

        pvp -= frame.getOffset();
        pvp.apply( zoom );
        image->setOffset( (pvp.x - framePVP.x) * pixel.w,
                          (pvp.y - framePVP.y) * pixel.h );
    }
    return images;
}