
* apps/morphers/iz.cc (main): Here. Save the sequence of recorder images as PNG images using Magick++. (save_colorized): New function. * apps/morphers/Makefile.am (noinst_PROGRAMS, iz_SOURCES) [HAVE_MAGICKXX]: Build `iz' only if Magick++ is available. (iz_output.ppm) [HAVE_MAGICKXX]: Likewise. (iz_CPPFLAGS, iz_LDFLAGS) [HAVE_MAGICKXX]: New. (tmp_iz.avi) [HAVE_MAGICKXX]: New target. (MOSTLYCLEANFILES): Add tmp_iz??????.png. --- milena/ChangeLog | 15 ++++++++++++ milena/apps/morphers/Makefile.am | 16 ++++++++++-- milena/apps/morphers/iz.cc | 47 ++++++++++++++++++++++++++++++++++--- 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/milena/ChangeLog b/milena/ChangeLog index c5eb04c..a8c9cad 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,3 +1,18 @@ +2012-06-21 Roland Levillain <roland@lrde.epita.fr> + + Use the lazy recorder morpher in apps/morphers/iz. + + * apps/morphers/iz.cc (main): Here. + Save the sequence of recorder images as PNG images using Magick++. + (save_colorized): New function. + * apps/morphers/Makefile.am + (noinst_PROGRAMS, iz_SOURCES) [HAVE_MAGICKXX]: Build `iz' only if + Magick++ is available. + (iz_output.ppm) [HAVE_MAGICKXX]: Likewise. + (iz_CPPFLAGS, iz_LDFLAGS) [HAVE_MAGICKXX]: New. + (tmp_iz.avi) [HAVE_MAGICKXX]: New target. + (MOSTLYCLEANFILES): Add tmp_iz??????.png. + 2012-06-20 Roland Levillain <roland@lrde.epita.fr> Add rules to build and run apps/morphers/iz. diff --git a/milena/apps/morphers/Makefile.am b/milena/apps/morphers/Makefile.am index fd5edda..829ba8a 100644 --- a/milena/apps/morphers/Makefile.am +++ b/milena/apps/morphers/Makefile.am @@ -28,8 +28,7 @@ noinst_PROGRAMS = \ recorder-bft \ recorder-wst \ mask+recorder \ - lazy_recorder \ - iz + lazy_recorder noinst_HEADERS = recorder.hh lazy_recorder.hh @@ -39,12 +38,22 @@ recorder_bft_SOURCES = recorder-bft.cc image2d-skel.hh recorder_wst_SOURCES = recorder-wst.cc mask_recorder_SOURCES = mask+recorder.cc lazy_recorder_SOURCES = lazy_recorder.cc -iz_SOURCES = iz.cc EXTRA_DIST = iz_input.pbm + +if HAVE_MAGICKXX +noinst_PROGRAMS += iz +iz_SOURCES = iz.cc +iz_CPPFLAGS = $(AM_CPPFLAGS) $(MAGICKXX_CPPFLAGS) +iz_LDFLAGS = $(AM_LDFLAGS) $(MAGICKXX_LDFLAGS) + # This target is phony: `iz' never writes `iz_output.ppm' actually. iz_output.ppm: iz$(EXEEXT) iz_input.pbm ./$< $(srcdir)/iz_input.pbm $@ +# Likewise, the dependency of this target is a (wrong) shortcut. +tmp_iz.avi: iz_output.ppm + mencoder "mf://tmp_iz*.png" -o tmp_iz.avi -ovc lavc -lavcopts vcodec=mjpeg -speed 10 +endif HAVE_MAGICKXX MOSTLYCLEANFILES = \ lena-mask-channel.ppm \ @@ -59,6 +68,7 @@ MOSTLYCLEANFILES = \ tmp_ws.ppm \ tmp_lab.pgm \ tmp_iz.pgm \ + tmp_iz??????.png \ tmp_iz.ppm \ tmp_iz_input.ppm diff --git a/milena/apps/morphers/iz.cc b/milena/apps/morphers/iz.cc index d02fd40..729b2f9 100644 --- a/milena/apps/morphers/iz.cc +++ b/milena/apps/morphers/iz.cc @@ -24,14 +24,40 @@ #include <mln/make/w_window2d.hh> +#include "apps/morphers/lazy_recorder.hh" + #include <mln/io/pbm/load.hh> #include <mln/io/pbm/save.hh> #include <mln/io/pgm/save.hh> #include <mln/io/ppm/save.hh> +#include <mln/io/magick/save.hh> #include <mln/literal/colors.hh> +// Save as PNG directly, instead of using PPM as intermediate format. +template <typename I> +inline +void +save_colorized(const mln::decorated_image< I, lazy_recorder<I> >& rec, + const std::string& prefix) +{ + mln_concrete(I) frame = mln::duplicate(rec.decoration().initial); + for (size_t i = 0; i < rec.decoration().sequence.size(); ++i) + { + std::stringstream s; + s << std::setfill ('0') << std::setw (6) << i; + mln::io::magick::save(mln::labeling::colorize(mln::value::rgb8(), frame), + prefix + s.str() + ".png"); + // Apply the I-th change to the next frame. + // + // Changes are applied after the I-th image has been written, + // to mimic the behavior of the original recorder morpher (see + // recorder.hh). + frame(rec.decoration().sequence[i].first) = + rec.decoration().sequence[i].second; + } +} void usage(char* argv[]) @@ -43,6 +69,9 @@ void usage(char* argv[]) int main(int argc, char* argv[]) { + // Initialize Magick++. + Magick::InitializeMagick(*argv); + using namespace mln; using value::int_u8; @@ -112,15 +141,25 @@ int main(int argc, char* argv[]) 0, c4(), nlabels), lab); + decorated_image< image2d<unsigned>, + lazy_recorder< image2d<unsigned> > > rec_lab = + lazy_record(lab); + io::pgm::save(data::saturate(value::int_u8(), lab), "tmp_lab.pgm"); - data::paste(transform::influence_zone_front(lab | (pw::value(ws) == pw::cst(0)), - c8(), - make::w_window2d(ww)), - lab); + image_if< decorated_image< image2d<unsigned int>, + lazy_recorder< image2d<unsigned int> > >, + fun::eq_v2b_expr_< pw::value_< image2d<unsigned int> >, + pw::cst_<int> > > rec_iz = + transform::influence_zone_front(rec_lab | (pw::value(ws) == pw::cst(0)), + c8(), + make::w_window2d(ww)); + data::paste(rec_iz, lab); io::pgm::save(data::saturate(value::int_u8(), lab), "tmp_iz.pgm"); + save_colorized(rec_iz.unmorph_(), "tmp_iz"); + image2d<value::rgb8> output = labeling::colorize(value::rgb8(), lab); io::ppm::save(output, "tmp_iz.ppm"); -- 1.7.2.5