URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-05-15 Etienne FOLIO <folio(a)lrde.epita.fr>
Big cleanup.
* Makefile: Remove. Not needed.
* README: New explainations.
* configure: To build the Makefile.
* dilation-n.hh: New algorithm.
* erosion-n.hh: New algorithm.
* main_dilation-n.cc: New test file.
* morpho.cc: Cleanup in here.
* treat.sh: Adaptation.
---
README | 16 +++++
configure | 23 -------
dilation-n.hh | 41 ++++++++++++++
erosion-n.hh | 41 ++++++++++++++
main_dilation-n.cc | 54 ++++++++++++++++++
morpho.cc | 153 +++++++++++++++++++++--------------------------------
treat.sh | 35 ++----------
7 files changed, 224 insertions(+), 139 deletions(-)
Index: trunk/milena/sandbox/inim/2010/morpho/Makefile (deleted)
===================================================================
Index: trunk/milena/sandbox/inim/2010/morpho/configure
===================================================================
--- trunk/milena/sandbox/inim/2010/morpho/configure (revision 3845)
+++ trunk/milena/sandbox/inim/2010/morpho/configure (revision 3846)
@@ -1,34 +1,17 @@
#! /bin/bash
-
-
if [ "$1" = "--debug" ]; then
-
DEBUG_FLAGS=" -g -ggdb "
OPT_FLAGS=""
else
-
OPT_FLAGS=" -DNDEBUG -O3 "
DEBUG_FLAGS=""
fi
-
-
-if [ "$2" = "--duma" ]; then
- LIB_PATH="-L/lrde/beyrouth/lrde-2011/da-mota/utils/duma "
- LIB=" -lduma "
-else
- LIB_PATH=" "
- LIB=" "
-fi
-
-
-CXXFLAGS="-Wall -Wextra -W -Werror -pedantic "
-
+CXXFLAGS="-Wall -Wextra -W -pedantic "
echo -n ' => Generating Makefile... '
-
echo 'CXX=g++' > Makefile
echo 'CXXFLAGS='${CXXFLAGS} >> Makefile
echo '' >> Makefile
@@ -57,8 +40,6 @@
echo '' >> Makefile
echo '' >> Makefile
echo '%.o: %.cc' >> Makefile
-echo ' $(CXX) $(CXXFLAGS) ' -I/work/$USER/milena '-c $< -o $@'
>> Makefile
+echo ' $(CXX) $(CXXFLAGS) ' -I../../../../ '-c $< -o $@' >>
Makefile
echo '' >> Makefile
-
-
echo ' [DONE]'
\ No newline at end of file
Index: trunk/milena/sandbox/inim/2010/morpho/main_dilation-n.cc
===================================================================
--- trunk/milena/sandbox/inim/2010/morpho/main_dilation-n.cc (revision 0)
+++ trunk/milena/sandbox/inim/2010/morpho/main_dilation-n.cc (revision 3846)
@@ -0,0 +1,54 @@
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <mln/debug/println.hh>
+#include <mln/data/fill.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/level/convert.hh>
+#include <mln/level/stretch.hh>
+
+#include <mln/core/alias/window2d.hh>
+
+#include "dilation-n.hh"
+#include "erosion-n.hh"
+
+int main(int argc, char** argv)
+{
+ using namespace mln;
+
+ // check arguments
+ if (argc != 5)
+ {
+ std::cerr << "Usage:" << std::endl
+ << " ./a.out <in.pbm> <out.pbm> <k>
<lambda>" << std::endl;
+ exit(1);
+ }
+
+ // build test image
+ std::cout << " => loading " << argv[1] <<
"..." << std::endl;
+ image2d<bool> in;
+ io::pbm::load(in, argv[1]);
+
+ value::int_u8 k = 1;
+ image2d<value::int_u8> ima = level::convert(k, in);
+ ima = level::stretch(k, ima);
+
+ std::cout << " => create window..." << std::endl;
+ window2d it;
+ it.insert(0, 0);
+ for (unsigned i = 1; i <= atoi(argv[3]); ++i)
+ {
+ it.insert(0, -i);
+ it.insert(0, i);
+ }
+
+ std::cout << " => applying dilation..." << std::endl;
+ image2d<value::int_u8> out;
+ out = morpho::erosion_n(ima, it, atoi(argv[4]));
+
+ std::cout << " => saving " << argv[2] <<
"..." << std::endl;
+ io::pgm::save(out, argv[2]);
+}
Index: trunk/milena/sandbox/inim/2010/morpho/erosion-n.hh
===================================================================
--- trunk/milena/sandbox/inim/2010/morpho/erosion-n.hh (revision 0)
+++ trunk/milena/sandbox/inim/2010/morpho/erosion-n.hh (revision 3846)
@@ -0,0 +1,41 @@
+#include <mln/core/concept/image.hh>
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ template <typename I, typename W>
+ inline
+ I
+ erosion_n(const Image<I>& ima_,
+ const W& win,
+ const unsigned lambda)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ I out;
+ initialize(out, ima);
+
+ mln_piter(I) p(ima.domain());
+ mln_qiter(W) q(win, p);
+
+ for_all(p)
+ {
+ unsigned i = 0;
+ for_all(q)
+ if (ima.has(q) && ima(q) != mln_max(mln_value(I)))
+ ++i;
+
+ out(p) = (i >= lambda)
+ ? mln_min(mln_value(I))
+ : ima(p);
+ }
+
+ return out;
+ }
+
+ }
+}
Index: trunk/milena/sandbox/inim/2010/morpho/morpho.cc
===================================================================
--- trunk/milena/sandbox/inim/2010/morpho/morpho.cc (revision 3845)
+++ trunk/milena/sandbox/inim/2010/morpho/morpho.cc (revision 3846)
@@ -1,124 +1,93 @@
#include <iostream>
#include <sstream>
#include <string>
-#include <mln/debug/println.hh>
+#include <mln/arith/revert.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/alias/window2d.hh>
#include <mln/io/pbm/load.hh>
#include <mln/io/pgm/save.hh>
-
-
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/accu/max.hh>
-#include <mln/value/label_8.hh>
#include <mln/labeling/regional_maxima.hh>
-#include <mln/data/fill.hh>
-#include <mln/literal/all.hh>
-#include <mln/arith/revert.hh>
#include <mln/level/convert.hh>
#include <mln/level/stretch.hh>
-#include <mln/morpho/closing/structural.hh>
-#include <mln/core/alias/window2d.hh>
-#include <mln/make/win_chamfer.hh>
#include <mln/linear/gaussian.hh>
-
#include <mln/morpho/rank_filter.hh>
+#include <mln/value/label_8.hh>
using namespace mln;
using namespace mln::value;
void
-load_img(image2d<bool>& in, const char* filename)
+load_img(image2d<int_u8>& ima, const char* filename)
{
- using namespace mln;
-
- // build test image
- std::cout << " => loading " << filename <<
"...";
+ std::cout << " => loadimag " << filename <<
"...";
std::cout.flush();
+
+ // load.
+ image2d<bool> in;
io::pbm::load(in, filename);
+
+ // convert and stretch.
+ int_u8 k = 1;
+ ima = level::convert(k, in);
+ ima = level::stretch(k, ima);
+
std::cout << "................[DONE]" << std::endl;
}
-
void
-revert_img(image2d<int_u8>& out,
- const image2d<bool>& in)
+revert_img(image2d<int_u8>& ima)
{
- using namespace mln;
-
- int_u8 k = 1;
- out = level::convert(k, in);
- out = level::stretch(k, out);
-
std::cout << " => revert image...";
std::cout.flush();
- out = arith::revert(out);
- std::cout << "...................[DONE]" << std::endl;
+ // revert.
+ ima = arith::revert(ima);
+ std::cout << "...................[DONE]" << std::endl;
}
-
-
-
void
-gaussian_filter(image2d<int_u8>& out, int gaussian_force)
+gaussian_filter(image2d<int_u8>& ima, float gaussian_force)
{
- using namespace mln;
-
std::cout << " => applying gaussian filter...";
std::cout.flush();
- out = linear::gaussian(out, gaussian_force, 1);
- // out = linear::gaussian_1st_derivative(out, gaussian_force, 1);
+
+ // gaussian filter.
+ ima = linear::gaussian(ima, gaussian_force, 1);
std::cout << ".......[DONE]" << std::endl;
}
-
-
-
-
-
-image2d<int_u8>
-rank_filter(const image2d<int_u8>& out,
- window2d it, int k, unsigned int lambda)
+void
+rank_filter(image2d<int_u8>& ima,
+ const window2d& it,
+ const unsigned k,
+ const unsigned lambda)
{
- using namespace mln;
-
std::cout << " => applying rank k filter...";
std::cout.flush();
- image2d<int_u8> rank_filtered = morpho::rank_filter(out, it, k);
+ // rank filter.
+ ima = morpho::rank_filter(ima, it, k);
- for (unsigned int y = 0; y <= rank_filtered.ncols () - 1; ++y)
- for (unsigned int x = 0; x <= rank_filtered.nrows() - 1; ++x)
- {
- if (rank_filtered(point2d(x, y)) < lambda)
- rank_filtered(point2d(x, y)) = 0;
+ mln_fwd_piter_(image2d<int_u8>) p(ima.domain());
+ for_all(p)
+ if (ima(p) < lambda)
+ ima(p) = mln_min(int_u8);
else
- rank_filtered(point2d(x, y)) = 255;
- }
+ ima(p) = mln_max(int_u8);
std::cout << ".........[DONE]" << std::endl;
-
- return rank_filtered;
}
-
-
-
-
void
-look_for_lines(const image2d<label_8>& labels, image2d<int_u8>& ima)
+replace_with_labels(const image2d<label_8>& labels, image2d<int_u8>&
ima)
{
mln_fwd_piter_(image2d<int_u8>) p(ima.domain());
for_all(p)
- {
if (ima(p) == mln_max(int_u8))
- {
- ima(p) = labels(p);
- }
- }
+ ima(p) = labels(p); // replace with label at p.
}
-
int
main(int argc, char** argv)
{
@@ -126,46 +95,50 @@
if (argc != 7)
{
std::cerr << "Usage:" << std::endl
- << " ./morpho <in.pbm> <gaussian_force> <k> "
+ << " ./morpho <ima.pbm> <gaussian_force> <k> "
<< "<window_width> <lambda> "
- << "<output_filename>" << std::endl;
+ << "<input_filename>" << std::endl;
exit(1);
}
+ // get argv variables.
const char* input_filename = argv[1];
- float gaussian_force = atof(argv[2]);
-
- unsigned int k = atoi(argv[3]);
- unsigned int w_width = atoi(argv[4]);
- unsigned int lambda = atoi(argv[5]);
+ const float gaussian_force = atof(argv[2]);
+ const unsigned k = atoi(argv[3]);
+ const unsigned w_width = atoi(argv[4]);
+ const unsigned lambda = atoi(argv[5]);
const char* output_filename = argv[6];
+ // load and revert image.
+ image2d<int_u8> ima;
+ load_img(ima, input_filename);
+ image2d<int_u8> in(ima);
+ //revert_img(ima);
+ io::pgm::save(ima, "1.pgm");
+
+ // apply gaussian filter.
+ gaussian_filter(ima, gaussian_force);
+ io::pgm::save(ima, "2.pgm");
- image2d<bool> in;
- load_img(in, input_filename);
-
- int_u8 i = 1;
- image2d<int_u8> in_u8 = level::convert(i, in);
- in_u8 = level::stretch(i, in_u8);
-
- image2d<int_u8> out = in_u8;
- gaussian_filter(out, gaussian_force);
-
+ // create window.
window2d window;
window.insert(0, 0);
-
for (unsigned i = 1; i <= w_width; ++i)
{
window.insert(0, -i);
window.insert(0, i);
}
- image2d<int_u8> ima =
- rank_filter(out, window, k, lambda);
+ // apply k-rank filter.
+ rank_filter(ima, window, k, lambda);
+ io::pgm::save(ima, "3.pgm");
+ // labelize.
label_8 nlabels = 0;
image2d<label_8> labels = labeling::regional_maxima(ima, c4(), nlabels);
+ io::pgm::save(labels, "4.pgm");
- look_for_lines(labels, in_u8);
- io::pgm::save(in_u8, output_filename);
+ // compute output image.
+ replace_with_labels(labels, in);
+ io::pgm::save(in, output_filename);
}
Index: trunk/milena/sandbox/inim/2010/morpho/treat.sh
===================================================================
--- trunk/milena/sandbox/inim/2010/morpho/treat.sh (revision 3845)
+++ trunk/milena/sandbox/inim/2010/morpho/treat.sh (revision 3846)
@@ -1,42 +1,21 @@
#!/bin/sh
-
-
gaussian_force=20 # best with values around 20
k=5 # best with values in [|1..10|]
window_width=20 # best with small values in [|10..30|]
lambda=5 # best with small values like 5-10
-OUTPUT_DIR=output
-
-if [ $# -eq 0 ]
+if [ $# -ne 2 ]
then
+ echo "Usage: ./run.sh <input_image.pbm> <output_image.pgm>"
+ exit 1
+fi
- echo -n 'Cleaning output directory........'
- rm -f /lrde/beyrouth/lrde-2011/da-mota/images_INIM/result/*
- echo '......[DONE]'
-
- mkdir -p ${OUTPUT_DIR}
-
- for filename in `echo *.pbm`
- do
- output_filename=${OUTPUT_DIR}/${filename}
-
- ~/morpho/morpho \
- ${filename} \
+./morpho \
+ $1 \
${gaussian_force} \
${k} \
${window_width} \
${lambda} \
- ${output_filename} \
+ $2 \
|| exit $?
-
- done
-
-fi
-
-
-for i in `ls ${OUTPUT_DIR}/*.pbm`
-do
- display $i
-done
Index: trunk/milena/sandbox/inim/2010/morpho/dilation-n.hh
===================================================================
--- trunk/milena/sandbox/inim/2010/morpho/dilation-n.hh (revision 0)
+++ trunk/milena/sandbox/inim/2010/morpho/dilation-n.hh (revision 3846)
@@ -0,0 +1,41 @@
+#include <mln/core/concept/image.hh>
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ template <typename I, typename W>
+ inline
+ I
+ dilation_n(const Image<I>& ima_,
+ const W& win,
+ const unsigned lambda)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ I out;
+ initialize(out, ima);
+
+ mln_piter(I) p(ima.domain());
+ mln_qiter(W) q(win, p);
+
+ for_all(p)
+ {
+ unsigned i = 0;
+ for_all(q)
+ if (ima.has(q) && ima(q) != mln_min(mln_value(I)))
+ ++i;
+
+ out(p) = (i >= lambda)
+ ? mln_max(mln_value(I))
+ : ima(p);
+ }
+
+ return out;
+ }
+
+ }
+}
Index: trunk/milena/sandbox/inim/2010/morpho/README
===================================================================
--- trunk/milena/sandbox/inim/2010/morpho/README (revision 0)
+++ trunk/milena/sandbox/inim/2010/morpho/README (revision 3846)
@@ -0,0 +1,16 @@
+== Dilation and erosion==
+
+Dilation and erosion: how to make a k-rank filter when it already exists:
+
+We developed those algorithms in erosion-n.hh and dilation-n.hh.
+You can test those by running main_dilation-n.cc.
+
+
+== Main morpho work ==
+
+The code is located in morpho.cc. You can run it by following those steps:
+- type ./configure in the shell
+- then make
+- then ./run.sh <input_image.pbm> <output_image.pgm>
+
+You can customize the input variables by editing the run.sh script.