TuttleOFX  1
main.cpp
Go to the documentation of this file.
00001 #include <tuttle/common/utils/global.hpp>
00002 
00003 #include <tuttle/host/Graph.hpp>
00004 
00005 #include <boost/gil/gil_all.hpp>
00006 
00007 #define png_infopp_NULL (png_infopp)NULL
00008 #define int_p_NULL (int*)NULL
00009 
00010 #include <boost/gil/extension/io/png_io.hpp>
00011 #include <boost/gil/image_view_factory.hpp>
00012 #include <boost/preprocessor/stringize.hpp>
00013 #include <boost/lexical_cast.hpp>
00014 
00015 #include <boost/timer.hpp>
00016 #include <boost/date_time/posix_time/posix_time.hpp>
00017 
00018 int main( int argc, char** argv )
00019 {
00020         boost::shared_ptr<tuttle::common::formatters::Formatter> formatter( tuttle::common::formatters::Formatter::get() );
00021         boost::shared_ptr<tuttle::common::Color>                 color( tuttle::common::Color::get() );
00022         formatter->init_logging();
00023         color->disable();
00024         
00025         if( argc < 2 )
00026         {
00027                 TUTTLE_LOG_ERROR( "[canny example] Missing operand." );
00028                 TUTTLE_LOG_ERROR( "[canny example] Usage: ./canny image.png" );
00029                 return 1;
00030         }
00031         try
00032         {
00033                 using namespace tuttle::host;
00034                 TUTTLE_LOG_INFO( "[canny example] Preload plugins" );
00035                 core().preload();
00036 
00037                 TUTTLE_TLOG( TUTTLE_INFO, core().getImageEffectPluginCache() );
00038 
00039                 TUTTLE_LOG_INFO( "[canny example] Preload done" );
00040 
00041 //              boost::gil::rgba32f_image_t imgRead;
00042 //              boost::gil::rgba8_image_t imgRead;
00043                 boost::gil::gray8_image_t imgRead;
00044                 boost::gil::png_read_and_convert_image( argv[1], imgRead );
00045 //              boost::gil::rgba32f_view_t imgView( view( imgRead ) );
00046 //              boost::gil::rgba8_view_t imgView( view( imgRead ) );
00047                 boost::gil::gray8_view_t imgView( view( imgRead ) );
00048 
00049                 TUTTLE_LOG_INFO( "[canny example] Create graph" );
00050 
00051                 Graph g;
00052                 InputBufferWrapper inputBuffer1 = g.createInputBuffer();
00053                 Graph::Node& bitdepth1    = g.createNode( "tuttle.bitdepth" );
00054                 Graph::Node& bitdepth2    = g.createNode( "tuttle.bitdepth" );
00055                 Graph::Node& blur         = g.createNode( "tuttle.blur" );
00056                 Graph::Node& blur1        = g.createNode( "tuttle.blur" );
00057                 Graph::Node& blur2        = g.createNode( "tuttle.blur" );
00058                 Graph::Node& sobel        = g.createNode( "tuttle.sobel" );
00059                 Graph::Node& sobel1       = g.createNode( "tuttle.sobel" );
00060                 Graph::Node& sobel2       = g.createNode( "tuttle.sobel" );
00061                 Graph::Node& localMaxima  = g.createNode( "tuttle.localmaxima" );
00062                 Graph::Node& floodfill    = g.createNode( "tuttle.floodfill" );
00063                 Graph::Node& thinning     = g.createNode( "tuttle.thinning" );
00064                 Graph::Node& write00       = g.createNode( "tuttle.pngwriter" );
00065                 Graph::Node& write0       = g.createNode( "tuttle.pngwriter" );
00066                 Graph::Node& write1a       = g.createNode( "tuttle.pngwriter" );
00067                 Graph::Node& write1b       = g.createNode( "tuttle.pngwriter" );
00068                 Graph::Node& write2       = g.createNode( "tuttle.pngwriter" );
00069                 Graph::Node& write3       = g.createNode( "tuttle.pngwriter" );
00070                 Graph::Node& write4       = g.createNode( "tuttle.pngwriter" );
00071 
00072                 TUTTLE_LOG_INFO( "[canny example] Initialize input buffer" );
00073                 
00074                 inputBuffer1.setRawImageBuffer(
00075                                 (void*)boost::gil::interleaved_view_get_raw_data( imgView ),
00076                                 imgView.width(), imgView.height(),
00077                                 InputBufferWrapper::ePixelComponentAlpha,
00078                                 InputBufferWrapper::eBitDepthUByte,
00079                                 imgView.pixels().row_size(),
00080                                 InputBufferWrapper::eImageOrientationFromTopToBottom
00081                         );
00082 
00083                 // Setup parameters
00084                 static const double kernelEpsilon = 0.01;
00085 
00086                 TUTTLE_LOG_INFO( "[canny example] setup parameters" );
00087                 TUTTLE_LOG_INFO( "[canny example] kernel epsilon " << kernelEpsilon );
00088 
00089                 bitdepth1.getParam( "outputBitDepth" ).setValue( "float" );
00090                 bitdepth2.getParam( "outputBitDepth" ).setValue( "byte" );
00091 
00092                 blur.getParam( "border" ).setValue( "Padded" );
00093                 blur.getParam( "size" ).setValue( 1.0, 1.0 );
00094                 blur.getParam( "normalizedKernel" ).setValue( false );
00095                 blur.getParam( "kernelEpsilon" ).setValue( kernelEpsilon );
00096 
00097                 blur1.getParam( "border" ).setValue( "Padded" );
00098                 blur1.getParam( "size" ).setValue( 1.0, 0.0 );
00099                 blur1.getParam( "normalizedKernel" ).setValue( false );
00100                 blur1.getParam( "kernelEpsilon" ).setValue( kernelEpsilon );
00101 
00102                 blur2.getParam( "border" ).setValue( "Padded" );
00103                 blur2.getParam( "size" ).setValue( 0.0, 1.0 );
00104                 blur2.getParam( "normalizedKernel" ).setValue( false );
00105                 blur2.getParam( "kernelEpsilon" ).setValue( kernelEpsilon );
00106 
00107                 sobel.getParam( "border" ).setValue( "Padded" );
00108                 sobel.getParam( "size" ).setValue( 1.0, 1.0 );
00109                 sobel.getParam( "normalizedKernel" ).setValue( false );
00110                 sobel.getParam( "computeGradientDirection" ).setValue( false );
00111                 sobel.getParam( "kernelEpsilon" ).setValue( kernelEpsilon );
00112 //              sobel.getParam( "unidimensional" ).setValue( true );
00113                 sobel.getParam( "outputComponent" ).setValue( "RGB" );
00114 
00115                 sobel1.getParam( "border" ).setValue( "Padded" );
00116                 sobel1.getParam( "size" ).setValue( 1.0, 1.0 );
00117                 sobel1.getParam( "normalizedKernel" ).setValue( false );
00118                 sobel1.getParam( "computeGradientDirection" ).setValue( false );
00119                 sobel1.getParam( "kernelEpsilon" ).setValue( kernelEpsilon );
00120                 sobel1.getParam( "pass" ).setValue( 1 );
00121                 sobel1.getParam( "outputComponent" ).setValue( "RGB" );
00122 
00123                 sobel2.getParam( "border" ).setValue( "Padded" );
00124                 sobel2.getParam( "size" ).setValue( 1.0, 1.0 );
00125                 sobel2.getParam( "normalizedKernel" ).setValue( false );
00126                 sobel2.getParam( "computeGradientDirection" ).setValue( false );
00127                 sobel2.getParam( "kernelEpsilon" ).setValue( kernelEpsilon );
00128                 sobel2.getParam( "pass" ).setValue( 2 );
00129                 sobel2.getParam( "outputComponent" ).setValue( "RGB" );
00130 
00131                 localMaxima.getParam( "outputComponent" ).setValue( "Alpha" );
00132 
00133 //              normalize.getParam( "mode" ).setValue( 0 ); //"analyse" );
00134 //              normalize.getParam( "analyseMode" ).setValue( 0 ); //"perChannel" );
00135 //              normalize.getParam( "processR" ).setValue( false );
00136 //              normalize.getParam( "processG" ).setValue( false );
00137 //              normalize.getParam( "processB" ).setValue( true  );
00138 //              normalize.getParam( "processA" ).setValue( false );
00139                 floodfill.getParam( "upperThres" ).setValue( 0.1 );
00140                 floodfill.getParam( "lowerThres" ).setValue( 0.025 );
00141 
00142                 write00.getParam( "channel" ).setValue( "rgba" );
00143                 write0.getParam( "channel" ).setValue( "rgba" );
00144                 write1a.getParam( "channel" ).setValue( "rgba" );
00145                 write1b.getParam( "channel" ).setValue( "rgba" );
00146                 write2.getParam( "channel" ).setValue( "rgba" );
00147                 write3.getParam( "channel" ).setValue( "rgba" );
00148                 write4.getParam( "channel" ).setValue( "rgba" );
00149 
00150                 write00.getParam( "filename" ).setValue( "data/canny/0_input.png" );
00151                 write0.getParam( "filename" ).setValue( "data/canny/0_blur.png" );
00152                 write1a.getParam( "filename" ).setValue( "data/canny/1a_sobel.png" );
00153                 write1b.getParam( "filename" ).setValue( "data/canny/1b_sobel.png" );
00154                 write2.getParam( "filename" ).setValue( "data/canny/2_localMaxima.png" );
00155                 write3.getParam( "filename" ).setValue( "data/canny/3_floodfill.png" );
00156                 write4.getParam( "filename" ).setValue( "data/canny/4_thinning.png" );
00157 
00158                 TUTTLE_LOG_INFO( "[canny example] connect plugins" );
00159 //              g.connect( read1, bitdepth );
00160 //              g.connect( bitdepth, sobel1 );
00161 
00162                 g.connect( inputBuffer1.getNode(), bitdepth1 );
00163                 g.connect( bitdepth1, blur1 );
00164                 g.connect( blur1, blur2 );
00165                 g.connect( blur2, sobel1 );
00166                 g.connect( sobel1, sobel2 );
00167                 g.connect( sobel2, localMaxima );
00168 //              g.connect( blur, sobel );
00169 //              g.connect( sobel, localMaxima );
00170                 g.connect( localMaxima, floodfill );
00171                 g.connect( floodfill, thinning );
00172                 g.connect( thinning, bitdepth2 );
00173 
00174                 g.connect( bitdepth1, write00 );
00175                 g.connect( blur2, write0 );
00176                 g.connect( sobel1, write1a );
00177                 g.connect( sobel2, write1b );
00178                 g.connect( localMaxima, write2 );
00179                 g.connect( floodfill, write3 );
00180                 g.connect( thinning, write4 );
00181 
00182                 std::list<std::string> outputs;
00183                 outputs.push_back( write00.getName() );
00184 //              outputs.push_back( write0.getName() );
00185                 outputs.push_back( write1a.getName() );
00186 //              outputs.push_back( write1b.getName() );
00187                 outputs.push_back( write2.getName() );
00188 //              outputs.push_back( write2.getName() );
00189                 outputs.push_back( write3.getName() );
00190                 outputs.push_back( write4.getName() );
00191                 outputs.push_back( bitdepth2.getName() );
00192 
00193                 TUTTLE_LOG_INFO( "[canny example] process" );
00194                 boost::posix_time::ptime t1(boost::posix_time::microsec_clock::local_time());
00195 //              memory::MemoryCache res0 = g.compute( bitdepth2 );
00196                 memory::MemoryCache outputCache;
00197                 g.compute( outputCache, outputs );
00198                 boost::posix_time::ptime t2(boost::posix_time::microsec_clock::local_time());
00199 
00200                 TUTTLE_LOG_INFO( "[canny example] Process took: " << t2 - t1 );
00201 
00202                 TUTTLE_LOG_INFO( outputCache );
00203                 memory::CACHE_ELEMENT imgRes = outputCache.get( bitdepth2.getName(), 0 );
00204 
00205                 TUTTLE_LOG_VAR( TUTTLE_TRACE, imgRes->getROD() );
00206                 TUTTLE_LOG_VAR( TUTTLE_TRACE, imgRes->getBounds() );
00207 //              boost::gil::rgba32f_view_t imgResView = imgRes->getGilView<boost::gil::rgba32f_view_t>();
00208 //              boost::gil::rgba8_view_t imgResView = imgRes->getGilView<boost::gil::rgba8_view_t>();
00209                 boost::gil::gray8_view_t imgResView = imgRes->getGilView<boost::gil::gray8_view_t>( tuttle::host::attribute::Image::eImageOrientationFromTopToBottom );
00210                 boost::gil::png_write_view( "data/canny/manual_output.png", boost::gil::color_converted_view<boost::gil::rgb8_pixel_t>( imgResView ) );
00211         }
00212         catch( tuttle::exception::Common& e )
00213         {
00214                 TUTTLE_LOG_ERROR( "[canny example] Tuttle exception" );
00215                 TUTTLE_LOG_ERROR( boost::diagnostic_information( e ) );
00216         }
00217         catch(... )
00218         {
00219                 TUTTLE_LOG_ERROR( "[canny example] Erreur inconnue" );
00220                 TUTTLE_LOG_ERROR( boost::current_exception_diagnostic_information() );
00221 
00222         }
00223 
00224         return 0;
00225 }
00226