TuttleOFX  1
thinning.hpp
Go to the documentation of this file.
00001 #ifndef _TERRY_FILTER_THINNING_HPP_
00002 #define _TERRY_FILTER_THINNING_HPP_
00003 
00004 #include <terry/channel.hpp>
00005 #include <terry/math/Rect.hpp>
00006 #include <terry/algorithm/transform_pixels.hpp>
00007 #include <terry/numeric/operations.hpp>
00008 #include <terry/numeric/assign_minmax.hpp>
00009 #include <terry/numeric/init.hpp>
00010 
00011 namespace terry {
00012 namespace filter {
00013 namespace thinning {
00014 
00015 static const bool lutthin1[512] = { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false, true, true, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, true, true, false, false, true, true, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, false, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, true, false, false, true, true, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, true, false, false, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true };
00016 static const bool lutthin2[512] = { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, false, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, false, true, false, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, false, false, true, false, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, false, true, true, true, false, false, true, true, false, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, false, false, true, false, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, false, true, true, true, false, false, true, true, false, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, false, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, false, false, true, false, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, false, true, true, true, false, false, true, true, false, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, false, false, true, false, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, false, true, true, true, false, false, true, true, false, true, true, true };
00017 
00018 template<class SView, class DView=SView>
00019 struct pixel_locator_thinning_t
00020 {
00021         typedef typename SView::locator SLocator;
00022         typedef typename DView::locator DLocator;
00023         typedef typename SView::value_type SPixel;
00024         typedef typename DView::value_type DPixel;
00025         typedef typename SLocator::cached_location_t SCachedLocation;
00026 
00027         const bool* _lut;
00028         SPixel _sWhite;
00029         DPixel _dWhite;
00030         DPixel _dBlack;
00031         const SLocator _loc_ref;
00032         // LT CT RT
00033         // LC    RC
00034         // LB CB RB
00035         const SCachedLocation LT;
00036         const SCachedLocation CT;
00037         const SCachedLocation RT;
00038         const SCachedLocation LC;
00039         const SCachedLocation RC;
00040         const SCachedLocation LB;
00041         const SCachedLocation CB;
00042         const SCachedLocation RB;
00043 
00044         pixel_locator_thinning_t( const SView& src, const bool* lut )
00045         : _lut(lut)
00046         , _loc_ref(src.xy_at(0,0))
00047         , LT(_loc_ref.cache_location(-1,-1))
00048         , CT(_loc_ref.cache_location( 0,-1))
00049         , RT(_loc_ref.cache_location( 1,-1))
00050 
00051         , LC(_loc_ref.cache_location(-1, 0))
00052         , RC(_loc_ref.cache_location( 1, 0))
00053 
00054         , LB(_loc_ref.cache_location(-1, 1))
00055         , CB(_loc_ref.cache_location( 0, 1))
00056         , RB(_loc_ref.cache_location( 1, 1))
00057         {
00058                 using namespace terry::numeric;
00059                 pixel_assigns_max( _sWhite );
00060                 pixel_assigns_min( _dBlack );
00061                 pixel_assigns_max( _dWhite );
00062         }
00063 
00064         DPixel operator()( const SLocator& src ) const
00065         {
00066                 using namespace terry;
00067 
00068                 if( *src != _sWhite )
00069                 {
00070                         return _dBlack;
00071                 }
00072                 
00073                 std::size_t id =  ( src[LT] == _sWhite )       |
00074                                      (( src[LC] == _sWhite ) << 1) |
00075                                      (( src[LB] == _sWhite ) << 2) |
00076                                      (( src[CT] == _sWhite ) << 3) |
00077                                      (( *src    == _sWhite ) << 4) |
00078                                      (( src[CB] == _sWhite ) << 5) |
00079                                      (( src[RT] == _sWhite ) << 6) |
00080                                      (( src[RC] == _sWhite ) << 7) |
00081                                      (( src[RB] == _sWhite ) << 8);
00082                 
00083                 if( _lut[id] )
00084                 {
00085                         return _dWhite;
00086                 }
00087                 return _dBlack;
00088         }
00089 };
00090 
00091 
00092 
00093 }
00094 
00095 
00096 template<class SView, class DView>
00097 void applyThinning( const SView& srcView, DView& tmpView, DView& dstView )
00098 {
00099         using namespace terry::numeric;
00100         
00101         typedef typename DView::value_type DPixel;
00102         DPixel pixelZero; pixel_zeros_t<DPixel>()( pixelZero );
00103         
00104         // todo: only fill borders !!
00105         fill_pixels( tmpView, pixelZero );
00106 
00107         const Rect<std::ptrdiff_t> srcRod = getBounds<std::ptrdiff_t>(srcView);
00108         const Rect<std::ptrdiff_t> proc1 = rectangleReduce( srcRod, 1 );
00109         const Rect<std::ptrdiff_t> proc2 = rectangleReduce( proc1, 1 );
00110 
00111         algorithm::transform_pixels_locator(
00112                 srcView, srcRod,
00113                 tmpView, getBounds<std::ptrdiff_t>(tmpView),
00114                 proc1,
00115                 terry::filter::thinning::pixel_locator_thinning_t<SView,DView>(srcView, terry::filter::thinning::lutthin1)
00116                 );
00117 
00118         // todo: only fill borders !!
00119         fill_pixels( dstView, pixelZero );
00120         
00121         algorithm::transform_pixels_locator(
00122                 tmpView, getBounds<std::ptrdiff_t>(tmpView),
00123                 dstView, getBounds<std::ptrdiff_t>(dstView),
00124                 proc2,
00125                 terry::filter::thinning::pixel_locator_thinning_t<DView,DView>(tmpView, terry::filter::thinning::lutthin2)
00126                 );
00127 }
00128 
00129 }
00130 }
00131 
00132 #endif
00133