TuttleOFX
1
|
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