* green/tools/annotating/histo/histo.cc: Manage new inputs/outputs.
* green/tools/annotating/opening/opening.cc: Manage new inputs/outputs.
* green/tools/annotating/iz/Makefile.am: New Makefile.
* green/tools/annotating/iz/iz.cc: New file.
* green/tools/annotating/regmax/regmax.cc: Manage new inputs/outputs.
---
milena/sandbox/ChangeLog | 10 +
.../sandbox/green/tools/annotating/histo/histo.cc | 84 +++--
.../tools/annotating/{histo => iz}/Makefile.am | 0
milena/sandbox/green/tools/annotating/iz/iz.cc | 373 ++++++++++++++++++++
.../green/tools/annotating/opening/opening.cc | 76 +++--
.../green/tools/annotating/regmax/regmax.cc | 253 ++++++++++++--
6 files changed, 714 insertions(+), 82 deletions(-)
copy milena/sandbox/green/tools/annotating/{histo => iz}/Makefile.am (100%)
create mode 100644 milena/sandbox/green/tools/annotating/iz/iz.cc
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index f56ea7a..861e635 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -75,6 +75,16 @@
* bin/pgm_to_pbm.cc,
* bin/ppm_negate.cc: New.
+2010-02-10 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
+ Fix last details in the image processing chain.
+
+ * green/tools/annotating/histo/histo.cc: Manage new inputs/outputs.
+ * green/tools/annotating/opening/opening.cc: Manage new inputs/outputs.
+ * green/tools/annotating/iz/Makefile.am: New Makefile.
+ * green/tools/annotating/iz/iz.cc: New file.
+ * green/tools/annotating/regmax/regmax.cc: Manage new inputs/outputs.
+
2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
Extend the histogram visualization tools for new projection concept.
diff --git a/milena/sandbox/green/tools/annotating/histo/histo.cc
b/milena/sandbox/green/tools/annotating/histo/histo.cc
index ab0b8af..8037e1a 100644
--- a/milena/sandbox/green/tools/annotating/histo/histo.cc
+++ b/milena/sandbox/green/tools/annotating/histo/histo.cc
@@ -16,14 +16,14 @@
#include <mln/fun/v2v/rgb8_to_rgbn.hh>
-#include <mln/io/dump/save.hh>
#include <mln/io/pbm/load.hh>
-#include <mln/io/pbm/save.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
#include <mln/io/ppm/load.hh>
+#include <mln/io/dump/save.hh>
+#include <mln/io/pgm/save.hh>
#include <mln/io/ppm/save.hh>
+#include <mln/literal/colors.hh>
+
#include <mln/opt/at.hh>
#include <mln/pw/value.hh>
@@ -33,15 +33,19 @@
template <unsigned n>
-void mk_histo(const std::string& input,
- const std::string& output,
- const std::string& histo,
- const std::string& mask)
+void mk_histo(const std::string& input, // in
+ const std::string& quant, // in
+ const std::string& histo, // out
+ const std::string& proj1, // out
+ const std::string& proj2, // out
+ const std::string& mask) // [in]
{
typedef mln::value::int_u8 t_int_u8;
+ typedef mln::value::int_u<n> t_int_un;
typedef mln::value::rgb8 t_rgb8;
typedef mln::value::rgb<n> t_rgbn;
typedef mln::image2d<t_int_u8> t_image2d_int_u8;
+ typedef mln::image2d<t_int_un> t_image2d_int_un;
typedef mln::image2d<t_rgb8> t_image2d_rgb8;
typedef mln::image2d<t_rgbn> t_image2d_rgbn;
typedef mln::image2d<bool> t_image2d_bool;
@@ -54,7 +58,9 @@ void mk_histo(const std::string& input,
t_image2d_rgbn i1_input; // input rgbn
t_image2d_bool m0_input; // mask input
t_histo3d h1_input; // histo input
- t_image2d_int_u8 p1_histo; // histo proj
+ t_image2d_int_u8 p1_histo1;// histo proj1
+ t_image2d_rgbn p1_histo2;// histo proj2
+ t_rgbn red(mln::literal::red);
mln::io::ppm::load(i0_input, input.c_str());
i1_input = mln::data::transform(i0_input, t_rgb8_to_rgbn());
@@ -72,9 +78,13 @@ void mk_histo(const std::string& input,
// END OF IMAGE PROCESSING CHAIN
// BEGIN DUMPING
- p1_histo = mln::display::display_histo3d_unsigned(h1_input);
+ p1_histo1 = mln::display::display_histo3d_unsigned(h1_input);
+ p1_histo2 = mln::display::display3_histo3d_unsigned(h1_input, red);
+
+ mln::io::ppm::save(i1_input, quant.c_str());
mln::io::dump::save(h1_input, histo.c_str());
- mln::io::pgm::save(p1_histo, output.c_str());
+ mln::io::pgm::save(p1_histo1, proj1.c_str());
+ mln::io::ppm::save(p1_histo2, proj2.c_str());
// END DUMPING
}
@@ -82,35 +92,47 @@ void mk_histo(const std::string& input,
void usage()
{
std::cout << std::endl;
- std::cout << "histo input.ppm q out.ppm histo.dump [msk.pbm]"
<< std::endl;
- std::cout << "where"
<< std::endl;
- std::cout << "input.ppm is the 8 bits color ppm image"
<< std::endl;
- std::cout << "q is the degree of quanification {2,3,4,5,6,7,8}"
<< std::endl;
- std::cout << "out.pgm is the r/g projection of the histogram"
<< std::endl;
- std::cout << "out.dump is the quantified color histogram"
<< std::endl;
- std::cout << "msk.pbm is the mask which select the pixels"
<< std::endl;
+ std::cout << "histo input.ppm q quant.ppm histo.dump proj.pgm"
+ << " proj.ppm [msk.pbm]" <<
std::endl;
+ std::cout << std::endl;
+ std::cout << "where :"
<< std::endl;
+ std::cout << "* [ in] input.ppm is the 8 bits color ppm image"
<< std::endl;
+ std::cout << "* [ in] q is the degree of quantification"
+ << " {2,3,4,5,6,7,8}" <<
std::endl;
+ std::cout << "* [out] quant.ppm is the q bits quantified input"
+ << " image" <<
std::endl;
+ std::cout << "* [out] histo.dump is the quantified color"
+ << " histogram" <<
std::endl;
+ std::cout << "* [out] proj.pgm is the r/g projection of the"
+ << " histogram (summing along the blue axe)" <<
std::endl;
+ std::cout << "* [out] proj.ppm is the r/g projection of the"
+ << " histogram with maxima plot on" <<
std::endl;
+ std::cout << "* [ in] msk.pbm is the mask which selects the"
+ << " pixels" <<
std::endl;
std::cout << std::endl;
}
int main(int argc, char* args[])
{
- if (5 == argc || 6 == argc)
+ if (7 == argc || 8 == argc)
{
- const std::string input(args[1]);
- const char q = args[2][0];
- const std::string output(args[3]);
- const std::string histo(args[4]);
- const std::string mask(6 == argc? args[5] : "");
+ const std::string input(args[1]); // in
+ const char q = args[2][0]; // in
+ const std::string quant(args[3]); // out
+ const std::string histo(args[4]); // out
+ const std::string proj1(args[5]); // out
+ const std::string proj2(args[6]); // out
+ const std::string mask(8 == argc? args[7] : ""); // [in]
switch(q)
{
- case '2': mk_histo<2>(input, output, histo, mask); break;
- case '3': mk_histo<3>(input, output, histo, mask); break;
- case '4': mk_histo<4>(input, output, histo, mask); break;
- case '5': mk_histo<5>(input, output, histo, mask); break;
- case '6': mk_histo<6>(input, output, histo, mask); break;
- case '7': mk_histo<7>(input, output, histo, mask); break;
- case '8': mk_histo<8>(input, output, histo, mask); break;
+ case '2': mk_histo<2>(input, quant, histo, proj1, proj2, mask);
break;
+ case '3': mk_histo<3>(input, quant, histo, proj1, proj2, mask);
break;
+ case '4': mk_histo<4>(input, quant, histo, proj1, proj2, mask);
break;
+ case '5': mk_histo<5>(input, quant, histo, proj1, proj2, mask);
break;
+ case '6': mk_histo<6>(input, quant, histo, proj1, proj2, mask);
break;
+ case '7': mk_histo<7>(input, quant, histo, proj1, proj2, mask);
break;
+ case '8': mk_histo<8>(input, quant, histo, proj1, proj2, mask);
break;
default: usage(); break;
}
}
diff --git a/milena/sandbox/green/tools/annotating/histo/Makefile.am
b/milena/sandbox/green/tools/annotating/iz/Makefile.am
similarity index 100%
copy from milena/sandbox/green/tools/annotating/histo/Makefile.am
copy to milena/sandbox/green/tools/annotating/iz/Makefile.am
diff --git a/milena/sandbox/green/tools/annotating/iz/iz.cc
b/milena/sandbox/green/tools/annotating/iz/iz.cc
new file mode 100644
index 0000000..07e5dd9
--- /dev/null
+++ b/milena/sandbox/green/tools/annotating/iz/iz.cc
@@ -0,0 +1,373 @@
+// TOOLS ==> influence zone transformation
+
+#include <iostream>
+#include <fstream>
+#include <boost/format.hpp>
+
+#include <mln/accu/stat/histo3d_rgb.hh>
+
+#include <mln/core/macros.hh>
+#include <mln/core/alias/neighb3d.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+
+#include <mln/data/compute.hh>
+
+#include <mln/display/display_histo.hh>
+
+#include <mln/io/dump/load.hh>
+#include <mln/io/dump/save.hh>
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/literal/colors.hh>
+
+#include <mln/labeling/compute.hh>
+#include <mln/labeling/mean_values.hh>
+
+#include <mln/transform/influence_zone_geodesic.hh>
+
+#include <mln/value/int_u8.hh>
+
+template <unsigned n>
+struct t_labeling_rgbn : mln::Function_v2v< t_labeling_rgbn<n> >
+{
+ typedef mln::value::rgb<n> t_rgbn;
+ typedef mln::value::label_8 t_lbl8;
+ typedef t_rgbn argument;
+ typedef t_lbl8 result;
+ typedef mln::image3d<t_lbl8> t_label;
+
+ const t_label& _label;
+
+ t_labeling_rgbn(const t_label& label) : _label(label) {}
+
+ result operator()(const argument& c) const
+ {
+ t_lbl8 tmp = mln::opt::at(_label, c.blue(), c.red(), c.green());
+
+ return tmp;
+ }
+};
+
+void compute_stats(const mln::image2d<mln::value::rgb8>& i_input_rgb8,
+ const mln::image2d<mln::value::label_8>& l_input_lbl8,
+ const mln::image3d<unsigned>& h_histo_rgbn,
+ const mln::image3d<mln::value::label_8>& l_histo_lbl8,
+ const mln::value::label_8& n_labels,
+ const std::string& log)
+{
+ typedef mln::algebra::vec<3,float> t_vec3f;
+ typedef mln::accu::math::sum<unsigned,unsigned> t_sum;
+ typedef mln::accu::stat::mean<t_vec3f,t_vec3f,t_vec3f> t_mean;
+ typedef mln::util::array<unsigned> t_count_array;
+ typedef mln::util::array<t_vec3f> t_mean_array;
+
+ mln::util::array<float> abs((unsigned)(n_labels)+1);
+ mln::util::array<float> rel((unsigned)(n_labels)+1);
+ unsigned nb = 0;
+
+ for (unsigned i = 0; i <= n_labels; ++i)
+ {
+ abs[i] = 0.0;
+ rel[i] = 0.0;
+ }
+
+ // COMPUTE THE SUM
+ t_count_array count = mln::labeling::compute(t_sum(),
+ h_histo_rgbn,
+ l_histo_lbl8,
+ n_labels);
+
+ // COMPUTE THE TOTAL
+ for (unsigned i = 0; i <= n_labels; ++i)
+ {
+ unsigned c = count[i];
+ nb += c;
+ }
+
+ // COMPUTE THE PERCENTAGES
+ for (unsigned i = 0; i <= n_labels; ++i)
+ if (0 < count[i])
+ {
+ abs[i] = ((float)count[i] / nb)*100.0;
+ rel[i] = ((float)count[i] / (nb - count[0]))*100.0;
+ }
+
+ // COMPUTE THE MEAN
+
+ t_mean_array mean = mln::labeling::compute(t_mean(),
+ i_input_rgb8,
+ l_input_lbl8,
+ n_labels);
+
+ // CORRECT 0 LABEL STATS
+ rel[0] = 0;
+ mean[0][0] = 255.0;
+ mean[0][1] = 255.0;
+ mean[0][2] = 0.0;
+
+ // PRINT STATS
+ std::ofstream log_stream(log.c_str());
+
+ for (unsigned i = 0; i <= n_labels; ++i)
+ {
+ const t_vec3f& mean_v = mean[i];
+
+ log_stream << boost::format("%2i|"
+ "r = %6.2f, g = %6.2f, b = %6.2f |"
+ "c = %7i, %%i = %5.2f, %%c = %5.2f")
+ % i
+ % mean_v[0]
+ % mean_v[1]
+ % mean_v[2]
+ % count[i]
+ % abs[i]
+ % rel[i]
+ << std::endl;
+ }
+
+ log_stream << std::endl << std::endl;
+ log_stream.flush();
+ log_stream.close();
+}
+
+bool expect(std::istream& stream, const std::string expected)
+{
+ bool result;
+ std::string got;
+
+ stream >> got;
+
+ result = (got == expected);
+
+ return result;
+}
+
+std::istream& operator>>(std::istream& stream,
+ mln::algebra::vec<3,float>& color)
+{
+ unsigned lbl;
+
+ stream >> lbl;
+ if (expect(stream, std::string("|")) &&
+ expect(stream, std::string("r")) &&
+ expect(stream, std::string("=")))
+ {
+ stream >> color[0];
+
+ if (expect(stream, std::string(",")) &&
+ expect(stream, std::string("g")) &&
+ expect(stream, std::string("=")))
+ {
+ stream >> color[1];
+
+ if (expect(stream, std::string(",")) &&
+ expect(stream, std::string("b")) &&
+ expect(stream, std::string("=")))
+ {
+ stream >> color[2];
+ }
+ }
+ }
+
+ return stream;
+}
+
+void load(mln::util::array< mln::algebra::vec<3,float> >& m2_label,
+ const char *colormap)
+{
+ typedef mln::algebra::vec<3,float> t_vec3f;
+ typedef mln::util::array<t_vec3f> t_mean_array;
+
+ std::ifstream stream(colormap);
+ std::string buffer;
+
+ getline(stream, buffer);
+
+ while (0 < buffer.size())
+ {
+ std::stringstream line(buffer);
+ t_vec3f mean_v;
+
+ line >> mean_v;
+
+ m2_label.append(mean_v);
+
+ getline(stream, buffer);
+ }
+
+ stream.close();
+}
+
+template<unsigned n>
+void mk_iz(const std::string& labeled, // in
+ const unsigned d, // in
+ const mln::neighb3d& nbh, // in
+ const std::string& input, // in
+ const std::string& quant, // in
+ const std::string& histo, // in
+ const std::string& colormap,// in
+ const std::string& iz, // out
+ const std::string& proj, // out
+ const std::string& mean, // out
+ const std::string& stats) // [out]
+{
+ typedef mln::value::int_u8 t_int_u8;
+ typedef mln::value::label_8 t_lbl8;
+ typedef mln::value::rgb8 t_rgb8;
+ typedef mln::value::rgb<n> t_rgbn;
+ typedef mln::algebra::vec<3,float> t_v3f;
+ typedef mln::image2d<t_int_u8> t_image2d_int_u8;
+ typedef mln::image2d<t_rgb8> t_image2d_rgb8;
+ typedef mln::image2d<t_rgbn> t_image2d_rgbn;
+ typedef mln::image2d<t_lbl8> t_image2d_lbl8;
+ typedef mln::image3d<unsigned> t_histo3d;
+ typedef mln::image3d<t_lbl8> t_image3d_lbl8;
+ typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun;
+ typedef mln::accu::stat::mean<t_v3f,t_v3f,t_v3f> t_mean;
+ typedef mln::util::array<t_v3f> t_mean_array;
+
+ // START OF IMAGE PROCESSING CHAIN
+ t_image2d_rgb8 i0_input; // input img
+ t_image2d_rgbn i1_input; // quant img
+ t_histo3d h1_input; // histo input
+ t_histo3d h2_input; // histo input
+ t_image2d_int_u8 p1_histo; // histo proj
+ t_image2d_rgb8 p3_histo; // histo proj
+ t_image3d_lbl8 l2_histo; // label histo
+ t_image3d_lbl8 l3_histo; // iz label hist
+ t_mean_array m2_label; // colormap
+ t_mean_array m3_label; // colormap
+ t_image2d_lbl8 l3_input; // label input
+ t_image2d_rgb8 i3_mean; // reconstructed
+
+ t_lbl8 n_lbl; // nb labels
+ t_rgb8 red(mln::literal::red);
+
+ mln::io::dump::load(l2_histo, labeled.c_str());
+ mln::io::ppm::load(i0_input, input.c_str());
+ mln::io::ppm::load(i1_input, quant.c_str());
+ mln::io::dump::load(h1_input, histo.c_str());
+ load(m2_label, colormap.c_str());
+
+ if (0 == d)
+ {
+ l3_histo = mln::transform::influence_zone_geodesic(l2_histo, nbh);
+ }
+ else
+ {
+ l3_histo = mln::transform::influence_zone_geodesic(l2_histo, nbh, d);
+ }
+ // END OF IMAGE PROCESSING CHAIN
+
+ // BEGIN DUMPING
+
+ n_lbl = (t_lbl8)(m2_label.size()-1);
+
+ l3_input = mln::data::transform(i1_input, t_labeling_rgbn<n>(l3_histo));
+ i3_mean = mln::labeling::mean_values(i0_input, l3_input, n_lbl);
+ m3_label = mln::labeling::compute(t_mean(), i0_input, l3_input, n_lbl);
+
+ // CORRECT 0 LABEL STATS
+ m3_label[0][0] = 255.0;
+ m3_label[0][1] = 255.0;
+ m3_label[0][2] = 0.0;
+
+ p3_histo = mln::display::display3_histo3d_unsigned<n>(h1_input,
+ l3_histo,
+ m3_label,
+ red);
+ mln::io::dump::save(l3_input, iz.c_str());
+ mln::io::ppm::save(p3_histo, proj.c_str());
+ mln::io::ppm::save(i3_mean, mean.c_str());
+
+ if (0 < stats.size())
+ compute_stats(i0_input, l3_input, h1_input, l3_histo, n_lbl, stats);
+
+ // END DUMPING
+}
+
+
+void usage()
+{
+ std::cout << std::endl;
+ std::cout << "iz labeled.dump d nbh input.ppm q quant.ppm"
+ << " histo.dump colormap.txt iz.dump proj.ppm"
+ << " mean.ppm [stats.txt]" <<
std::endl;
+ std::cout << std::endl;
+ std::cout << "where :"
<< std::endl;
+ std::cout << "* [ in] labeled.dump is the labeled 3d histogram"
<< std::endl;
+ std::cout << "* [ in] d is the depth for the zone influence"
+ << " transformation (0 means infinite)" <<
std::endl;
+ std::cout << "* [ in] nbh is the 3d neighbourhood {6,18,26}"
<< std::endl;
+ std::cout << "* [ in] input.ppm is the 8 bits color ppm image"
<< std::endl;
+ std::cout << "* [ in] q is the degree of quantification"
+ << " {2,3,4,5,6,7,8}" <<
std::endl;
+ std::cout << "* [ in] quant.ppm is the q bits quantified input"
+ << " image" <<
std::endl;
+ std::cout << "* [ in] histo.dump is the quantified color"
+ << " histogram" <<
std::endl;
+ std::cout << "* [ in] colormap.txt is the colormap for labels"
<< std::endl;
+ std::cout << "* [out] iz.dump is the iz labeled 3d histogram"
<< std::endl;
+ std::cout << "* [out] proj.ppm is the r/g projection of the"
+ << " histogram with maxima label plot on" <<
std::endl;
+ std::cout << "* [out] mean.ppm is the mean reconstructed image"
<< std::endl;
+ std::cout << "* [out] stats.txt is the statistical label
report"<< std::endl;
+ std::cout << std::endl;
+}
+
+int main(int argc, char* args[])
+{
+ if (12 == argc || 13 == argc)
+ {
+ const std::string labeled(args[1]); // in
+ const unsigned d = atoi(args[2]); // in
+ const char nbh = args[3][0]; // in
+ const std::string input(args[4]); // in
+ const char q = args[5][0]; // in
+ const std::string quant(args[6]); // in
+ const std::string histo(args[7]); // in
+ const std::string colormap(args[8]); // in
+ const std::string iz(args[9]); // out
+ const std::string proj(args[10]); // out
+ const std::string mean(args[11]); // out
+ const std::string stats(13 == argc? args[12] : ""); // [out]
+
+
+ mln::neighb3d neighbourhood;
+
+ switch (nbh)
+ {
+ case '6': neighbourhood = mln::c6(); break;
+ case '1': neighbourhood = mln::c18(); break;
+ case '2': neighbourhood = mln::c26(); break;
+ default: usage(); return 0; // force usage and quit
+ }
+
+ switch (q)
+ {
+ case '2' : mk_iz<2>(labeled,d,neighbourhood,input,quant,
+ histo,colormap,iz,proj,mean,stats);break;
+ case '3' : mk_iz<3>(labeled,d,neighbourhood,input,quant,
+ histo,colormap,iz,proj,mean,stats);break;
+ case '4' : mk_iz<4>(labeled,d,neighbourhood,input,quant,
+ histo,colormap,iz,proj,mean,stats);break;
+ case '5' : mk_iz<5>(labeled,d,neighbourhood,input,quant,
+ histo,colormap,iz,proj,mean,stats);break;
+ case '6' : mk_iz<6>(labeled,d,neighbourhood,input,quant,
+ histo,colormap,iz,proj,mean,stats);break;
+ case '7' : mk_iz<7>(labeled,d,neighbourhood,input,quant,
+ histo,colormap,iz,proj,mean,stats);break;
+ case '8' : mk_iz<8>(labeled,d,neighbourhood,input,quant,
+ histo,colormap,iz,proj,mean,stats);break;
+ default: usage(); break;
+ }
+ }
+ else
+ usage();
+
+ return 0;
+}
diff --git a/milena/sandbox/green/tools/annotating/opening/opening.cc
b/milena/sandbox/green/tools/annotating/opening/opening.cc
index 3e1dbf2..cdd37fb 100644
--- a/milena/sandbox/green/tools/annotating/opening/opening.cc
+++ b/milena/sandbox/green/tools/annotating/opening/opening.cc
@@ -15,36 +15,47 @@
#include <mln/io/dump/load.hh>
#include <mln/io/dump/save.hh>
-#include <mln/io/pgm/load.hh>
+#include <mln/io/ppm/save.hh>
#include <mln/io/pgm/save.hh>
+#include <mln/literal/colors.hh>
+
#include <mln/morpho/opening/volume.hh>
+#include <mln/value/rgb.hh>
#include <mln/value/int_u8.hh>
-void mk_opening(const std::string& input,
- const unsigned min_vol,
- const std::string& output,
- const std::string& opened)
+template <unsigned n>
+void mk_opening(const std::string& histo, // in
+ const unsigned min_vol, // in
+ const std::string& opened, // out
+ const std::string& proj1, // out
+ const std::string& proj2) // out
{
typedef mln::value::int_u8 t_int_u8;
+ typedef mln::value::rgb<n> t_rgbn;
typedef mln::image2d<t_int_u8> t_image2d_int_u8;
+ typedef mln::image2d<t_rgbn> t_image2d_rgbn;
typedef mln::image3d<unsigned> t_histo3d;
typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun;
// START OF IMAGE PROCESSING CHAIN
t_histo3d h1_input; // histo input
t_histo3d h2_input; // histo input
- t_image2d_int_u8 p1_histo; // histo proj
+ t_image2d_int_u8 p1_histo1;// histo proj1
+ t_image2d_rgbn p1_histo2;// histo proj2
+ t_rgbn red(mln::literal::red);
- mln::io::dump::load(h1_input, input.c_str());
+ mln::io::dump::load(h1_input, histo.c_str());
h2_input = mln::morpho::opening::volume(h1_input, mln::c6(), min_vol);
// END OF IMAGE PROCESSING CHAIN
// BEGIN DUMPING
- p1_histo = mln::display::display_histo3d_unsigned(h2_input);
+ p1_histo1 = mln::display::display_histo3d_unsigned(h2_input);
+ p1_histo2 = mln::display::display3_histo3d_unsigned(h2_input, red);
mln::io::dump::save(h2_input, opened.c_str());
- mln::io::pgm::save(p1_histo, output.c_str());
+ mln::io::pgm::save(p1_histo1, proj1.c_str());
+ mln::io::ppm::save(p1_histo2, proj2.c_str());
// END DUMPING
}
@@ -52,25 +63,46 @@ void mk_opening(const std::string& input,
void usage()
{
std::cout << std::endl;
- std::cout << "opening input.dump v out.dump out.ppm"
<< std::endl;
- std::cout << "where"
<< std::endl;
- std::cout << "input.dump is the 3d color input histo"
<< std::endl;
- std::cout << "v is the minimum size of each composant"
<< std::endl;
- std::cout << "out.pgm is the r/g proj of the opened histogram"
<< std::endl;
- std::cout << "out.dump is the opened histogram"
<< std::endl;
+ std::cout << "opening q histo.dump v opened.dump proj.pgm"
+ << " proj.ppm" <<
std::endl;
+ std::cout << std::endl;
+ std::cout << "where :"
<< std::endl;
+ std::cout << "* [ in] q is the degree of quantification"
+ << " {2,3,4,5,6,7,8}" <<
std::endl;
+ std::cout << "* [ in] histo.dump is the quantified color"
+ << " histogram" <<
std::endl;
+ std::cout << "* [ in] v is the minimum size (in pixels) of"
+ << " each composant" <<
std::endl;
+ std::cout << "* [out] opened.dump is the filtered histogram"
<< std::endl;
+ std::cout << "* [out] proj.pgm is the r/g projection of the"
+ << " histogram (summing along the blue axe)" <<
std::endl;
+ std::cout << "* [out] proj.ppm is the r/g projection of the"
+ << " histogram with maxima plot on" <<
std::endl;
std::cout << std::endl;
}
int main(int argc, char* args[])
{
- if (5 == argc)
+ if (7 == argc)
{
- const std::string input(args[1]);
- const unsigned min_vol = atoi(args[2]);
- const std::string output(args[3]);
- const std::string opened(args[4]);
-
- mk_opening(input, min_vol, output, opened);
+ const char q = args[1][0]; // in
+ const std::string histo(args[2]); // in
+ const unsigned min_vol = atoi(args[3]); // in
+ const std::string opened(args[4]); // out
+ const std::string proj1(args[5]); // out
+ const std::string proj2(args[6]); // out
+
+ switch(q)
+ {
+ case '2': mk_opening<2>(histo, min_vol, opened, proj1, proj2);
break;
+ case '3': mk_opening<3>(histo, min_vol, opened, proj1, proj2);
break;
+ case '4': mk_opening<4>(histo, min_vol, opened, proj1, proj2);
break;
+ case '5': mk_opening<5>(histo, min_vol, opened, proj1, proj2);
break;
+ case '6': mk_opening<6>(histo, min_vol, opened, proj1, proj2);
break;
+ case '7': mk_opening<7>(histo, min_vol, opened, proj1, proj2);
break;
+ case '8': mk_opening<8>(histo, min_vol, opened, proj1, proj2);
break;
+ default: usage(); break;
+ }
}
else
usage();
diff --git a/milena/sandbox/green/tools/annotating/regmax/regmax.cc
b/milena/sandbox/green/tools/annotating/regmax/regmax.cc
index 2079bc4..0ff4d2e 100644
--- a/milena/sandbox/green/tools/annotating/regmax/regmax.cc
+++ b/milena/sandbox/green/tools/annotating/regmax/regmax.cc
@@ -1,8 +1,13 @@
// TOOLS ==> regmax on histo
#include <iostream>
+#include <fstream>
+#include <boost/format.hpp>
#include <mln/accu/stat/histo3d_rgb.hh>
+#include <mln/accu/stat/mean.hh>
+
+#include <mln/algebra/vec.hh>
#include <mln/core/macros.hh>
#include <mln/core/alias/neighb3d.hh>
@@ -18,9 +23,14 @@
#include <mln/io/dump/save.hh>
#include <mln/io/pgm/load.hh>
#include <mln/io/pgm/save.hh>
+#include <mln/io/ppm/load.hh>
#include <mln/io/ppm/save.hh>
#include <mln/labeling/regional_maxima.hh>
+#include <mln/labeling/compute.hh>
+#include <mln/labeling/mean_values.hh>
+
+#include <mln/literal/colors.hh>
#include <mln/morpho/opening/volume.hh>
@@ -28,6 +38,8 @@
#include <mln/value/int_u8.hh>
#include <mln/value/rgb8.hh>
+#include <mln/util/array.hh>
+
template <unsigned n>
struct t_labeling_rgbn : mln::Function_v2v< t_labeling_rgbn<n> >
{
@@ -49,19 +61,134 @@ struct t_labeling_rgbn : mln::Function_v2v<
t_labeling_rgbn<n> >
}
};
-void mk_regmax(const std::string& input,
- const std::string& quant,
- const std::string& histo,
- const std::string& label,
- const std::string& output)
+void compute_stats(const mln::image2d<mln::value::rgb8>& i_input_rgb8,
+ const mln::image2d<mln::value::label_8>& l_input_lbl8,
+ const mln::image3d<unsigned>& h_histo_rgbn,
+ const mln::image3d<mln::value::label_8>& l_histo_lbl8,
+ const mln::value::label_8& n_labels,
+ const std::string& log)
+{
+ typedef mln::algebra::vec<3,float> t_vec3f;
+ typedef mln::accu::math::sum<unsigned,unsigned> t_sum;
+ typedef mln::accu::stat::mean<t_vec3f,t_vec3f,t_vec3f> t_mean;
+ typedef mln::util::array<unsigned> t_count_array;
+ typedef mln::util::array<t_vec3f> t_mean_array;
+
+ mln::util::array<float> abs((unsigned)(n_labels)+1);
+ mln::util::array<float> rel((unsigned)(n_labels)+1);
+ unsigned nb = 0;
+
+ for (unsigned i = 0; i <= n_labels; ++i)
+ {
+ abs[i] = 0.0;
+ rel[i] = 0.0;
+ }
+
+ // COMPUTE THE SUM
+ t_count_array count = mln::labeling::compute(t_sum(),
+ h_histo_rgbn,
+ l_histo_lbl8,
+ n_labels);
+
+ // COMPUTE THE TOTAL
+ for (unsigned i = 0; i <= n_labels; ++i)
+ {
+ unsigned c = count[i];
+ nb += c;
+ }
+
+ // COMPUTE THE PERCENTAGES
+ for (unsigned i = 0; i <= n_labels; ++i)
+ if (0 < count[i])
+ {
+ abs[i] = ((float)count[i] / nb)*100.0;
+ rel[i] = ((float)count[i] / (nb - count[0]))*100.0;
+ }
+
+ // COMPUTE THE MEAN
+
+ t_mean_array mean = mln::labeling::compute(t_mean(),
+ i_input_rgb8,
+ l_input_lbl8,
+ n_labels);
+
+ // CORRECT 0 LABEL STATS
+ rel[0] = 0;
+ mean[0][0] = 255.0;
+ mean[0][1] = 255.0;
+ mean[0][2] = 0.0;
+
+ // PRINT STATS
+ std::ofstream log_stream(log.c_str());
+
+ for (unsigned i = 0; i <= n_labels; ++i)
+ {
+ const t_vec3f& mean_v = mean[i];
+
+ log_stream << boost::format("%2i|"
+ "r = %6.2f, g = %6.2f, b = %6.2f |"
+ "c = %7i, %%i = %5.2f, %%c = %5.2f")
+ % i
+ % mean_v[0]
+ % mean_v[1]
+ % mean_v[2]
+ % count[i]
+ % abs[i]
+ % rel[i]
+ << std::endl;
+ }
+
+ log_stream << std::endl << std::endl;
+ log_stream.flush();
+ log_stream.close();
+}
+
+void save(mln::util::array< mln::algebra::vec<3,float> >& m2_label,
+ const char *colormap)
+{
+ typedef mln::algebra::vec<3,float> t_vec3f;
+ typedef mln::util::array<t_vec3f> t_mean_array;
+
+ std::ofstream stream(colormap);
+
+ for (unsigned i = 0; i < m2_label.size(); ++i)
+ {
+ const t_vec3f& mean_v = m2_label[i];
+
+ stream << boost::format("%2i | r = %6.2f, g = %6.2f, b = %6.2f")
+ % i
+ % mean_v[0]
+ % mean_v[1]
+ % mean_v[2]
+ << std::endl;
+ }
+
+ stream.flush();
+ stream.close();
+}
+
+template <unsigned n>
+void mk_regmax(const std::string& input, // in
+ const std::string& quant, // in
+ const std::string& histo, // in
+ const std::string& opened, // in
+ const mln::neighb3d& nbh, // in
+ const std::string& labeled, // out
+ const std::string& proj, // out
+ const std::string& colormap,// out
+ const std::string& mean, // out
+ const std::string& stats) // [out]
{
typedef mln::value::label_8 t_lbl8;
typedef mln::value::rgb8 t_rgb8;
- typedef mln::value::rgbn t_rgbn;
+ typedef mln::value::rgb<n> t_rgbn;
typedef mln::value::int_u8 t_int_u8;
+ typedef mln::value::int_u<n> t_int_un;
typedef mln::algebra::vec<3,float> t_v3f;
typedef mln::image2d<t_int_u8> t_image2d_int_u8;
+ typedef mln::image2d<t_int_un> t_image2d_int_un;
typedef mln::image2d<t_rgb8> t_image2d_rgb8;
+ typedef mln::image2d<t_rgbn> t_image2d_rgbn;
typedef mln::image3d<t_lbl8> t_image3d_lbl8;
typedef mln::image2d<t_lbl8> t_image2d_lbl8;
typedef mln::image3d<unsigned> t_histo3d;
@@ -71,60 +198,128 @@ void mk_regmax(const std::string& input,
t_image2d_rgb8 i0_input; // input img
t_image2d_rgbn i1_input; // quant img
+ t_histo3d h1_input; // input histo
t_histo3d h2_input; // opened histo
-// t_image2d_int_u8 p2_label; // histo proj
- t_image2d_lbl8 p2_label; // histo proj
-// t_image2d_rgb8 p2_label; // histo proj
+ t_image2d_rgb8 p2_label; // histo proj
t_image3d_lbl8 l2_histo; // label histo
- t_mean_array m2_label; // palette
+ t_image2d_lbl8 l2_input; // label input
+ t_mean_array m2_label; // colormap
+ t_image2d_rgb8 i2_mean; // reconstructed
t_lbl8 n_lbl; // nb class
+ t_rgb8 red(mln::literal::red);
+
// BEGIN LOADING
mln::io::ppm::load(i0_input, input.c_str());
mln::io::ppm::load(i1_input, quant.c_str());
- mln::io::dump::load(h2_input, histo.c_str());
+ mln::io::dump::load(h1_input, histo.c_str());
+ mln::io::dump::load(h2_input, opened.c_str());
// END LOADING
// BEGIN IMAGE PROCESSING
- l2_histo = mln::labeling::regional_maxima(h2_input, mln::c6(), n_lbl);
+ l2_histo = mln::labeling::regional_maxima(h2_input, nbh, n_lbl);
// END IMAGE PROCESSING
// BEGIN SAVING
- mln::debug::println(h2_input);
mln::io::dump::save(l2_histo, labeled.c_str());
l2_input = mln::data::transform(i1_input, t_labeling_rgbn<n>(l2_histo));
- m2_label = mln::labeling::compute(t_mean(), i0_input, l2_input, n_labels);
- p2_label =mln::display::display3_histo3d_unsigned(h2_input,l2_histo,m2_label);
+ i2_mean = mln::labeling::mean_values(i0_input, l2_input, n_lbl);
+ m2_label = mln::labeling::compute(t_mean(), i0_input, l2_input, n_lbl);
+
+ // CORRECT 0 LABEL STATS
+ m2_label[0][0] = 255.0;
+ m2_label[0][1] = 255.0;
+ m2_label[0][2] = 0.0;
+
+ p2_label =mln::display::display3_histo3d_unsigned<n>(h1_input,
+ l2_histo,
+ m2_label,
+ red);
+
+ mln::io::ppm::save(p2_label, proj.c_str());
+ save(m2_label, colormap.c_str());
+ mln::io::ppm::save(i2_mean, mean.c_str());
+
+ if (0 < stats.size())
+ compute_stats(i0_input, l2_input, h1_input, l2_histo, n_lbl, stats);
-// mln::io::pgm::save(p2_label, output.c_str());
- mln::io::ppm::save(p2_label, output.c_str());
- std::cout << "Nb classes : " << n_lbl << std::endl;
// END SAVING
}
-
void usage()
{
std::cout << std::endl;
- std::cout << "regmax input.dump out.dump out.ppm"
<< std::endl;
- std::cout << "where"
<< std::endl;
- std::cout << "input.dump is opened histo"
<< std::endl;
- std::cout << "out.pgm is the r/g proj of the opened histogram"
<< std::endl;
- std::cout << "out.dump is the labeled histogram"
<< std::endl;
+ std::cout << "regmax input.ppm q quant.ppm histo.dump"
+ << " opened.dump nbh labeled.dump proj.ppm"
+ << " colormap.txt mean.ppm [stats.txt]" <<
std::endl;
+ std::cout << std::endl;
+ std::cout << "where :"
<< std::endl;
+ std::cout << "* [ in] input.ppm is the 8 bits color ppm image"
<< std::endl;
+ std::cout << "* [ in] q is the degree of quantification"
+ << " {2,3,4,5,6,7,8}" <<
std::endl;
+ std::cout << "* [ in] quant.ppm is the q bits quantified input"
+ << " image" <<
std::endl;
+ std::cout << "* [ in] histo.dump is the quantified color"
+ << " histogram" <<
std::endl;
+ std::cout << "* [ in] opened.dump is the filtered histogram"
<< std::endl;
+ std::cout << "* [ in] nbh is the 3d neighbourhood {6,18,26}"
<< std::endl;
+ std::cout << "* [out] labeled.dump is the labeled 3d histogram"
<< std::endl;
+ std::cout << "* [out] proj.ppm is the r/g projection of the"
+ << " histogram with maxima label plot on" <<
std::endl;
+ std::cout << "* [out] colormap.txt is the colormap for labels"
<< std::endl;
+ std::cout << "* [out] mean.ppm is the mean reconstructed image"
<< std::endl;
+ std::cout << "* [out] stats.txt is the statistical label
report"<< std::endl;
std::cout << std::endl;
}
int main(int argc, char* args[])
{
- if (4 == argc)
+ if (11 == argc || 12 == argc)
{
- const std::string input(args[1]);
- const std::string output(args[2]);
- const std::string labeled(args[3]);
+ const std::string input(args[1]); // in
+ const char q = args[2][0]; // in
+ const std::string quant(args[3]); // in
+ const std::string histo(args[4]); // in
+ const std::string opened(args[5]); // in
+ const char nbh = args[6][0]; // in
+ const std::string labeled(args[7]); // out
+ const std::string proj(args[8]); // out
+ const std::string colormap(args[9]);// out
+ const std::string mean(args[10]); // out
+ const std::string stats(12 == argc? args[11] : ""); // [out]
+
+
+ mln::neighb3d neighbourhood;
+
+ switch (nbh)
+ {
+ case '6': neighbourhood = mln::c6(); break;
+ case '1': neighbourhood = mln::c18(); break;
+ case '2': neighbourhood = mln::c26(); break;
+ default: usage(); return 0; // force usage and quit
+ }
+
+ switch (q)
+ {
- mk_regmax(input, output, labeled);
+ case '2': mk_regmax<2>(input,quant,histo,opened,neighbourhood,
+ labeled,proj,colormap,mean,stats); break;
+ case '3': mk_regmax<3>(input,quant,histo,opened,neighbourhood,
+ labeled,proj,colormap,mean,stats); break;
+ case '4': mk_regmax<4>(input,quant,histo,opened,neighbourhood,
+ labeled,proj,colormap,mean,stats); break;
+ case '5': mk_regmax<5>(input,quant,histo,opened,neighbourhood,
+ labeled,proj,colormap,mean,stats); break;
+ case '6': mk_regmax<6>(input,quant,histo,opened,neighbourhood,
+ labeled,proj,colormap,mean,stats); break;
+ case '7': mk_regmax<7>(input,quant,histo,opened,neighbourhood,
+ labeled,proj,colormap,mean,stats); break;
+ case '8': mk_regmax<8>(input,quant,histo,opened,neighbourhood,
+ labeled,proj,colormap,mean,stats); break;
+ default: usage(); break;
+ }
}
else
usage();
--
1.5.6.5