static void thresholdTemplate( Image& dst, const Image& src, THTYPE t, void ( SIMD::*func )( DSTTYPE*, const SRCTYPE*, size_t, THTYPE ) const ) { SIMD* simd = SIMD::instance(); cvt::IMapScoped<DSTTYPE> mapdst( dst ); cvt::IMapScoped<const SRCTYPE> mapsrc( src ); size_t w = src.width(); size_t h = src.height(); while( h-- ) { ( simd->*func )( mapdst.ptr(), mapsrc.ptr(), w, t ); mapdst++; mapsrc++; } }
void MorphErode::erodeU8( Image& dst, const Image& src, size_t radius ) const { size_t step = radius * 2 + 1; size_t curbuf; size_t w = src.width(); size_t h = src.height(); SIMD* simd = SIMD::instance(); size_t bstride = Math::pad16( w ); uint8_t** buf; size_t i; IMapScoped<uint8_t> mapdst( dst ); IMapScoped<const uint8_t> mapsrc( src ); /* allocate and fill buffer */ ScopedBuffer<uint8_t,true> bufmem( bstride * step ); ScopedBuffer<uint8_t*,true> bufptr( step ); buf = bufptr.ptr(); buf[ 0 ] = bufmem.ptr(); for( i = 0; i < step; i++ ) { if( i != 0 ) buf[ i ] = buf[ i - 1 ] + bstride; simd->erodeSpanU8( buf[ i ], mapsrc.ptr(), w, radius ); mapsrc++; } /* upper border */ simd->MinValueVertU8( mapdst.ptr(), ( const uint8_t** ) buf, radius + 1, w ); for( i = 1; i < radius; i++ ) { uint8_t* prev = mapdst.ptr(); mapdst++; simd->MinValueU8( mapdst.ptr(), ( const uint8_t* ) prev, ( const uint8_t* ) buf[ radius + 1 + i ], w ); } mapdst++; /* center */ curbuf = 0; i = h - 2 * radius - 1; simd->MinValueVertU8( mapdst.ptr(), ( const uint8_t** ) buf, step, w ); mapdst++; while( i-- ) { simd->erodeSpanU8( buf[ curbuf ], mapsrc.ptr(), w, radius ); curbuf = ( curbuf + 1 ) % step; simd->MinValueVertU8( mapdst.ptr(), ( const uint8_t** ) buf, step, w ); mapdst++; mapsrc++; } /* lower border */ /* reorder buffer */ ScopedBuffer<uint8_t*,true> bufptr2( step ); uint8_t** buf2 = bufptr2.ptr(); for( i = 0; i < step; i++ ) buf2[ i ] = buf[ ( curbuf + i ) % step ]; for( i = 1; i <= radius; i++ ) { simd->MinValueVertU8( mapdst.ptr(), ( const uint8_t** ) ( buf2 + i ), step - i, w ); mapdst++; } }
void Threshold::apply( Image& dst, const Image& src, const float threshold, IFilterType type ) const { if( type != IFILTER_CPU || !( src.format().formatID == IFORMAT_GRAY_FLOAT || src.format().formatID == IFORMAT_GRAY_UINT8 ) ) throw CVTException( "Not implemented" ); if( dst.width() != src.width() || dst.height() != src.height() || !( dst.format().formatID == IFORMAT_GRAY_FLOAT || dst.format().formatID == IFORMAT_GRAY_UINT8 ) ) { dst.reallocate( src.width(), src.height(), IFormat::GRAY_UINT8 ); } size_t w = src.width(); size_t h = src.height(); SIMD* simd = SIMD::instance(); if( src.format().formatID == IFORMAT_GRAY_FLOAT ) { if( dst.format().formatID == IFORMAT_GRAY_UINT8 ) { cvt::IMapScoped<uint8_t> mapdst( dst ); cvt::IMapScoped<const float> mapsrc( src ); while( h-- ) { simd->threshold1_f_to_u8( mapdst.ptr(), mapsrc.ptr(), w, threshold ); mapdst++; mapsrc++; } } else { cvt::IMapScoped<float> mapdst( dst ); cvt::IMapScoped<const float> mapsrc( src ); while( h-- ) { simd->threshold1_f_to_f( mapdst.ptr(), mapsrc.ptr(), w, threshold ); mapdst++; mapsrc++; } } } else { uint8_t t = Math::round( threshold * 0xff ); if( dst.format().formatID == IFORMAT_GRAY_UINT8 ) { cvt::IMapScoped<uint8_t> mapdst( dst ); cvt::IMapScoped<const uint8_t> mapsrc( src ); while( h-- ) { simd->threshold1_u8_to_u8( mapdst.ptr(), mapsrc.ptr(), w, t ); mapdst++; mapsrc++; } } else { cvt::IMapScoped<float> mapdst( dst ); cvt::IMapScoped<const uint8_t> mapsrc( src ); while( h-- ) { simd->threshold1_u8_to_f( mapdst.ptr(), mapsrc.ptr(), w, t ); mapdst++; mapsrc++; } } } }
static void morphTemplate( Image& dst, const Image& src, size_t radius, void ( SIMD::*hfunc )( TYPE*, const TYPE*, size_t, size_t ) const, void ( SIMD::*hfuncborder )( TYPE*, const TYPE*, const TYPE*, size_t ) const, void ( SIMD::*vfunc )( TYPE*, const TYPE**, size_t, size_t ) const ) { SIMD* simd = SIMD::instance(); const size_t boxsize = radius * 2 + 1; size_t curbuf; size_t w = src.width(); size_t h = src.height(); size_t bstride = Math::pad16( sizeof( TYPE ) * w ) / sizeof( TYPE ); //FIXME: does this always work - it should TYPE** buf; size_t i; IMapScoped<TYPE> mapdst( dst ); IMapScoped<const TYPE> mapsrc( src ); /* allocate and fill buffer */ ScopedBuffer<TYPE,true> bufmem( bstride * boxsize ); ScopedBuffer<TYPE*,true> bufptr( boxsize ); buf = bufptr.ptr(); buf[ 0 ] = bufmem.ptr(); for( i = 0; i < boxsize; i++ ) { if( i != 0 ) buf[ i ] = buf[ i - 1 ] + bstride; ( simd->*hfunc )( buf[ i ], mapsrc.ptr(), w, radius ); mapsrc++; } /* upper border */ ( simd->*vfunc )( mapdst.ptr(), ( const TYPE** ) buf, radius + 1, w ); for( i = 1; i < radius; i++ ) { TYPE* prev = mapdst.ptr(); mapdst++; ( simd->*hfuncborder )( mapdst.ptr(), ( const TYPE* ) prev, ( const TYPE* ) buf[ radius + 1 + i ], w ); } mapdst++; /* center */ curbuf = 0; i = h - 2 * radius - 1; ( simd->*vfunc )( mapdst.ptr(), ( const TYPE** ) buf, boxsize, w ); mapdst++; while( i-- ) { ( simd->*hfunc )( buf[ curbuf ], mapsrc.ptr(), w, radius ); curbuf = ( curbuf + 1 ) % boxsize; ( simd->*vfunc )( mapdst.ptr(), ( const TYPE** ) buf, boxsize, w ); mapdst++; mapsrc++; } /* lower border */ /* reorder buffer */ ScopedBuffer<TYPE*,true> bufptr2( boxsize ); TYPE** buf2 = bufptr2.ptr(); for( i = 0; i < boxsize; i++ ) buf2[ i ] = buf[ ( curbuf + i ) % boxsize ]; for( i = 1; i <= radius; i++ ) { ( simd->*vfunc )( mapdst.ptr(), ( const TYPE** ) ( buf2 + i ), boxsize - i, w ); mapdst++; } }