Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Sandbox: ICP: 'lazy'_map.
* sandbox/jardonnet/test/icp.cc: Update.
* sandbox/jardonnet/test/reduce.cc: New: image scaling.
* sandbox/jardonnet/test/01.pbm,
* sandbox/jardonnet/test/02.pbm: New: test images.
* sandbox/jardonnet/registration/icp.hh: Use type lazy_map instead of std::pair, in order to use sp�cific constructors.
* sandbox/jardonnet/registration/projection.hh: update.
* sandbox/jardonnet/registration/tools.hh: Add tools for boxes (to include in Milena?).
registration/icp.hh | 25 +++++++++--------
registration/projection.hh | 27 ++++--------------
registration/tools.hh | 66 +++++++++++++++++++++++++++++++++++++++++++++
test/reduce.cc | 26 +++++++++++++++++
4 files changed, 113 insertions(+), 31 deletions(-)
Index: sandbox/jardonnet/test/icp.cc
Index: sandbox/jardonnet/test/reduce.cc
--- sandbox/jardonnet/test/reduce.cc (revision 0)
+++ sandbox/jardonnet/test/reduce.cc (revision 0)
@@ -0,0 +1,26 @@
+#include <mln/core/image2d.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pbm/save.hh>
+
+#include <mln/subsampling/subsampling.hh>
+
+
+int main(int argc, char*argv[])
+{
+ if (argc != 3)
+ {
+ std::cout << "usage : " << argv[0] << " in.pbm out.pbm" << std::endl;
+ }
+
+ using namespace mln;
+
+ image2d<bool> img;
+
+ io::pbm::load(img, argv[1]);
+
+ image2d<bool> output = subsampling::subsampling(img, make::dpoint2d(2,2), argc);
+
+ io::pbm::save(output, argv[2]);
+}
+
Index: sandbox/jardonnet/test/01.pbm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: sandbox/jardonnet/test/01.pbm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: sandbox/jardonnet/test/02.pbm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: sandbox/jardonnet/test/02.pbm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: sandbox/jardonnet/registration/icp.hh
--- sandbox/jardonnet/registration/icp.hh (revision 1815)
+++ sandbox/jardonnet/registration/icp.hh (working copy)
@@ -66,24 +66,24 @@
namespace impl
{
- template <typename P, typename T1, typename T2>
+ template <typename P, typename T>
inline
p_array<P>
icp_(p_array<P>& C,
const p_array<P>& X,
- std::pair<T1,T2>&)
+ lazy_map<T>& map)
{
trace::entering("registration::impl::icp_");
unsigned int k;
quat7<P::dim> old_qk, qk;
float err;
- float err_bis;
+ //float err_bis;
p_array<P> Ck(C), Xk(C); //FIXME: Xk copy C
algebra::vec<P::dim,float> mu_C = center(C), mu_Xk;
- const float epsilon = 1e-2;
+ const float epsilon = 1;//1e-3;
//// step 1
k = 0;
@@ -91,7 +91,7 @@
//// step 2
//err_bis = projection::fill_Xk(Ck, map, Xk);
//projection::de_base(Ck, X, Xk, err_bis);
- projection::memo(Ck, X, Xk, err_bis);
+ projection::memo(Ck, X, Xk, map);
mu_Xk = center(Xk);
@@ -104,12 +104,11 @@
//// err = d(Ck+1,Xk)
err = rms(Ck, Xk);
- std::cout << "error :" << err << std::endl;
+ std::cout << k << ' ' << err << std::endl; //plot file
++k;
} while (k < 3 || (qk - old_qk).sqr_norm() > epsilon);
- std::cout << "nb of iterations : " << k << std::endl;
trace::exiting("registration::impl::icp_");
return Ck;
}
@@ -120,8 +119,8 @@
//Only for 2d and 3d image
template <typename I, typename J>
inline
- mln_concrete(I)
- icp(Image<I>& cloud_,
+ mln_concrete(I) //FIXME: should return something else ? qk ?
+ icp(const Image<I>& cloud_,
const Image<J>& surface_)
{
trace::entering("registration::icp");
@@ -142,7 +141,7 @@
fun::cham<point3d> fun;
w_window<mln_dpoint(I3d), float> chamfer = make::w_window(win3d, fun);
*/
- std::pair<mln_ch_value(I3d,float), mln_ch_value(I3d,mln_point(I3d)) > maps;// =
+ //std::pair<mln_ch_value(I3d,float), mln_ch_value(I3d,mln_point(I3d)) > maps;// =
//dt::chamfer(surface, chamfer);
@@ -150,7 +149,11 @@
p_array<mln_point(I3d)> c = convert::to_p_array(cloud);
p_array<mln_point(I3d)> x = convert::to_p_array(surface);
- p_array<mln_point(I3d)> res = impl::icp_(c, x, maps);
+ //build closest point map
+ //lazy_map<I3d> map(enlarge(bigger(c.bbox(),x.bbox()),50));
+ lazy_map<I3d> map(1000,1000,50);
+
+ p_array<mln_point(I3d)> res = impl::icp_(c, x, map);
//to 2d : projection (FIXME:if 3d)
//mln_concrete(I) output = convert::to_image2d(res)?
Index: sandbox/jardonnet/registration/projection.hh
--- sandbox/jardonnet/registration/projection.hh (revision 1815)
+++ sandbox/jardonnet/registration/projection.hh (working copy)
@@ -67,27 +67,18 @@
}
- template <typename P>
- void memo(// input
- const p_array<P>& Ck,
+ template <typename P, typename T>
+ void memo(const p_array<P>& Ck,
const p_array<P>& X,
- // inout
p_array<P>& Xk,
- float& err)
+ lazy_map<T>& map) // first: closest points, second: is_computed
{
- //FIXME: remove static
- //FIXME: domain generated by X and C's domain?
- static image3d<point3d> map(1000,1000,10);
- static image3d<bool> mapset(1000,1000,10);
-
assert(Ck.npoints() == Xk.npoints());
- err = 0.f;
-
for (size_t i = 0; i < Ck.npoints(); ++i)
{
float best_d;
- if (mapset(Ck[i]) == false)
+ if (map.known(Ck[i]) == false)
{
algebra::vec<P::dim,float> Cki = Ck[i];
algebra::vec<P::dim,float> best_x = X[0];
@@ -103,16 +94,12 @@
}
}
Xk.hook_()[i] = algebra::to_point<P>(best_x);
- map(Ck[i]) = Xk[i];
- mapset(Ck[i]) = true;
+ map.map(Ck[i]) = Xk[i];
+ map.known(Ck[i]) = true;
}
else
- {
- Xk.hook_()[i] = map(Ck[i]);
- }
- err += best_d;
+ Xk.hook_()[i] = map.map(Ck[i]);
}
- err /= Ck.npoints();
}
} // end of namespace projection
Index: sandbox/jardonnet/registration/tools.hh
--- sandbox/jardonnet/registration/tools.hh (revision 1815)
+++ sandbox/jardonnet/registration/tools.hh (working copy)
@@ -6,9 +6,75 @@
# include <mln/algebra/mat.hh>
# include <mln/core/p_array.hh>
+
namespace mln
{
+
+ //FIXME: Shall we use something *really* lazy
+ template <typename I>
+ struct lazy_map
+ {
+ template <typename P>
+ lazy_map(const box_<P>& domain)
+ : map(domain), known(domain)
+ { }
+
+ lazy_map(int nrows, int ncols, int bdr = 3)
+ : map(nrows, ncols, bdr), known(nrows,ncols,bdr)
+ { }
+
+ mln_ch_value(I, mln_point(I)) map;
+ mln_ch_value(I, bool) known;
+ };
+
+
+ // Point
+
+ template <typename P>
+ P min(const P& a, const P& b)
+ {
+ if (a > b)
+ return b;
+ return a;
+ }
+
+ template <typename P>
+ P max(const P& a, const P& b)
+ {
+ if (a < b)
+ return b;
+ return a;
+ }
+
+
+ // Box
+
+ template <typename P>
+ inline
+ const box_<P>& //dif
+ enlarge(const box_<P>& box, unsigned b)
+ {
+ for (unsigned i = 0; i < P::dim; ++i)
+ {
+ box.pmin()[i] -= b;
+ box.pmax()[i] += b;
+ }
+ return box;
+ }
+
+ template <typename P>
+ box_<P> bigger(box_<P> a, box_<P> b)
+ {
+ P pmin,pmax;
+
+ pmin = min(a.pmin(), b.pmin());
+ pmax = max(a.pmax(), b.pmax());
+
+ return box_<P>(pmin, pmax);
+ }
+
+
//FIXME: move?
namespace convert
{
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Ugo Jardonnet <jardonnet(a)lrde.epita.fr>
Sandbox: ICP : projection::memo.
* sandbox/jardonnet/test/icp.cc: Update.
* sandbox/jardonnet/test/check: Test projection techniques.
* sandbox/jardonnet/TODO: Update.
* sandbox/jardonnet/registration/quat7.hh: Correction.
* sandbox/jardonnet/registration/cloud.hh: Correction.
* sandbox/jardonnet/registration/jacobi.hh: Add FIXME (nD).
* sandbox/jardonnet/registration/icp.hh: Improvment.
* sandbox/jardonnet/registration/projection.hh: Add a projection
technique "memo" computing closest point only if needed.
* sandbox/jardonnet/registration/tools.hh: Gather together tools to add
to milena.
mln/make/window3d.hh | 2
sandbox/jardonnet/TODO | 14 ++
sandbox/jardonnet/registration/cloud.hh | 4
sandbox/jardonnet/registration/icp.hh | 117
+++++++----------------
sandbox/jardonnet/registration/jacobi.hh | 2
sandbox/jardonnet/registration/projection.hh | 57 ++++++++++-
sandbox/jardonnet/registration/quat7.hh | 50 ++-------
sandbox/jardonnet/registration/tools.hh | 137
+++++++++++++++++++++++++++
sandbox/jardonnet/test/check | 13 ++
9 files changed, 273 insertions(+), 123 deletions(-)
Index: mln/make/window3d.hh
--- mln/make/window3d.hh (revision 1814)
+++ mln/make/window3d.hh (working copy)
@@ -62,7 +62,7 @@
inline
mln::window3d window3d(bool (&values)[M])
{
- int h = unsigned(std::pow(float(M), 1 / 3)) / 2;
+ int h = unsigned(std::pow(float(M), float(1. / 3.))) / 2;
mln_precondition((2 * h + 1) * (2 * h + 1) * (2 * h + 1) == M);
mln::window3d tmp;
unsigned i = 0;
Index: sandbox/jardonnet/test/icp.cc
Index: sandbox/jardonnet/test/check
--- sandbox/jardonnet/test/check (revision 0)
+++ sandbox/jardonnet/test/check (revision 0)
@@ -0,0 +1,13 @@
+#!/bin/zsh
+
+touch log
+
+echo "### report : projection" >> log
+echo "*** maps ***" >> log
+time ./+icp_maps.exe +01.pbm +02.pbm >> log
+echo "*** de_base ***" >> log
+time ./+icp_base.exe +01.pbm +02.pbm >> log
+echo "*** memo ***" >> log
+time ./+icp_memo.exe +01.pbm +02.pbm >> log
+
+cat log
Property changes on: sandbox/jardonnet/test/check
___________________________________________________________________
Name: svn:executable
+ *
Index: sandbox/jardonnet/TODO
--- sandbox/jardonnet/TODO (revision 1814)
+++ sandbox/jardonnet/TODO (working copy)
@@ -6,3 +6,17 @@
gaussian.cc:22: error: no match for 'operator==' in 'img == out'
- -
+adapt test for threshold (old thresholding)
+- -
+
+- Enlever static dans projection::memo
+
+Note:
++01.bmp: 943 pts
+30 itérations : 30*943 = 28290 calcul de ppp
+Domaine +02.bmp: 777x480 = 362082
+nb de ppp calculé memo = 11749
+
+map 1:40
+de_base 10.5
+memo 9.5
\ No newline at end of file
Index: sandbox/jardonnet/registration/quat7.hh
--- sandbox/jardonnet/registration/quat7.hh (revision 1814)
+++ sandbox/jardonnet/registration/quat7.hh (working copy)
@@ -15,37 +15,9 @@
# include <mln/trait/all.hh>
+# include <mln/make/vec.hh>
-// FIXME : move elsewhere
-namespace mln
-{
- namespace algebra
- {
-
- template<unsigned n, unsigned m, typename T>
- mat<m,n,T>
- trans(const mat<n,m,T>& matrice)
- {
- mat<m,n,T> tmp;
- for (unsigned i = 0; i < n; ++i)
- for (unsigned j = 0; j < m; ++j)
- tmp(j,i) = matrice(i,j);
- return tmp;
- }
-
- // trace
-
- template<unsigned n, typename T> inline
- float tr(const mat<n,n,T>& m)
- {
- float f = 0.f;
- for (unsigned i = 0; i < n; ++i)
- f += m(i,i);
- return f;
- }
-
- }
-}
+# include "tools.hh"
namespace mln
{
@@ -89,10 +61,15 @@
assert(input.npoints() == output.npoints());
assert(_qR.is_unit());
- //FIXME utiliser equivalent pour p_array
- //std::transform(input.begin(), input.end(),
- // output.begin(),
- // *this);
+ for (size_t i = 0; i < input.npoints(); i++)
+ output.hook_()[i] = algebra::to_point<P>((*this)(input[i]));
+ }
+
+ friend std::ostream& operator << (std::ostream& os, quat7& q)
+ {
+ std::cout << q._qR << std::endl;
+ std::cout << q._qT << std::endl;
+ return os;
}
};
@@ -121,8 +98,6 @@
// qR
- //FIXME : use P::dim ?
- std::cout << "loop" << std::endl;
algebra::mat<P::dim,P::dim,float> Mk;
for (unsigned i = 0; i < C.npoints(); ++i)
{
@@ -131,12 +106,11 @@
Mk += make::mat(Ci - mu_C) * trans(make::mat(Xki - mu_Xk));
}
Mk /= C.npoints();
- std::cout << "loop end" << std::endl;
const algebra::mat<P::dim,P::dim,float> Ak = Mk - trans(Mk);
const float v[3] = {Ak(1,2), Ak(2,0), Ak(0,1)};
- const algebra::mat<3,1,float> D = make::mat<3,1,3,float>(v); //
FIXME why <...>
+ const algebra::mat<3,1,float> D = make::mat<3,1,3,float>(v);
algebra::mat<4,4,float> Qk;
Index: sandbox/jardonnet/registration/cloud.hh
--- sandbox/jardonnet/registration/cloud.hh (revision 1814)
+++ sandbox/jardonnet/registration/cloud.hh (working copy)
@@ -51,7 +51,7 @@
return f / a1.npoints();
}
- }
-}
+ } // end of namespace registration
+} // end of namespace mln
#endif // ndef CLOUD_HH
Index: sandbox/jardonnet/registration/jacobi.hh
--- sandbox/jardonnet/registration/jacobi.hh (revision 1814)
+++ sandbox/jardonnet/registration/jacobi.hh (working copy)
@@ -11,7 +11,7 @@
namespace mln
{
-
+ //FIXME: nD ?
#define rotateJacobi(a,i,j,k,l) g=a(i,j);h=a(k,l);a(i,j)=g-s*(h+g*tau); \
a(k,l)=h+s*(g-h*tau);
Index: sandbox/jardonnet/registration/icp.hh
--- sandbox/jardonnet/registration/icp.hh (revision 1814)
+++ sandbox/jardonnet/registration/icp.hh (working copy)
@@ -35,7 +35,10 @@
# include <mln/algebra/quat.hh>
# include <mln/algebra/vec.hh>
-# include <mln/core/w_window.hh>
+# include <mln/make/w_window.hh>
+# include <mln/make/window3d.hh>
+
+# include "tools.hh"
# include "cloud.hh"
# include "quat7.hh"
@@ -66,49 +69,47 @@
template <typename P, typename T1, typename T2>
inline
p_array<P>
- icp_(const p_array<P>& C,
- const p_array<P>&,
- std::pair<T1,T2>& map)
+ icp_(p_array<P>& C,
+ const p_array<P>& X,
+ std::pair<T1,T2>&)
{
trace::entering("registration::impl::icp_");
unsigned int k;
quat7<P::dim> old_qk, qk;
- float err, err_bis;
- p_array<P> Ck(C), Xk(C);
+ float err;
+ float err_bis;
+ p_array<P> Ck(C), Xk(C); //FIXME: Xk copy C
algebra::vec<P::dim,float> mu_C = center(C), mu_Xk;
- const float epsilon = 1e-3;
+ const float epsilon = 1e-2;
- //step 1
+ //// step 1
k = 0;
- Ck = C;
-
do {
- std::cout << "step2: projection" << std::endl;
- //step 2
- err_bis = projection::fill_Xk(Ck, map, Xk);
+ //// step 2
+ //err_bis = projection::fill_Xk(Ck, map, Xk);
+ //projection::de_base(Ck, X, Xk, err_bis);
+ projection::memo(Ck, X, Xk, err_bis);
- std::cout << "step2.1: center" << std::endl;
mu_Xk = center(Xk);
- std::cout << "step3: Compute qk" << std::endl;
- // step 3
+ //// step 3
old_qk = qk;
qk = match(C, mu_C, Xk, mu_Xk);
- std::cout << "step4: apply qk" << std::endl;
- // step 4
+ //// step 4
qk.apply_on(C, Ck); // Ck+1 = qk(C)
- // err = d(Ck+1,Xk)
+ //// err = d(Ck+1,Xk)
err = rms(Ck, Xk);
+ std::cout << "error :" << err << std::endl;
++k;
- std::cout << "error is " << err << std::endl;
} while (k < 3 || (qk - old_qk).sqr_norm() > epsilon);
+ std::cout << "nb of iterations : " << k << std::endl;
trace::exiting("registration::impl::icp_");
return Ck;
}
@@ -116,42 +117,6 @@
} // end of namespace mln::registration::impl
- //FIXME: move?
- namespace convert
- {
- template <typename T>
- const image3d<T>&
- to_image_3d(const image3d<T>& img)
- {
- return img;
- }
-
- template <typename T>
- image3d<T>&
- to_image_3d(image3d<T>& img)
- {
- return img;
- }
-
- template <typename T>
- image3d<T>
- to_image_3d(const image2d<T>& img)
- {
- point3d pmin(img.domain().pmin()[0], img.domain().pmin()[1], -10);
- point3d pmax(img.domain().pmax()[0], img.domain().pmax()[1], 10);
- image3d<T> img3d(box3d(pmin,pmax));
-
- mln_piter(image3d<T>) p(img3d.domain());
- for_all(p)
- {
- if (p[2] == 0)
- img3d(p) = exact(img)(point2d(p[0],p[1]));
- }
- return img3d;
- }
- }
-
-
//Only for 2d and 3d image
template <typename I, typename J>
inline
@@ -163,44 +128,38 @@
mln_precondition(exact(cloud_).has_data());
mln_precondition(exact(surface_).has_data());
- std::cout << "convert to image3d" << std::endl;
//convert to image: time consuming
typedef image3d<mln_value(I)> I3d;
I3d cloud = convert::to_image_3d(exact(cloud_));
const I3d surface = convert::to_image_3d(exact(surface_));
-
- std::cout << "chamfer" << std::endl;
-
- //FIXME: not a chamfer. etienne?
+ /*
//create a pair (distance map, closest point)
- // window<dpoint3d> win3d;
- w_window<dpoint3d, float> chamfer; // = make::w_window(win3d, fun);
- std::pair<mln_ch_value(I3d,float),
mln_ch_value(I3d,mln_point(I3d)) > maps =
- dt::chamfer(surface, chamfer);
+ bool w[27] = {true, true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true, true};
+ window<mln_dpoint(I3d)> win3d = make::window3d(w);
+ fun::cham<point3d> fun;
+ w_window<mln_dpoint(I3d), float> chamfer = make::w_window(win3d,
fun);
+ */
+ std::pair<mln_ch_value(I3d,float),
mln_ch_value(I3d,mln_point(I3d)) > maps;// =
+ //dt::chamfer(surface, chamfer);
- std::cout << "Build p_array" << std::endl;
- //build p_arrays.
- p_array<mln_point(I3d)> c,x;
- mln_piter(I3d) p1(cloud.domain());
- for_all(p1)
- if (exact(cloud)(p1))
- c.append(p1);
-
- mln_piter(I3d) p2(surface.domain());
- for_all(p2)
- if (exact(surface)(p2))
- x.append(p2);
+ //build p_arrays.
+ p_array<mln_point(I3d)> c = convert::to_p_array(cloud);
+ p_array<mln_point(I3d)> x = convert::to_p_array(surface);
- std::cout << "Start ICP" << std::endl;
p_array<mln_point(I3d)> res = impl::icp_(c, x, maps);
//to 2d : projection (FIXME:if 3d)
+ //mln_concrete(I) output = convert::to_image2d(res)?
mln_concrete(I) output(exact(cloud_).domain());
- for (unsigned i; i < res.npoints(); i++)
+ for (size_t i = 0; i < res.npoints(); i++)
{
point2d p(res[i][0], res[i][1]);
+ //FIXME: not necessary if output(res.bbox())
+ //if (output.has(p))
output(p) = true;
}
Index: sandbox/jardonnet/registration/projection.hh
--- sandbox/jardonnet/registration/projection.hh (revision 1814)
+++ sandbox/jardonnet/registration/projection.hh (working copy)
@@ -21,16 +21,18 @@
for (size_t i = 0; i < Ck.npoints(); ++i)
{
+ //FIXME: bof
+ //if (map.second.has(Ck[i]))
+ //{
//x[i] := Ck[i] closest point in X
Xk.hook_()[i] = map.second(Ck[i]);
//err := Distance between Ck[i] and its closest point
err += map.first(Ck[i]);
+ //}
}
return err /= Ck.npoints();
}
-
-
template <typename P>
void de_base(// input
const p_array<P>& Ck,
@@ -63,7 +65,58 @@
}
err /= Ck.npoints();
}
+
+
+ template <typename P>
+ void memo(// input
+ const p_array<P>& Ck,
+ const p_array<P>& X,
+ // inout
+ p_array<P>& Xk,
+ float& err)
+ {
+ //FIXME: remove static
+ //FIXME: domain generated by X and C's domain?
+ static image3d<point3d> map(1000,1000,10);
+ static image3d<bool> mapset(1000,1000,10);
+
+ assert(Ck.npoints() == Xk.npoints());
+
+ err = 0.f;
+
+ for (size_t i = 0; i < Ck.npoints(); ++i)
+ {
+ float best_d;
+ if (mapset(Ck[i]) == false)
+ {
+ algebra::vec<P::dim,float> Cki = Ck[i];
+ algebra::vec<P::dim,float> best_x = X[0];
+ best_d = norm::l2(Cki - best_x);
+ for (size_t j = 1; j < X.npoints(); ++j)
+ {
+ algebra::vec<P::dim,float> Xj = X[j];
+ float d = norm::l2(Cki - Xj);
+ if (d < best_d)
+ {
+ best_d = d;
+ best_x = Xj;
}
}
+ Xk.hook_()[i] = algebra::to_point<P>(best_x);
+ map(Ck[i]) = Xk[i];
+ mapset(Ck[i]) = true;
+ }
+ else
+ {
+ Xk.hook_()[i] = map(Ck[i]);
+ }
+ err += best_d;
+ }
+ err /= Ck.npoints();
+ }
+
+ } // end of namespace projection
+
+} // end of namespace mln
#endif // ndef PROJECTION_HH
Index: sandbox/jardonnet/registration/tools.hh
--- sandbox/jardonnet/registration/tools.hh (revision 0)
+++ sandbox/jardonnet/registration/tools.hh (revision 0)
@@ -0,0 +1,137 @@
+#ifndef REGISTRATION_TOOL_HH
+# define REGISTRATION_TOOL_HH
+
+// temporary
+
+# include <mln/algebra/mat.hh>
+# include <mln/core/p_array.hh>
+
+namespace mln
+{
+
+ //FIXME: move?
+ namespace convert
+ {
+
+ template <typename I>
+ inline
+ p_array<mln_point(I)>
+ to_p_array(const Image<I>& img_)
+ {
+ const I& img = exact(img_);
+
+ p_array<mln_point(I)> a;
+
+ mln_piter(I) p(img.domain());
+ for_all(p)
+ if (img(p))
+ a.append(p);
+ return a;
+ }
+
+ //FIXME: to write
+ /*
+ template <typename A>
+ inline
+ image2d<mln_value(A)>
+ to_image2d(const A& a)
+ {
+ image2d<mln_value(A)> img(a.bbox());
+ for (size_t i = 0; i < a.npoints(); i++)
+ {
+ point2d p(res[i][0], res[i][1]);
+ //FIXME: BOF
+ //if (output.has(p))
+ output(p) = true;
+ }
+ }
+ */
+
+ template <typename T>
+ inline
+ const image3d<T>&
+ to_image_3d(const image3d<T>& img)
+ {
+ return img;
+ }
+
+ template <typename T>
+ image3d<T>&
+ to_image_3d(image3d<T>& img)
+ {
+ return img;
+ }
+
+ template <typename T>
+ inline
+ image3d<T>
+ to_image_3d(const image2d<T>& img)
+ {
+ point3d pmin(img.domain().pmin()[0], img.domain().pmin()[1], -1);
+ point3d pmax(img.domain().pmax()[0], img.domain().pmax()[1], 1);
+ image3d<T> img3d(box3d(pmin,pmax));
+
+ mln_piter(image3d<T>) p(img3d.domain());
+ for_all(p)
+ {
+ if (p[2] == 0)
+ img3d(p) = exact(img)(point2d(p[0],p[1]));
+ }
+ return img3d;
+ }
+
+ } // end of namespace convert
+
+
+
+ namespace fun
+ {
+ //FIXME: temporary
+ template <typename C, typename T= float>
+ struct cham : public Function_p2v< cham<C,T> >
+ {
+ typedef T result;
+ //bad
+ T operator()(dpoints_fwd_piter<mln::dpoint_<mln::grid::cube, int>
>& v) const
+ {
+ C o = C::origin;
+ if (v < o)
+ return 1.;
+ else
+ return 0.;
+ }
+ };
+ } // end of namespace fun
+
+
+
+ namespace algebra
+ {
+
+ template<unsigned n, unsigned m, typename T>
+ mat<m,n,T>
+ trans(const mat<n,m,T>& matrice)
+ {
+ mat<m,n,T> tmp;
+ for (unsigned i = 0; i < n; ++i)
+ for (unsigned j = 0; j < m; ++j)
+ tmp(j,i) = matrice(i,j);
+ return tmp;
+ }
+
+ // trace
+
+ template<unsigned n, typename T> inline
+ float tr(const mat<n,n,T>& m)
+ {
+ float f = 0.f;
+ for (unsigned i = 0; i < n; ++i)
+ f += m(i,i);
+ return f;
+ }
+
+ } // end of namespace algebra
+
+} // end of namespace mln
+
+#endif // REGISTRATION_TOOLS_HH
1
0
1814: Have piters on line graph windows and neighborhoods actually use them.
by Roland Levillain 28 Mar '08
by Roland Levillain 28 Mar '08
28 Mar '08
https://svn.lrde.epita.fr/svn/oln/trunk/milena
All the duplicated code is the source of all those repetitive changes. My
next patches will be about factoring all those guys.
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Have piters on line graph windows and neighborhoods actually use
them.
* mln/core/line_graph_window_piter.hh
(mln::line_graph_window_fwd_piter<P, W>)
(mln::line_graph_window_bkd_piter<P, W>):
Have these class templates take a window type as second,
additional parameter.
(mln::line_graph_window_fwd_piter<P, W>::nbh_)
(mln::line_graph_window_bkd_piter<P, W>::nbh_):
New attributes.
(line_graph_window_fwd_piter)
(line_graph_window_bkd_piter):
Adjust ctors.
(mln::line_graph_window_fwd_piter<P, W>::first_)
(mln::line_graph_window_fwd_piter<P, W>::step_)
(mln::line_graph_window_bkd_piter<P, W>::first_)
(mln::line_graph_window_bkd_piter<P, W>::step_):
New methods.
(mln::line_graph_window_fwd_piter<P, W>::start)
(mln::line_graph_window_fwd_piter<P, W>::next_)
(mln::line_graph_window_bkd_piter<P, W>::start)
(mln::line_graph_window_bkd_piter<P, W>::next_):
Delegate the body of the routine to the window.
* mln/core/line_graph_elt_window.hh
(mln::line_graph_elt_window<P>::fwd_qiter)
(mln::line_graph_elt_window<P>::bkd_qiter):
Adjust typedefs.
(mln::line_graph_elt_window<P>::psite):
New typedef.
(mln::line_graph_elt_window<P>::start)
(mln::line_graph_elt_window<P>::next_):
New methods.
* mln/core/line_graph_neighborhood_piter.hh
(mln::line_graph_neighborhood_fwd_piter<P, N>)
(mln::line_graph_neighborhood_bkd_piter<P, N>):
Have these class templates take a neighborhood type as second,
additional parameter.
(mln::line_graph_neighborhood_fwd_piter<P, N>::nbh_)
(mln::line_graph_neighborhood_bkd_piter<P, N>::nbh_):
New attributes.
(line_graph_neighborhood_fwd_piter)
(line_graph_neighborhood_bkd_piter):
Adjust ctors.
(mln::line_graph_neighborhood_fwd_piter<P, N>::first_)
(mln::line_graph_neighborhood_fwd_piter<P, N>::step_)
(mln::line_graph_neighborhood_bkd_piter<P, N>::first_)
(mln::line_graph_neighborhood_bkd_piter<P, N>::step_):
New methods.
(mln::line_graph_neighborhood_fwd_piter<P, N>::start)
(mln::line_graph_neighborhood_fwd_piter<P, N>::next_)
(mln::line_graph_neighborhood_bkd_piter<P, N>::start)
(mln::line_graph_neighborhood_bkd_piter<P, N>::next_):
Delegate the body of the routine to the neighborhood.
* mln/core/line_graph_elt_neighborhood.hh
(mln::line_graph_elt_neighborhood<P>::fwd_qiter)
(mln::line_graph_elt_neighborhood<P>::bkd_qiter):
Adjust typedefs.
(mln::line_graph_elt_neighborhood<P>::psite):
New typedef.
(mln::line_graph_elt_neighborhood<P>::start)
(mln::line_graph_elt_neighborhood<P>::next_):
New methods.
* tests/core/line_graph_elt_window.cc: Update test.
* tests/core/line_graph_elt_neighborhood.cc: New test.
mln/core/line_graph_elt_neighborhood.hh | 92 +++++++---
mln/core/line_graph_elt_window.hh | 90 ++++++----
mln/core/line_graph_neighborhood_piter.hh | 260 ++++++++++++++++-------------
mln/core/line_graph_window_piter.hh | 263 ++++++++++++++++--------------
tests/core/line_graph_elt_neighborhood.cc | 43 +++-
tests/core/line_graph_elt_window.cc | 29 +++
6 files changed, 479 insertions(+), 298 deletions(-)
Index: mln/core/line_graph_window_piter.hh
--- mln/core/line_graph_window_piter.hh (revision 1813)
+++ mln/core/line_graph_window_piter.hh (working copy)
@@ -57,16 +57,16 @@
template <typename P> class line_graph_psite;
- /*---------------------------------.
- | line_graph_window_fwd_piter<P>. |
- `---------------------------------*/
+ /*------------------------------------.
+ | line_graph_window_fwd_piter<P, W>. |
+ `------------------------------------*/
/// \brief Forward iterator on line graph window.
- template <typename P>
+ template <typename P, typename W>
class line_graph_window_fwd_piter :
- public Point_Iterator< line_graph_window_fwd_piter<P> > // or Iterator<...>?
+ public Point_Iterator< line_graph_window_fwd_piter<P, W> >
{
- typedef line_graph_window_fwd_piter<P> self_;
+ typedef line_graph_window_fwd_piter<P, W> self_;
typedef Point_Iterator< self_ > super_;
public:
@@ -83,8 +83,9 @@
public:
/// Construction.
/// \{
- template <typename W, typename Pref>
- line_graph_window_fwd_piter(const W& win, const Point_Site<Pref>& p_ref);
+ template <typename Pref>
+ line_graph_window_fwd_piter(const Window<W>& win,
+ const Point_Site<Pref>& p_ref);
/// \}
/// Manipulation.
@@ -117,11 +118,23 @@
coord operator[](unsigned i) const;
/// \}
+ /// Internals, used by the window.
+ /// \{
+ public:
+ /// Set the iterator to the first site of the graph.
+ void first_();
+ /// Advance the position of the iterator by one step.
+ void step_();
+
+ /// An internal iterator on the set of edges of the underlying graph.
+ util::edge_id id_;
+ /// \}
+
private:
+ /// The window.
+ const W& win_;
/// The ``central'' psite of the window.
const psite& p_ref_;
- /// An internal iterator on the set of edges of the underlying graph.
- util::edge_id id_;
/// The psite corresponding to this iterator.
psite psite_;
/// The point corresponding to this iterator.
@@ -134,22 +147,22 @@
the general mechanism provided by Point_Site. But then again, we
need to refine/adjust the interface of Point_Site w.r.t. the
mandatory conversions to points. */
- template <typename P>
+ template <typename P, typename W>
inline
std::ostream&
- operator<<(std::ostream& ostr, const line_graph_window_fwd_piter<P>& p);
+ operator<<(std::ostream& ostr, const line_graph_window_fwd_piter<P, W>& p);
- /*---------------------------------.
- | line_graph_window_bkd_piter<P>. |
- `---------------------------------*/
+ /*------------------------------------.
+ | line_graph_window_bkd_piter<P, W>. |
+ `------------------------------------*/
/// \brief Backward iterator on line graph window.
- template <typename P>
+ template <typename P, typename W>
class line_graph_window_bkd_piter :
- public Point_Iterator< line_graph_window_bkd_piter<P> > // or Iterator<...>?
+ public Point_Iterator< line_graph_window_bkd_piter<P, W> >
{
- typedef line_graph_window_bkd_piter<P> self_;
+ typedef line_graph_window_bkd_piter<P, W> self_;
typedef Point_Iterator< self_ > super_;
public:
@@ -166,8 +179,9 @@
public:
/// Construction.
/// \{
- template <typename W, typename Pref>
- line_graph_window_bkd_piter(const W& win, const Point_Site<Pref>& p_ref);
+ template <typename Pref>
+ line_graph_window_bkd_piter(const Window<W>& win,
+ const Point_Site<Pref>& p_ref);
/// \}
/// Manipulation.
@@ -200,11 +214,23 @@
coord operator[](unsigned i) const;
/// \}
+ /// Internals, used by the window.
+ /// \{
+ public:
+ /// Set the iterator to the first site of the graph.
+ void first_();
+ /// Advance the position of the iterator by one step.
+ void step_();
+
+ /// An internal iterator on the set of edges of the underlying graph.
+ util::edge_id id_;
+ /// \}
+
private:
+ /// The window.
+ const W& win_;
/// The ``central'' psite of the window.
const psite& p_ref_;
- /// An internal iterator on the set of edges of the underlying graph.
- util::edge_id id_;
/// The psite corresponding to this iterator.
psite psite_;
/// The point corresponding to this iterator.
@@ -217,26 +243,26 @@
the general mechanism provided by Point_Site. But then again, we
need to refine/adjust the interface of Point_Site w.r.t. the
mandatory conversions to points. */
- template <typename P>
+ template <typename P, typename W>
inline
std::ostream&
- operator<<(std::ostream& ostr, const line_graph_window_bkd_piter<P>& p);
+ operator<<(std::ostream& ostr, const line_graph_window_bkd_piter<P, W>& p);
# ifndef MLN_INCLUDE_ONLY
- /*---------------------------------.
- | line_graph_window_fwd_piter<P>. |
- `---------------------------------*/
+ /*------------------------------------.
+ | line_graph_window_fwd_piter<P, W>. |
+ `------------------------------------*/
- // FIXME: Currently, argument win is ignored.
- template <typename P>
- template <typename W, typename Pref>
+ template <typename P, typename W>
+ template <typename Pref>
inline
- line_graph_window_fwd_piter<P>::line_graph_window_fwd_piter(const W& /* win */,
+ line_graph_window_fwd_piter<P, W>::line_graph_window_fwd_piter(const Window<W>& win,
const Point_Site<Pref>& p_ref)
- : p_ref_(exact(p_ref).to_psite()),
+ : win_(exact(win)),
+ p_ref_(exact(p_ref).to_psite()),
// Initialize psite_ to a dummy value.
psite_()
{
@@ -244,10 +270,10 @@
invalidate();
}
- template <typename P>
+ template <typename P, typename W>
inline
bool
- line_graph_window_fwd_piter<P>::is_valid() const
+ line_graph_window_fwd_piter<P, W>::is_valid() const
{
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
@@ -255,52 +281,55 @@
return p_ref_.is_valid() && id_ < p_ref_.plg().gr_->nedges();
}
- template <typename P>
+ template <typename P, typename W>
inline
void
- line_graph_window_fwd_piter<P>::invalidate()
+ line_graph_window_fwd_piter<P, W>::invalidate()
{
id_ = -1;
}
- template <typename P>
+ template <typename P, typename W>
inline
void
- line_graph_window_fwd_piter<P>::start()
+ line_graph_window_fwd_piter<P, W>::start()
{
- id_ = 0;
- if (!adjacent_or_equal_to_p_ref_())
- next_();
- /* FIXME: This is redundant with the end of next_(), but we might
- change the implementation of start_() when we'll fix it later,
- and no longer use next_(). */
+ win_.start(*this);
if (is_valid())
update_();
}
- template <typename P>
+ template <typename P, typename W>
inline
void
- line_graph_window_fwd_piter<P>::next_()
+ line_graph_window_fwd_piter<P, W>::next_()
{
- /* FIXME: This is inefficient. The graph structure should be able
- to produce the set of adjacent edges fast. Boost Graphs
- probably provides adequates structures to fetch these
- neighbors in constant time. */
- /* FIXME: Moreover, the behavior of next shall depend on the
- window, which is not the case now! (Currently, next_() behaves
- as win was always an elementary window.) */
- do
- ++id_;
- while (is_valid() && !adjacent_or_equal_to_p_ref_());
+ win_.next_(*this);
if (is_valid())
update_();
}
- template <typename P>
+ template <typename P, typename W>
+ inline
+ void
+ line_graph_window_fwd_piter<P, W>::first_()
+ {
+ id_ = 0;
+ }
+
+ template <typename P, typename W>
+ inline
+ void
+ line_graph_window_fwd_piter<P, W>::step_()
+ {
+ ++id_;
+ }
+
+
+ template <typename P, typename W>
inline
bool
- line_graph_window_fwd_piter<P>::adjacent_or_equal_to_p_ref_() const
+ line_graph_window_fwd_piter<P, W>::adjacent_or_equal_to_p_ref_() const
{
// Check wether the iterator points to P_REF_.
if (id_ == p_ref_.id())
@@ -330,68 +359,69 @@
return false;
}
- template <typename P>
+ template <typename P, typename W>
inline
void
- line_graph_window_fwd_piter<P>::update_()
+ line_graph_window_fwd_piter<P, W>::update_()
{
// Update psite_.
psite_ = line_graph_psite<P>(p_ref_.plg(), id_);
}
- template <typename P>
+ template <typename P, typename W>
inline
const P&
- line_graph_window_fwd_piter<P>::to_point() const
+ line_graph_window_fwd_piter<P, W>::to_point() const
{
return p_;
}
- template <typename P>
+ template <typename P, typename W>
inline
const line_graph_psite<P>&
- line_graph_window_fwd_piter<P>::to_psite() const
+ line_graph_window_fwd_piter<P, W>::to_psite() const
{
return psite_;
}
- template <typename P>
+ template <typename P, typename W>
inline
- line_graph_window_fwd_piter<P>::operator line_graph_psite<P> () const
+ line_graph_window_fwd_piter<P, W>::operator line_graph_psite<P> () const
{
mln_precondition(is_valid());
return psite_;
}
- template <typename P>
+ template <typename P, typename W>
inline
mln_coord(P)
- line_graph_window_fwd_piter<P>::operator[](unsigned i) const
+ line_graph_window_fwd_piter<P, W>::operator[](unsigned i) const
{
assert(i < dim);
return p_[i];
}
- template <typename P>
+ template <typename P, typename W>
inline
std::ostream&
- operator<<(std::ostream& ostr, const line_graph_window_fwd_piter<P>& p)
+ operator<<(std::ostream& ostr, const line_graph_window_fwd_piter<P, W>& p)
{
return ostr << p.to_psite();
}
- /*---------------------------------.
- | line_graph_window_bkd_piter<P>. |
- `---------------------------------*/
+ /*------------------------------------.
+ | line_graph_window_bkd_piter<P, W>. |
+ `------------------------------------*/
// FIXME: Currently, argument win is ignored.
- template <typename P>
- template <typename W, typename Pref>
+ template <typename P, typename W>
+ template <typename Pref>
inline
- line_graph_window_bkd_piter<P>::line_graph_window_bkd_piter(const W& /* win */,
+ line_graph_window_bkd_piter<P, W>::line_graph_window_bkd_piter(const Window<W>& win,
const Point_Site<Pref>& p_ref)
- : p_ref_(exact(p_ref).to_psite()),
+ : win_(exact(win)),
+ p_ref_(exact(p_ref).to_psite()),
// Initialize psite_ to a dummy value.
psite_()
{
@@ -399,10 +429,10 @@
invalidate();
}
- template <typename P>
+ template <typename P, typename W>
inline
bool
- line_graph_window_bkd_piter<P>::is_valid() const
+ line_graph_window_bkd_piter<P, W>::is_valid() const
{
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
@@ -410,52 +440,55 @@
return p_ref_.is_valid() && id_ < p_ref_.plg().gr_->nedges();
}
- template <typename P>
+ template <typename P, typename W>
inline
void
- line_graph_window_bkd_piter<P>::invalidate()
+ line_graph_window_bkd_piter<P, W>::invalidate()
{
id_ = -1;
}
- template <typename P>
+ template <typename P, typename W>
inline
void
- line_graph_window_bkd_piter<P>::start()
+ line_graph_window_bkd_piter<P, W>::start()
{
- id_ = p_ref_.plg().gr_->nedges() - 1;
- if (!adjacent_or_equal_to_p_ref_())
- next_();
- /* FIXME: This is redundant with the end of next_(), but we might
- change the implementation of start_() when we'll fix it later,
- and no longer use next_(). */
+ win_.start(*this);
if (is_valid())
update_();
}
- template <typename P>
+ template <typename P, typename W>
inline
void
- line_graph_window_bkd_piter<P>::next_()
+ line_graph_window_bkd_piter<P, W>::next_()
{
- /* FIXME: This is inefficient. The graph structure should be able
- to produce the set of adjacent edges fast. Boost Graphs
- probably provides adequates structures to fetch these
- neighbors in constant time. */
- /* FIXME: Moreover, the behavior of next shall depend on the
- window, which is not the case now! (Currently, next_() behaves
- as win was always an elementary window.) */
- do
- --id_;
- while (is_valid() && !adjacent_or_equal_to_p_ref_());
+ win_.next_(*this);
if (is_valid())
update_();
}
- template <typename P>
+ template <typename P, typename W>
+ inline
+ void
+ line_graph_window_bkd_piter<P, W>::first_()
+ {
+ id_ = p_ref_.plg().gr_->nedges() - 1;
+ }
+
+ template <typename P, typename W>
+ inline
+ void
+ line_graph_window_bkd_piter<P, W>::step_()
+ {
+ --id_;
+ }
+
+
+ template <typename P, typename W>
inline
bool
- line_graph_window_bkd_piter<P>::adjacent_or_equal_to_p_ref_() const
+ line_graph_window_bkd_piter<P, W>::adjacent_or_equal_to_p_ref_() const
{
// Check wether the iterator points to P_REF_.
if (id_ == p_ref_.id())
@@ -485,52 +518,52 @@
return false;
}
- template <typename P>
+ template <typename P, typename W>
inline
void
- line_graph_window_bkd_piter<P>::update_()
+ line_graph_window_bkd_piter<P, W>::update_()
{
// Update psite_.
psite_ = line_graph_psite<P>(p_ref_.plg(), id_);
}
- template <typename P>
+ template <typename P, typename W>
inline
const P&
- line_graph_window_bkd_piter<P>::to_point() const
+ line_graph_window_bkd_piter<P, W>::to_point() const
{
return p_;
}
- template <typename P>
+ template <typename P, typename W>
inline
const line_graph_psite<P>&
- line_graph_window_bkd_piter<P>::to_psite() const
+ line_graph_window_bkd_piter<P, W>::to_psite() const
{
return psite_;
}
- template <typename P>
+ template <typename P, typename W>
inline
- line_graph_window_bkd_piter<P>::operator line_graph_psite<P> () const
+ line_graph_window_bkd_piter<P, W>::operator line_graph_psite<P> () const
{
mln_precondition(is_valid());
return psite_;
}
- template <typename P>
+ template <typename P, typename W>
inline
mln_coord(P)
- line_graph_window_bkd_piter<P>::operator[](unsigned i) const
+ line_graph_window_bkd_piter<P, W>::operator[](unsigned i) const
{
assert(i < dim);
return p_[i];
}
- template <typename P>
+ template <typename P, typename W>
inline
std::ostream&
- operator<<(std::ostream& ostr, const line_graph_window_bkd_piter<P>& p)
+ operator<<(std::ostream& ostr, const line_graph_window_bkd_piter<P, W>& p)
{
return ostr << p.to_psite();
}
Index: mln/core/line_graph_elt_window.hh
--- mln/core/line_graph_elt_window.hh (revision 1813)
+++ mln/core/line_graph_elt_window.hh (working copy)
@@ -28,13 +28,11 @@
#ifndef MLN_CORE_LINE_GRAPH_ELT_WINDOW_HH
# define MLN_CORE_LINE_GRAPH_ELT_WINDOW_HH
-/*! \file mln/core/line_graph_elt_window.hh
- *
- * \brief Definition of the elementary ``window'' on a line graph.
- *
- * \todo Make naming coherent: we have window (without '_') but
- * point_, neighb_, etc.
- */
+/// \file mln/core/line_graph_elt_window.hh
+/// \brief Definition of the elementary ``window'' on a line graph.
+
+/* FIXME: Have a consistent naming: we have window (without '_') but
+ point_, neighb_, etc. */
/* FIXME: Factor those classes:
- mln::graph_elt_window
@@ -50,14 +48,11 @@
namespace mln
{
// Fwd decls.
- template <typename P> class line_graph_window_fwd_piter;
- template <typename P> class line_graph_window_bkd_piter;
+ template <typename P, typename W> class line_graph_window_fwd_piter;
+ template <typename P, typename W> class line_graph_window_bkd_piter;
- /*! \brief Elementary window on line graph class.
- *
- * FIXME: Doc.
- */
+ /// \brief Elementary window on line graph class.
template <typename P>
class line_graph_elt_window : public Window< line_graph_elt_window<P> >
{
@@ -66,23 +61,21 @@
public:
/// Associated types.
/// \{
- /// The type of point stored into the window.
- // FIXME: Is this right, if we consider that this window stores
- // psites, not points?
+ /// The type of point corresponding to the window.
typedef P point;
+ /// The type of psite corresponding to the window.
+ typedef line_graph_psite<P> psite;
// FIXME: This is a dummy value.
typedef void dpoint;
- /*! \brief Point_Iterator type to browse the points of a generic window
- * w.r.t. the ordering of delta-points.
- */
- typedef line_graph_window_fwd_piter<P> fwd_qiter;
-
- /*! \brief Point_Iterator type to browse the points of a generic window
- * w.r.t. the reverse ordering of delta-points.
- */
- typedef line_graph_window_bkd_piter<P> bkd_qiter;
+ /// \brief Point_Iterator type to browse the psites of the window
+ /// w.r.t. the ordering of edges.
+ typedef line_graph_window_fwd_piter<P, self_> fwd_qiter;
+
+ /// \brief Point_Iterator type to browse the psites of the window
+ /// w.r.t. the reverse ordering of edges.
+ typedef line_graph_window_bkd_piter<P, self_> bkd_qiter;
/// The default qiter type.
typedef fwd_qiter qiter;
@@ -91,16 +84,25 @@
/// Construct an elementary line_graph window.
line_graph_elt_window();
+ /// Services for iterators.
+ /// \{
+ /// Move \a piter to the beginning of the iteration on this window.
+ template <typename Piter>
+ void start(Point_Iterator<Piter>& piter) const;
+ /// Move \a piter to the next site on this window.
+ template <typename Piter>
+ void next_(Point_Iterator<Piter>& piter) const;
+ /// \}
+
+ /// Interface of the concept Window.
+ /// \{
/// Is the window is empty?
bool is_empty() const;
-
/// Is the window centered?
bool is_centered() const;
-
/// Is the window symmetric?
- // FIXME: We should defin this more precisely.
+ // FIXME: We should define this more precisely.
bool is_symmetric() const;
-
/// Return the maximum coordinate gap between the window center
/// and a window point.
/* FIXME: This method returns a dummy value (0), since the delta
@@ -114,9 +116,9 @@
It raises another question: should delta() be part of the
concept ``Window''? */
unsigned delta() const;
-
/// Apply a central symmetry to the target window.
self_& sym();
+ /// \}
};
@@ -129,6 +131,34 @@
}
template <typename P>
+ template <typename Piter>
+ inline
+ void
+ line_graph_elt_window<P>::start(Point_Iterator<Piter>& piter_) const
+ {
+ Piter& piter = exact(piter_);
+ piter.first_();
+ if (!piter.adjacent_or_equal_to_p_ref_())
+ next_(piter);
+ }
+
+ template <typename P>
+ template <typename Piter>
+ inline
+ void
+ line_graph_elt_window<P>::next_(Point_Iterator<Piter>& piter_) const
+ {
+ Piter& piter = exact(piter_);
+ /* FIXME: This is inefficient. The graph structure should be able
+ to produce the set of adjacent nodes fast. Boost Graphs
+ probably provides adequates structures to fetch these
+ neighbors in constant time. */
+ do
+ piter.step_();
+ while (piter.is_valid() && !piter.adjacent_or_equal_to_p_ref_());
+ }
+
+ template <typename P>
inline
bool
line_graph_elt_window<P>::is_empty() const
Index: mln/core/line_graph_neighborhood_piter.hh
--- mln/core/line_graph_neighborhood_piter.hh (revision 1813)
+++ mln/core/line_graph_neighborhood_piter.hh (working copy)
@@ -57,16 +57,16 @@
template <typename P> class line_graph_psite;
- /*---------------------------------------.
- | line_graph_neighborhood_fwd_piter<P>. |
- `---------------------------------------*/
+ /*------------------------------------------.
+ | line_graph_neighborhood_fwd_piter<P, N>. |
+ `------------------------------------------*/
/// \brief Forward iterator on line graph neighborhood.
- template <typename P>
+ template <typename P, typename N>
class line_graph_neighborhood_fwd_piter :
- public Point_Iterator< line_graph_neighborhood_fwd_piter<P> > // or Iterator<...>?
+ public Point_Iterator< line_graph_neighborhood_fwd_piter<P, N> >
{
- typedef line_graph_neighborhood_fwd_piter<P> self_;
+ typedef line_graph_neighborhood_fwd_piter<P, N> self_;
typedef Point_Iterator< self_ > super_;
public:
@@ -83,8 +83,8 @@
public:
/// Construction.
/// \{
- template <typename N, typename Pref>
- line_graph_neighborhood_fwd_piter(const N& nbh,
+ template <typename Pref>
+ line_graph_neighborhood_fwd_piter(const Neighborhood<N>& nbh,
const Point_Site<Pref>& p_ref);
/// \}
@@ -119,11 +119,23 @@
coord operator[](unsigned i) const;
/// \}
+ /// Internals, used by the neighborhood.
+ /// \{
+ public:
+ /// Set the iterator to the first site of the graph.
+ void first_();
+ /// Advance the position of the iterator by one step.
+ void step_();
+
+ /// An internal iterator on the set of edges of the underlying graph.
+ util::edge_id id_;
+ /// \}
+
private:
+ /// The neighborhood.
+ const N& nbh_;
/// The ``central'' psite of the neighborhood.
const psite& p_ref_;
- /// An internal iterator on the set of edges of the underlying graph.
- util::edge_id id_;
/// The psite corresponding to this iterator.
psite psite_;
/// The point corresponding to this iterator.
@@ -136,23 +148,23 @@
the general mechanism provided by Point_Site. But then again, we
need to refine/adjust the interface of Point_Site w.r.t. the
mandatory conversions to points. */
- template <typename P>
+ template <typename P, typename N>
inline
std::ostream&
operator<<(std::ostream& ostr,
- const line_graph_neighborhood_fwd_piter<P>& p);
+ const line_graph_neighborhood_fwd_piter<P, N>& p);
- /*---------------------------------------.
- | line_graph_neighborhood_bkd_piter<P>. |
- `---------------------------------------*/
+ /*------------------------------------------.
+ | line_graph_neighborhood_bkd_piter<P, N>. |
+ `------------------------------------------*/
/// \brief Backward iterator on line graph neighborhood.
- template <typename P>
+ template <typename P, typename N>
class line_graph_neighborhood_bkd_piter :
- public Point_Iterator< line_graph_neighborhood_bkd_piter<P> > // or Iterator<...>?
+ public Point_Iterator< line_graph_neighborhood_bkd_piter<P, N> >
{
- typedef line_graph_neighborhood_bkd_piter<P> self_;
+ typedef line_graph_neighborhood_bkd_piter<P, N> self_;
typedef Point_Iterator< self_ > super_;
public:
@@ -169,8 +181,8 @@
public:
/// Construction.
/// \{
- template <typename N, typename Pref>
- line_graph_neighborhood_bkd_piter(const N& nbh,
+ template <typename Pref>
+ line_graph_neighborhood_bkd_piter(const Neighborhood<N>& nbh,
const Point_Site<Pref>& p_ref);
/// \}
@@ -205,11 +217,23 @@
coord operator[](unsigned i) const;
/// \}
+ /// Internals, used by the neighborhood.
+ /// \{
+ public:
+ /// Set the iterator to the first site of the graph.
+ void first_();
+ /// Advance the position of the iterator by one step.
+ void step_();
+
+ /// An internal iterator on the set of edges of the underlying graph.
+ util::edge_id id_;
+ /// \}
+
private:
+ /// The neighborhood.
+ const N& nbh_;
/// The ``central'' psite of the neighborhood.
const psite& p_ref_;
- /// An internal iterator on the set of edges of the underlying graph.
- util::edge_id id_;
/// The psite corresponding to this iterator.
psite psite_;
/// The point corresponding to this iterator.
@@ -222,27 +246,28 @@
the general mechanism provided by Point_Site. But then again, we
need to refine/adjust the interface of Point_Site w.r.t. the
mandatory conversions to points. */
- template <typename P>
+ template <typename P, typename N>
inline
std::ostream&
operator<<(std::ostream& ostr,
- const line_graph_neighborhood_bkd_piter<P>& p);
+ const line_graph_neighborhood_bkd_piter<P, N>& p);
# ifndef MLN_INCLUDE_ONLY
- /*---------------------------------------.
- | line_graph_neighborhood_fwd_piter<P>. |
- `---------------------------------------*/
+ /*------------------------------------------.
+ | line_graph_neighborhood_fwd_piter<P, N>. |
+ `------------------------------------------*/
// FIXME: Currently, argument nbh is ignored.
- template <typename P>
- template <typename N, typename Pref>
+ template <typename P, typename N>
+ template <typename Pref>
inline
- line_graph_neighborhood_fwd_piter<P>::line_graph_neighborhood_fwd_piter(const N& /* nbh */,
+ line_graph_neighborhood_fwd_piter<P, N>::line_graph_neighborhood_fwd_piter(const Neighborhood<N>& nbh,
const Point_Site<Pref>& p_ref)
- : p_ref_(exact(p_ref).to_psite()),
+ : nbh_(exact(nbh)),
+ p_ref_(exact(p_ref).to_psite()),
// Initialize psite_ to a dummy value.
psite_()
{
@@ -250,10 +275,10 @@
invalidate();
}
- template <typename P>
+ template <typename P, typename N>
inline
bool
- line_graph_neighborhood_fwd_piter<P>::is_valid() const
+ line_graph_neighborhood_fwd_piter<P, N>::is_valid() const
{
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
@@ -261,52 +286,55 @@
return p_ref_.is_valid() && id_ < p_ref_.plg().gr_->nedges();
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- line_graph_neighborhood_fwd_piter<P>::invalidate()
+ line_graph_neighborhood_fwd_piter<P, N>::invalidate()
{
id_ = -1;
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- line_graph_neighborhood_fwd_piter<P>::start()
+ line_graph_neighborhood_fwd_piter<P, N>::start()
{
- id_ = 0;
- if (!adjacent_or_equal_to_p_ref_())
- next_();
- /* FIXME: This is redundant with the end of next_(), but we might
- change the implementation of start_() when we'll fix it later,
- and no longer use next_(). */
+ nbh_.start(*this);
if (is_valid())
update_();
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- line_graph_neighborhood_fwd_piter<P>::next_()
+ line_graph_neighborhood_fwd_piter<P, N>::next_()
{
- /* FIXME: This is inefficient. The graph structure should be able
- to produce the set of adjacent edges fast. Boost Graphs
- probably provides adequates structures to fetch these
- neighbors in constant time. */
- /* FIXME: Moreover, the behavior of next shall depend on the
- neighborhood, which is not the case now! (Currently, next_()
- behaves as nbh was always an elementary neighborhood.) */
- do
- ++id_;
- while (is_valid() && !adjacent_or_equal_to_p_ref_());
+ nbh_.next_(*this);
if (is_valid())
update_();
}
- template <typename P>
+ template <typename P, typename N>
+ inline
+ void
+ line_graph_neighborhood_fwd_piter<P, N>::first_()
+ {
+ id_ = 0;
+ }
+
+ template <typename P, typename N>
+ inline
+ void
+ line_graph_neighborhood_fwd_piter<P, N>::step_()
+ {
+ ++id_;
+ }
+
+
+ template <typename P, typename N>
inline
bool
- line_graph_neighborhood_fwd_piter<P>::adjacent_or_equal_to_p_ref_() const
+ line_graph_neighborhood_fwd_piter<P, N>::adjacent_or_equal_to_p_ref_() const
{
// Check wether the iterator points to P_REF_.
if (id_ == p_ref_.id())
@@ -336,69 +364,70 @@
return false;
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- line_graph_neighborhood_fwd_piter<P>::update_()
+ line_graph_neighborhood_fwd_piter<P, N>::update_()
{
// Update psite_.
psite_ = line_graph_psite<P>(p_ref_.plg(), id_);
}
- template <typename P>
+ template <typename P, typename N>
inline
const P&
- line_graph_neighborhood_fwd_piter<P>::to_point() const
+ line_graph_neighborhood_fwd_piter<P, N>::to_point() const
{
return p_;
}
- template <typename P>
+ template <typename P, typename N>
inline
const line_graph_psite<P>&
- line_graph_neighborhood_fwd_piter<P>::to_psite() const
+ line_graph_neighborhood_fwd_piter<P, N>::to_psite() const
{
return psite_;
}
- template <typename P>
+ template <typename P, typename N>
inline
- line_graph_neighborhood_fwd_piter<P>::operator line_graph_psite<P> () const
+ line_graph_neighborhood_fwd_piter<P, N>::operator line_graph_psite<P> () const
{
mln_precondition(is_valid());
return psite_;
}
- template <typename P>
+ template <typename P, typename N>
inline
mln_coord(P)
- line_graph_neighborhood_fwd_piter<P>::operator[](unsigned i) const
+ line_graph_neighborhood_fwd_piter<P, N>::operator[](unsigned i) const
{
assert(i < dim);
return p_[i];
}
- template <typename P>
+ template <typename P, typename N>
inline
std::ostream&
operator<<(std::ostream& ostr,
- const line_graph_neighborhood_fwd_piter<P>& p)
+ const line_graph_neighborhood_fwd_piter<P, N>& p)
{
return ostr << p.to_psite();
}
- /*---------------------------------------.
- | line_graph_neighborhood_bkd_piter<P>. |
- `---------------------------------------*/
+ /*------------------------------------------.
+ | line_graph_neighborhood_bkd_piter<P, N>. |
+ `------------------------------------------*/
// FIXME: Currently, argument nbh is ignored.
- template <typename P>
- template <typename N, typename Pref>
+ template <typename P, typename N>
+ template <typename Pref>
inline
- line_graph_neighborhood_bkd_piter<P>::line_graph_neighborhood_bkd_piter(const N& /* nbh */,
+ line_graph_neighborhood_bkd_piter<P, N>::line_graph_neighborhood_bkd_piter(const Neighborhood<N>& nbh,
const Point_Site<Pref>& p_ref)
- : p_ref_(exact(p_ref).to_psite()),
+ : nbh_(exact(nbh)),
+ p_ref_(exact(p_ref).to_psite()),
// Initialize psite_ to a dummy value.
psite_()
{
@@ -406,10 +435,10 @@
invalidate();
}
- template <typename P>
+ template <typename P, typename N>
inline
bool
- line_graph_neighborhood_bkd_piter<P>::is_valid() const
+ line_graph_neighborhood_bkd_piter<P, N>::is_valid() const
{
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
@@ -417,52 +446,55 @@
return p_ref_.is_valid() && id_ < p_ref_.plg().gr_->nedges();
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- line_graph_neighborhood_bkd_piter<P>::invalidate()
+ line_graph_neighborhood_bkd_piter<P, N>::invalidate()
{
id_ = -1;
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- line_graph_neighborhood_bkd_piter<P>::start()
+ line_graph_neighborhood_bkd_piter<P, N>::start()
{
- id_ = p_ref_.plg().gr_->nedges() - 1;
- if (!adjacent_or_equal_to_p_ref_())
- next_();
- /* FIXME: This is redundant with the end of next_(), but we might
- change the implementation of start_() when we'll fix it later,
- and no longer use next_(). */
+ nbh_.start(*this);
if (is_valid())
update_();
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- line_graph_neighborhood_bkd_piter<P>::next_()
+ line_graph_neighborhood_bkd_piter<P, N>::next_()
{
- /* FIXME: This is inefficient. The graph structure should be able
- to produce the set of adjacent edges fast. Boost Graphs
- probably provides adequates structures to fetch these
- neighbors in constant time. */
- /* FIXME: Moreover, the behavior of next shall depend on the
- neighborhood, which is not the case now! (Currently, next_()
- behaves as nbh was always an elementary neighborhood.) */
- do
- --id_;
- while (is_valid() && !adjacent_or_equal_to_p_ref_());
+ nbh_.next_(*this);
if (is_valid())
update_();
}
- template <typename P>
+ template <typename P, typename N>
+ inline
+ void
+ line_graph_neighborhood_bkd_piter<P, N>::first_()
+ {
+ id_ = p_ref_.plg().gr_->nedges() - 1;
+ }
+
+ template <typename P, typename N>
+ inline
+ void
+ line_graph_neighborhood_bkd_piter<P, N>::step_()
+ {
+ --id_;
+ }
+
+
+ template <typename P, typename N>
inline
bool
- line_graph_neighborhood_bkd_piter<P>::adjacent_or_equal_to_p_ref_() const
+ line_graph_neighborhood_bkd_piter<P, N>::adjacent_or_equal_to_p_ref_() const
{
// Check wether the iterator points to P_REF_.
if (id_ == p_ref_.id())
@@ -492,53 +524,53 @@
return false;
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- line_graph_neighborhood_bkd_piter<P>::update_()
+ line_graph_neighborhood_bkd_piter<P, N>::update_()
{
// Update psite_.
psite_ = line_graph_psite<P>(p_ref_.plg(), id_);
}
- template <typename P>
+ template <typename P, typename N>
inline
const P&
- line_graph_neighborhood_bkd_piter<P>::to_point() const
+ line_graph_neighborhood_bkd_piter<P, N>::to_point() const
{
return p_;
}
- template <typename P>
+ template <typename P, typename N>
inline
const line_graph_psite<P>&
- line_graph_neighborhood_bkd_piter<P>::to_psite() const
+ line_graph_neighborhood_bkd_piter<P, N>::to_psite() const
{
return psite_;
}
- template <typename P>
+ template <typename P, typename N>
inline
- line_graph_neighborhood_bkd_piter<P>::operator line_graph_psite<P> () const
+ line_graph_neighborhood_bkd_piter<P, N>::operator line_graph_psite<P> () const
{
mln_precondition(is_valid());
return psite_;
}
- template <typename P>
+ template <typename P, typename N>
inline
mln_coord(P)
- line_graph_neighborhood_bkd_piter<P>::operator[](unsigned i) const
+ line_graph_neighborhood_bkd_piter<P, N>::operator[](unsigned i) const
{
assert(i < dim);
return p_[i];
}
- template <typename P>
+ template <typename P, typename N>
inline
std::ostream&
operator<<(std::ostream& ostr,
- const line_graph_neighborhood_bkd_piter<P>& p)
+ const line_graph_neighborhood_bkd_piter<P, N>& p)
{
return ostr << p.to_psite();
}
Index: mln/core/line_graph_elt_neighborhood.hh
--- mln/core/line_graph_elt_neighborhood.hh (revision 1813)
+++ mln/core/line_graph_elt_neighborhood.hh (working copy)
@@ -28,17 +28,11 @@
#ifndef MLN_CORE_LINE_GRAPH_ELT_NEIGHBORHOOD_HH
# define MLN_CORE_LINE_GRAPH_ELT_NEIGHBORHOOD_HH
-/*! \file mln/core/line_graph_elt_neighborhood.hh
- *
- * \brief Definition of the elementary ``window'' on a line graph.
- *
- * \todo Make naming coherent: we have window (without '_') but
- * point_, neighb_, etc.
- */
+/// \file mln/core/line_graph_elt_neighborhood.hh
+/// \brief Definition of the elementary ``window'' on a line graph.
-# include <mln/core/concept/neighborhood.hh>
-# include <mln/core/line_graph_psite.hh>
-# include <mln/core/line_graph_neighborhood_piter.hh>
+/* FIXME: Have a consistent naming: we have window (without '_') but
+ point_, neighb_, etc. */
/* FIXME: Factor those classes:
- mln::graph_elt_window
@@ -46,17 +40,19 @@
- mln::line_graph_elt_window
- mln::line_graph_elt_neighborhood. */
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/line_graph_psite.hh>
+# include <mln/core/line_graph_neighborhood_piter.hh>
+
+
namespace mln
{
// Fwd decls.
- template <typename P> class line_graph_neighborhood_fwd_piter;
- template <typename P> class line_graph_neighborhood_bkd_piter;
+ template <typename P, typename N> class line_graph_neighborhood_fwd_piter;
+ template <typename P, typename N> class line_graph_neighborhood_bkd_piter;
- /*! \brief Elementary neighborhood on line graph class.
- *
- * FIXME: Doc.
- */
+ /// \brief Elementary neighborhood on line graph class.
template <typename P>
class line_graph_elt_neighborhood
: public Neighborhood< line_graph_elt_neighborhood<P> >
@@ -66,29 +62,69 @@
public:
/// Associated types.
/// \{
- /// The type of point stored into the neighborhood.
- // FIXME: Is this right, if we consider that this neighborhood stores
- // psites, not points?
+ /// The type of point corresponding to the neighborhood.
typedef P point;
+ /// The type of psite corresponding to the neighborhood.
+ typedef line_graph_psite<P> psite;
// FIXME: This is a dummy value.
typedef void dpoint;
- /*! \brief Point_Iterator type to browse the points of a generic
- * neighborhood w.r.t. the ordering of delta-points.
- */
- typedef line_graph_neighborhood_fwd_piter<P> fwd_niter;
-
- /*! \brief Point_Iterator type to browse the points of a generic
- * neighborhood w.r.t. the reverse ordering of delta-points.
- */
- typedef line_graph_neighborhood_bkd_piter<P> bkd_niter;
+ /// \brief Point_Iterator type to browse the psites of the
+ /// neighborhood w.r.t. the ordering of edges.
+ typedef line_graph_neighborhood_fwd_piter<P, self_> fwd_niter;
+
+ /// \brief Point_Iterator type to browse the psites of the
+ /// neighborhood w.r.t. the reverse ordering of edges.
+ typedef line_graph_neighborhood_bkd_piter<P, self_> bkd_niter;
/// The default qiter type.
typedef fwd_niter niter;
/// \}
+
+ /// Services for iterators.
+ /// \{
+ /// Move \a piter to the beginning of the iteration on this neighborhood.
+ template <typename Piter>
+ void start(Point_Iterator<Piter>& piter) const;
+ /// Move \a piter to the next site on this neighborhood.
+ template <typename Piter>
+ void next_(Point_Iterator<Piter>& piter) const;
+ /// \}
};
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename P>
+ template <typename Piter>
+ inline
+ void
+ line_graph_elt_neighborhood<P>::start(Point_Iterator<Piter>& piter_) const
+ {
+ Piter& piter = exact(piter_);
+ piter.first_();
+ if (!piter.adjacent_or_equal_to_p_ref_())
+ next_(piter);
+ }
+
+ template <typename P>
+ template <typename Piter>
+ inline
+ void
+ line_graph_elt_neighborhood<P>::next_(Point_Iterator<Piter>& piter_) const
+ {
+ Piter& piter = exact(piter_);
+ /* FIXME: This is inefficient. The graph structure should be able
+ to produce the set of adjacent nodes fast. Boost Graphs
+ probably provides adequates structures to fetch these
+ neighbors in constant time. */
+ do
+ piter.step_();
+ while (piter.is_valid() && !piter.adjacent_or_equal_to_p_ref_());
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
} // end of namespace mln
Index: tests/core/line_graph_elt_window.cc
--- tests/core/line_graph_elt_window.cc (revision 1813)
+++ tests/core/line_graph_elt_window.cc (working copy)
@@ -49,6 +49,20 @@
| Graph. |
`--------*/
+ /* The graph is as follows and its corresponding line graph are as
+ follows:
+
+ 0 1 2 3 4 0 1 2 3 4
+ .----------- .-----------
+ | |
+ 0 | 0 2 0 | * *
+ 1 | \ / | 1 | 0 1 |
+ 2 | 1 | 2 | * 4
+ 3 | \ | 3 | 2 |
+ 4 | 3-4 4 | *3*
+
+ */
+
// Points associated to nodes.
std::vector<p_t> points;
points.push_back(make::point2d(0,0)); // Point associated to node 0.
@@ -76,7 +90,18 @@
// Line graph psite set.
p_line_graph<p_t> plg(g);
// Line graph point site.
- line_graph_psite<p_t> psite(plg, 0);
+ line_graph_psite<p_t> p(plg, 1);
// ``Sliding'' window of a psite of PLG.
- line_graph_elt_window<p_t> win;
+ typedef line_graph_elt_window<p_t> win_t;
+ win_t win;
+
+ mln_fwd_qiter_(win_t) fq(win, p);
+ for_all(fq)
+ std::cout << fq << " ";
+ std::cout << std::endl;
+
+ mln_bkd_qiter_(win_t) bq(win, p);
+ for_all(bq)
+ std::cout << bq << " ";
+ std::cout << std::endl;
}
Index: tests/core/line_graph_elt_neighborhood.cc
--- tests/core/line_graph_elt_neighborhood.cc (revision 1813)
+++ tests/core/line_graph_elt_neighborhood.cc (working copy)
@@ -25,15 +25,15 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/core/line_graph_elt_window.cc
+/*! \file tests/core/line_graph_elt_neighborhood.cc
*
- * \brief Tests on mln::line_graph_elt_window.
+ * \brief Tests on mln::line_graph_elt_neighborhood.
*/
#include <vector>
#include <mln/core/point2d.hh>
-#include <mln/core/line_graph_elt_window.hh>
+#include <mln/core/line_graph_elt_neighborhood.hh>
#include <mln/debug/iota.hh>
#include <mln/debug/println.hh>
@@ -49,6 +49,20 @@
| Graph. |
`--------*/
+ /* The graph is as follows and its corresponding line graph are as
+ follows:
+
+ 0 1 2 3 4 0 1 2 3 4
+ .----------- .-----------
+ | |
+ 0 | 0 2 0 | * *
+ 1 | \ / | 1 | 0 1 |
+ 2 | 1 | 2 | * 4
+ 3 | \ | 3 | 2 |
+ 4 | 3-4 4 | *3*
+
+ */
+
// Points associated to nodes.
std::vector<p_t> points;
points.push_back(make::point2d(0,0)); // Point associated to node 0.
@@ -69,14 +83,25 @@
g.add_edge(3, 4);
g.add_edge(4, 2);
- /*------------------.
- | Graph and window. |
- `------------------*/
+ /*-------------------------.
+ | Graph and neighborhood. |
+ `-------------------------*/
// Line graph psite set.
p_line_graph<p_t> plg(g);
// Line graph point site.
- line_graph_psite<p_t> psite(plg, 0);
- // ``Sliding'' window of a psite of PLG.
- line_graph_elt_window<p_t> win;
+ line_graph_psite<p_t> p(plg, 1);
+ // ``Sliding'' neighborhood of a psite of PLG.
+ typedef line_graph_elt_neighborhood<p_t> nbh_t;
+ nbh_t nbh;
+
+ mln_fwd_niter_(nbh_t) fq(nbh, p);
+ for_all(fq)
+ std::cout << fq << " ";
+ std::cout << std::endl;
+
+ mln_bkd_niter_(nbh_t) bq(nbh, p);
+ for_all(bq)
+ std::cout << bq << " ";
+ std::cout << std::endl;
}
1
0
https://svn.lrde.epita.fr/svn/oln/trunk
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Fix naive DT in Etienne's sandbox.
* milena/sandbox/folio/naive.cc: Fix.
naive.cc | 35 +++++++++++++----------------------
1 files changed, 13 insertions(+), 22 deletions(-)
Index: milena/sandbox/folio/naive.cc
--- milena/sandbox/folio/naive.cc (revision 1812)
+++ milena/sandbox/folio/naive.cc (working copy)
@@ -35,6 +35,7 @@
# define MLN_DT_NAIVE_HH
# include <mln/core/concept/image.hh>
+# include <mln/core/concept/function.hh>
# include <mln/literal/zero.hh>
# include <mln/accu/min.hh>
@@ -56,8 +57,8 @@
*/
template <typename I, typename F>
inline
- mln_ch_value(I, typename F::ret)
- naive(const Image<I>& input_, F& fun_);
+ mln_ch_value(I, mln_result(F))
+ naive(const Image<I>& input_, const Function_v2v<F>& fun_);
# ifndef MLN_INCLUDE_ONLY
@@ -66,14 +67,15 @@
template <typename I, typename F>
inline
- mln_ch_value(I, typename F::ret)
- naive(const Image<I>& input_, F& fun_)
+ mln_ch_value(I, mln_result(F))
+ naive(const Image<I>& input_, const Function_v2v<F>& fun_)
{
const I& input = exact(input_);
+ const F& fun = exact(fun_);
mln_precondition(input.has_data());
- mln_ch_value(I, typename F::ret) output;
- initialize(input.domain());
+ mln_ch_value(I, mln_result(F)) output;
+ initialize(output, input);
mln_piter(I) p(input.domain());
for_all(p)
@@ -83,7 +85,7 @@
else
{
// p is in the background so the distance has to be computed.
- accu::min_<typename F::ret> min;
+ accu::min_<mln_result(F)> min;
min.init();
mln_piter(I) q(input.domain());
@@ -93,7 +95,7 @@
// q is in the object.
// metal::vec<2, int> vp = p.to_point(), vq = q.to_point();
// min.take(fun_(vp, vq));
- min.take(fun_(p, q));
+ min.take(fun(p - q));
}
output(p) = min;
}
@@ -114,18 +116,7 @@
#include <mln/debug/println.hh>
#include <mln/core/image2d.hh>
#include <mln/level/fill.hh>
-#include <mln/norm/l2.hh>
-
-struct l2norm
-{
- typedef float ret;
- template <typename C, typename D>
- D
- operator()(C a, C b)
- {
- return mln::norm::l2(a, b);
- }
-};
+#include <mln/fun/v2v/norm.hh>
int main()
{
@@ -142,8 +133,8 @@
level::fill(ima, vals);
debug::println(ima);
- l2norm fun;
- image2d<float> out = dt::naive(ima, fun);
+ typedef fun::v2v::l2_norm< algebra::vec<2,float>, float > L2;
+ image2d<float> out = dt::naive(ima, L2());
std::cerr << "Distance:" << std::endl;
debug::println(out);
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Ugo Jardonnet <jardonnet(a)lrde.epita.fr>
Sandbox: ICP: use of projection maps.
* mln/binarization/thresholding.hh: Renamed as
* mln/binarization/threshold.hh.
* sandbox/jardonnet/test/icp.cc: Update: maps.
* sandbox/jardonnet/registration/icp.hh: .
* sandbox/jardonnet/registration/projection.hh: .
mln/binarization/threshold.hh | 18 +++----
sandbox/jardonnet/registration/icp.hh | 63
+++++++++++----------------
sandbox/jardonnet/registration/jacobi.hh | 2
sandbox/jardonnet/registration/projection.hh | 25 +++++++++-
sandbox/jardonnet/test/icp.cc | 4 -
5 files changed, 61 insertions(+), 51 deletions(-)
Index: mln/binarization/threshold.hh
--- mln/binarization/threshold.hh (revision 1811)
+++ mln/binarization/threshold.hh (working copy)
@@ -25,10 +25,10 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_BINARIZATION_THRESHOLDING_HH
-# define MLN_BINARIZATION_THRESHOLDING_HH
+#ifndef MLN_BINARIZATION_THRESHOLD_HH
+# define MLN_BINARIZATION_THRESHOLD_HH
-/*! \file mln/binarization/thresholding.hh
+/*! \file mln/binarization/threshold.hh
*
* \brief Threshold the contents of an image into another binary one.
*/
@@ -55,7 +55,7 @@
*/
template <typename I>
mln_concrete_ch_value(I, bool)
- thresholding(const Image<I>& input, const mln_value(I) threshold);
+ threshold(const Image<I>& input, const mln_value(I) threshold);
# ifndef MLN_INCLUDE_ONLY
@@ -63,9 +63,9 @@
template <typename I>
inline
mln_concrete_ch_value(I, bool)
- thresholding(const Image<I>& input, const mln_value(I) threshold)
+ threshold(const Image<I>& input, const mln_value(I) value)
{
- trace::entering("binarization::thresholding");
+ trace::entering("binarization::threshold");
mln_precondition(exact(input).has_data());
mlc_is(mln_trait_value_nature(mln_value(I)),
@@ -73,10 +73,10 @@
mln_concrete_ch_value(I, bool) output(exact(input).domain());
- fun::v2b::threshold< mln_value(I) > f(threshold);
+ fun::v2b::threshold< mln_value(I) > f(value);
output = binarization::binarization(exact(input), f);
- trace::exiting("binarization::thresholding");
+ trace::exiting("binarization::threshold");
return output;
}
@@ -87,4 +87,4 @@
} // end of namespace mln
-#endif // ! MLN_BINARIZATION_THRESHOLDING_HH
+#endif // ! MLN_BINARIZATION_THRESHOLD_HH
Index: sandbox/jardonnet/test/icp.cc
--- sandbox/jardonnet/test/icp.cc (revision 1811)
+++ sandbox/jardonnet/test/icp.cc (working copy)
@@ -15,8 +15,6 @@
io::pbm::load(img1, argv[1]);
io::pbm::load(img2, argv[2]);
- image2d< bool > res(img1.domain());
-
- io::pbm::save(registration::icp(img1,img2,res), "./+registred.pbm");
+ io::pbm::save(registration::icp(img1,img2), "./+registred.pbm");
}
Index: sandbox/jardonnet/registration/jacobi.hh
--- sandbox/jardonnet/registration/jacobi.hh (revision 1811)
+++ sandbox/jardonnet/registration/jacobi.hh (working copy)
@@ -7,9 +7,11 @@
// from num. rec. in C
+
namespace mln
{
+
#define rotateJacobi(a,i,j,k,l) g=a(i,j);h=a(k,l);a(i,j)=g-s*(h+g*tau); \
a(k,l)=h+s*(g-h*tau);
Index: sandbox/jardonnet/registration/icp.hh
--- sandbox/jardonnet/registration/icp.hh (revision 1811)
+++ sandbox/jardonnet/registration/icp.hh (working copy)
@@ -54,10 +54,9 @@
*/
template <typename I, typename J>
inline
- I
+ mln_concrete(I)
icp(const Image<I>& cloud,
- const Image<J>& surface,
- I& r);
+ const Image<J>& surface);
# ifndef MLN_INCLUDE_ONLY
@@ -66,23 +65,17 @@
template <typename P, typename T1, typename T2>
inline
- void
+ p_array<P>
icp_(const p_array<P>& C,
- const p_array<P>& X,
- std::pair<T1,T2>&,
- p_array<P>& Ck)
+ const p_array<P>&,
+ std::pair<T1,T2>& map)
{
trace::entering("registration::impl::icp_");
unsigned int k;
quat7<P::dim> old_qk, qk;
float err, err_bis;
-
- assert(Ck.npoints() == C.npoints());
- p_array<P> Xk(C); //FIXME:is it correct?
- /// Ck.reserve(C.npoints());
- //Xk.reserve(C.npoints());
- //assert(C.npoints() != 0);
+ p_array<P> Ck(C), Xk(C);
algebra::vec<P::dim,float> mu_C = center(C), mu_Xk;
@@ -93,19 +86,19 @@
Ck = C;
do {
- std::cout << "step2" << std::endl;
- //step 2 FIXME : etienne
- projection::de_base(Ck, X, Xk, err_bis);
+ std::cout << "step2: projection" << std::endl;
+ //step 2
+ err_bis = projection::fill_Xk(Ck, map, Xk);
- std::cout << "step2.1 center" << std::endl;
+ std::cout << "step2.1: center" << std::endl;
mu_Xk = center(Xk);
- std::cout << "step3" << std::endl;
+ std::cout << "step3: Compute qk" << std::endl;
// step 3
old_qk = qk;
qk = match(C, mu_C, Xk, mu_Xk);
- std::cout << "step4" << std::endl;
+ std::cout << "step4: apply qk" << std::endl;
// step 4
qk.apply_on(C, Ck); // Ck+1 = qk(C)
@@ -113,10 +106,11 @@
err = rms(Ck, Xk);
++k;
- std::cout << err << std::endl;
+ std::cout << "error is " << err << std::endl;
} while (k < 3 || (qk - old_qk).sqr_norm() > epsilon);
trace::exiting("registration::impl::icp_");
+ return Ck;
}
} // end of namespace mln::registration::impl
@@ -161,10 +155,9 @@
//Only for 2d and 3d image
template <typename I, typename J>
inline
- I
+ mln_concrete(I)
icp(Image<I>& cloud_,
- const Image<J>& surface_,
- I& r)
+ const Image<J>& surface_)
{
trace::entering("registration::icp");
mln_precondition(exact(cloud_).has_data());
@@ -178,15 +171,13 @@
std::cout << "chamfer" << std::endl;
- /*
+
//FIXME: not a chamfer. etienne?
//create a pair (distance map, closest point)
- w_window<mln_dpoint(I3d), float> chamfer;
- */
- std::pair<mln_ch_value(I3d,float),
mln_ch_value(I3d,mln_point(I3d)) > maps;
- /*
+ // window<dpoint3d> win3d;
+ w_window<dpoint3d, float> chamfer; // = make::w_window(win3d, fun);
+ std::pair<mln_ch_value(I3d,float),
mln_ch_value(I3d,mln_point(I3d)) > maps =
dt::chamfer(surface, chamfer);
- */
std::cout << "Build p_array" << std::endl;
//build p_arrays.
@@ -203,18 +194,18 @@
x.append(p2);
std::cout << "Start ICP" << std::endl;
+ p_array<mln_point(I3d)> res = impl::icp_(c, x, maps);
- p_array<mln_point(I3d)> res(c);
- impl::icp_(c, x, maps, res);
-
- //to 2d
- for (unsigned e; e < res.npoints(); e++)
+ //to 2d : projection (FIXME:if 3d)
+ mln_concrete(I) output(exact(cloud_).domain());
+ for (unsigned i; i < res.npoints(); i++)
{
- point2d p(res[e][0], res[e][1]);
- r(p) = true;
+ point2d p(res[i][0], res[i][1]);
+ output(p) = true;
}
trace::exiting("registration::icp");
+ return output;
}
# endif // ! MLN_INCLUDE_ONLY
Index: sandbox/jardonnet/registration/projection.hh
--- sandbox/jardonnet/registration/projection.hh (revision 1811)
+++ sandbox/jardonnet/registration/projection.hh (working copy)
@@ -10,6 +10,27 @@
namespace projection
{
+ template <typename P, typename T1, typename T2>
+ float fill_Xk(const p_array<P>& Ck,
+ std::pair<T1,T2>& map,
+ p_array<P>& Xk)
+ {
+ assert(Ck.npoints() == Xk.npoints());
+
+ float err = 0.f;
+
+ for (size_t i = 0; i < Ck.npoints(); ++i)
+ {
+ //x[i] := Ck[i] closest point in X
+ Xk.hook_()[i] = map.second(Ck[i]);
+ //err := Distance between Ck[i] and its closest point
+ err += map.first(Ck[i]);
+ }
+ return err /= Ck.npoints();
+ }
+
+
+
template <typename P>
void de_base(// input
const p_array<P>& Ck,
@@ -18,7 +39,7 @@
p_array<P>& Xk,
float& err)
{
- // assert(Ck.npoints() == Xk.npoints());
+ assert(Ck.npoints() == Xk.npoints());
err = 0.f;
@@ -37,13 +58,11 @@
best_x = Xj;
}
}
- if (i < Xk.npoints()) // FIXME:double hack
Xk.hook_()[i] = algebra::to_point<P>(best_x);
err += best_d;
}
err /= Ck.npoints();
}
-
}
}
1
0
https://svn.lrde.epita.fr/svn/oln/trunk
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Augment doc about image types.
* milena/doc/tutorial/image_types.txt: Augment.
image_types.txt | 220 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 216 insertions(+), 4 deletions(-)
Index: milena/doc/tutorial/image_types.txt
--- milena/doc/tutorial/image_types.txt (revision 1810)
+++ milena/doc/tutorial/image_types.txt (working copy)
@@ -24,10 +24,141 @@
signature is "ima(p : psite) : rvalue"
-** about domain and destination
+** about domain, site, and psite
-ima.domain is usually a mathematical set. Yet it can be a
-multiset (a bag) but then weird things might happen...
+*** need for psite
+
+Sometimes, accessing a value in constant-time complexity, O(1), is not
+possible with a site object.
+
+Example with a run-length encoded image :
+
+ c 6 7 8 9
+ r
+ +-+-+-+
+ 3 | |x| |
+ +-+-+-+-+
+ 4 | | |
+ +-+-+
+
+The site x is the point (3, 7). The image values are stored in a
+multi-array where the first index is the one of the run and the second
+index the offset of the cell from the beginning of the run. The site
+x thus corresponds to the cell (0, 1).
+
+ j= 0 1 2
+ +-+-+-+
+i= 0 | |x| |
+ +-+-+-+-+
+i= 1 | | |
+ +-+-+
+ j= 0 1
+
+Here we have:
+
+ I::site = point2d but I::psite = run_point2d
+
+where, roughly, run_point2d = { i_of_run, i_in_run, run_ptr }.
+
+
+*** from psite to site
+
+Consider that we have an image type I such as I::site != I::psite. In
+that case, an object of type I::psite is convertible towards an object
+of type I::site. Furthermore, a psite shall behave as if it was a
+site.
+
+Design note: it seems impossible to offer through the interface of
+some psite what is expected from its corresponding site. For
+instance, when a site has a given feature, say a method "m", then this
+method has to appear in the psite interface. Idea: thanks to
+inheritance, we fetch an interface + an implementation that delegates
+to the site.
+
+Example: run_point2d has a method ::row() because point2d provides
+such a method. How it works: a psite inherits from
+internal::site_impl<site> which is specialized for every site type;
+for instance, internal::site_impl<point2d> owns the method "coord
+row() const" which is defined as "return exact(this)->to_site().row()"
+
+This is of course only true for read-only methods.
+
+
+*** site location
+
+A point of a space (the 2D plane or 3D space) is about equivalent to a
+vector. We do not distinguish between those two notions: a point M is
+like the vector OM where O is the origin of the space.
+
+We have mln::vec<dim,coord> (space vector) built over
+metal::array<n,T> (static container). When dim = 2, we have vec::x()
+and vec::y() to access the coordinates, in addition to the more
+general method vec::op[](i). On the other side, we have
+array::element<i>() to access the i-th element.
+
+We do not ambiguity: grid point 2d (i,j) v. 2D plane point
+(x,y) v. 2D vector (x,y)
+
+ideas: gpoint2d v. spoint2d !!!
+
+
+*** iterating and ordering
+
+The iteration mechanism for images is directly derived from the
+mechanism for site set. A site set is iterable in a forward way.
+This way depends on the structure of the set; Cf. the documentation.
+The reserve iteration way, called backward, can always be defined
+because we only provide bidirectional containers. The ordering
+relationship corresponding to the forward iteration browsing is
+"fwd_less".
+
+The basic iterator has the only property of browsing every site once.
+It is often identical to the forward iterator but it is not a
+requirement. FIXME: find an example where it is not the case.
+
+When sites are localized, a special ordering between such sites is
+defined, based on the site localization. More precisely, it is a
+lexicographical ordering considering the coordinates going from the
+first component (at index 0) to the last one (at index dim - 1). This
+is location_less. In most cases, we cannot provide an iterator that
+follows this spatial ordering because the underlying structures are
+usually not suited for such an iterator to be efficient.
+
+FIXME: hypothesis and property for superior_window and inferior_window.
+
+
+*** arithmetics over sites
+
+psite + dpsite -> psite when compatible (?)
+ site + dpsite = (re-written) site + dsite (when possible) -> site
+psite + dsite = (re-written) site + dsite (when possible) -> site
+
+Example:
+run_psite2d + dpoint2d -> point2d
+
+
+FIXME: more examples
+
+
+** about value, rvalue, and lvalue
+
+Image types provide a method to access values, namely "operator() const".
+Yet, its signature is NOT "value operator()(const site& p) const"
+but "rvalue operator()(const psite& p) const"
+
+For instance, with I being image2d<int_u8>, we have :
+
+ I::value = int_u8 but I::rvalue = const int_u8&
+
+so copying the value when the call "f(p)" returns is avoided.
+In that case, it is a low-level implementation issue that makes rvalue
+be different from value. In some other cases, the difference can be
+more fundamental. For instance, a proxy is returned so that some extra
+code is performed if this value is eventually read (FIXME: take a better
+example).
+
+
+** about destination
ima.destination is a set. Every value, that is ima(p) with p in
ima.domain, is taken from this set. For instance, a color image can
@@ -215,6 +346,8 @@
** associated types
+*** list of associated types
+
mesh (? support)
pset (? domain_t)
site
@@ -233,6 +366,41 @@
skeleton
+*** value
+Type of values enclosed in the image container.
+By copie; not by reference (not T&).
+Might be a pointer (T*).
+Assignable and copiable (not a shallow copy).
+
+Ex: int_u8, etc.
+
+*** site
+Type of the cell containing a value.
+
+*** required for implementation purpose
+rvalue, lvalue, and psite; see later.
+
+*** location
+A site can be localized into a given space, e.g., the 2D plane and can
+be point-wise. In that case, the associated type "location" gives the
+corresponding type of space vector. For instance, with a classical 2D
+image, a site is a 2D point (node of the regular square grid) and the
+location is trivially a vector of the 2D plane.
+
+When a site is not point-wise, some implementation can also provide a
+location; this can be convenient in order to get a spacial
+representation of sites and images. For instance, consider that we
+have a tesselation computed from point seeds (a Voronoi diagram for
+instance) and a structure (the corresponding Delaunay triangulation)
+where a site is a tile of this tesselation. A tile can be identified
+without ambiguity through its seed; this seed point is then the
+representative point for that tile. By extension, we can state that
+the location of a tile is its seed.
+
+For some image types, sites are not localized and a special type is
+used to define ::location.
+
+
** methods
@@ -551,6 +719,13 @@
** image2d<T>
+regular square grid where grid nodes are objects of type point2d +(row, col), a couple of integer coordinates
+
+psite = point2d = point_<grid2d,int>
+site = point2d
+location = vec<2,int> (more precise than vec<2,float>)
+
** fun_image<S,F>
pset = S
@@ -558,6 +733,43 @@
read_only
+** geometrical transformation (morpher)
+
+An image computed on the fly from another image on which a geometrical
+transformation is applied. A geometrical transformation is either a
+function
+
+ site_set -> site_set
+ site |-> site
+
+or a function
+
+ site_set_in -> site_set_out
+ site_in |-> site_out
+
+In the first case, the resulting image has the same point set as the
+initial image (example : clock-wise rotation of 90°, translation of a
+vector with integral coordinates).
+
+In the second case, the resulting image has a different point set,
+reflecting a possibly different domain or topology (example: arbitrary
+rotation).
+
+
+images (f, T) -> g
+
+
+g(p) = f( T(p) )
+so :
+g( T_1(p) ) = f(p)
+
+or :
+
+g( T(p) ) = f(p)
+
+
+FIXME: to be continued.
+
* value morpher
-pset is
\ No newline at end of file
+FIXME
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Sandbox: ICP: draft improvment.
* sandbox/jardonnet/test/Makefile: -O3 version.
* sandbox/jardonnet/test/icp.cc: image loading.
* sandbox/jardonnet/registration/quat7.hh: Update.
* sandbox/jardonnet/registration/chamfer.hh: Etienne's.
* sandbox/jardonnet/registration/cloud.hh: Correction.
* sandbox/jardonnet/registration/icp.hh: Update.
* sandbox/jardonnet/registration/projection.hh: To be removed.
* sandbox/jardonnet/registration/quat/rotation.hh: s/3/n/.
mln/make/mat.hh | 2
sandbox/folio/naive.cc | 14 +
sandbox/jardonnet/registration/chamfer.hh | 189 ++++++++++++++++++++++++
sandbox/jardonnet/registration/cloud.hh | 7
sandbox/jardonnet/registration/icp.hh | 124 +++++++++++++--
sandbox/jardonnet/registration/projection.hh | 3
sandbox/jardonnet/registration/quat/rotation.hh | 7
sandbox/jardonnet/registration/quat7.hh | 5
sandbox/jardonnet/test/Makefile | 3
sandbox/jardonnet/test/icp.cc | 16 +-
10 files changed, 334 insertions(+), 36 deletions(-)
Index: mln/make/mat.hh
--- mln/make/mat.hh (revision 1809)
+++ mln/make/mat.hh (working copy)
@@ -71,7 +71,7 @@
{
algebra::mat<n,1,T> tmp;
for (unsigned i = 0; i < n; i++)
- tmp(i,1) = v[i];
+ tmp(i,0) = v[i];
return tmp;
}
Index: sandbox/jardonnet/test/icp.cc
--- sandbox/jardonnet/test/icp.cc (revision 1809)
+++ sandbox/jardonnet/test/icp.cc (working copy)
@@ -1,16 +1,22 @@
#include <mln/core/image3d.hh>
-#include <mln/io/ppm/load.hh>
-#include <mln/io/ppm/save.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pbm/save.hh>
#include <sandbox/jardonnet/registration/icp.hh>
-int main(int, char*)
+int main(int, char* argv[])
{
using namespace mln;
- image3d< value::rgb8 > img;
+ image2d< bool > img1;
+ image2d< bool > img2;
- registration::icp(img,img);
+ io::pbm::load(img1, argv[1]);
+ io::pbm::load(img2, argv[2]);
+
+ image2d< bool > res(img1.domain());
+
+ io::pbm::save(registration::icp(img1,img2,res), "./+registred.pbm");
}
Index: sandbox/jardonnet/test/Makefile
--- sandbox/jardonnet/test/Makefile (revision 1809)
+++ sandbox/jardonnet/test/Makefile (working copy)
@@ -16,6 +16,9 @@
icp:
g++ icp.cc $(FLAG) -o '+icp.exe'
+icp++:
+ g++ icp.cc -I../../.. -O3 -o '+icp.exe'
+
run:
time ./+sub.exe . . ; time ./+gsub.exe . .
Index: sandbox/jardonnet/registration/quat7.hh
--- sandbox/jardonnet/registration/quat7.hh (revision 1809)
+++ sandbox/jardonnet/registration/quat7.hh (working copy)
@@ -122,20 +122,23 @@
// qR
//FIXME : use P::dim ?
+ std::cout << "loop" << std::endl;
algebra::mat<P::dim,P::dim,float> Mk;
for (unsigned i = 0; i < C.npoints(); ++i)
{
algebra::vec<P::dim,float> Ci = C[i];
- algebra::vec<P::dim,float> Xki = Xki;
+ algebra::vec<P::dim,float> Xki = Xk[i];
Mk += make::mat(Ci - mu_C) * trans(make::mat(Xki - mu_Xk));
}
Mk /= C.npoints();
+ std::cout << "loop end" << std::endl;
const algebra::mat<P::dim,P::dim,float> Ak = Mk - trans(Mk);
const float v[3] = {Ak(1,2), Ak(2,0), Ak(0,1)};
const algebra::mat<3,1,float> D = make::mat<3,1,3,float>(v); // FIXME why <...>
+
algebra::mat<4,4,float> Qk;
Qk(0,0) = tr(Mk);
put(trans(D), 0,1, Qk);
Index: sandbox/jardonnet/registration/chamfer.hh
--- sandbox/jardonnet/registration/chamfer.hh (revision 0)
+++ sandbox/jardonnet/registration/chamfer.hh (revision 0)
@@ -0,0 +1,189 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_DT_CHAMFER_HH
+# define MLN_DT_CHAMFER_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/w_window.hh>
+
+namespace mln
+{
+
+ namespace dt
+ {
+
+ /*! Distance tranform by chamfer application.
+ *
+ * \param[in] input_ The input image.
+ * \param[in] chamfer The chamfer window to use for distance calcul.
+ * \return A pair (distance map, nearest point map).
+ *
+ * \pre \p img has to be initialized.
+ */
+ template<typename I, typename T>
+ std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+ chamfer(const Image<I>& input_,
+ w_window<mln_dpoint(I), T> chamfer);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ /*! Computes a pass of the chamfer DT algorithm.
+ *
+ * \param[in] p Iterator on the input image to use.
+ * \param[in] chamfer The chamfer window to use for distance calcul.
+ * \param[in] input The input image.
+ * \param[out] outputDistance The distance map updated.
+ * \param[out] outputnearest The nearest points map updated.
+ */
+ template<typename Q, typename I, typename T>
+ inline
+ void
+ chamfer_pass(const w_window<mln_dpoint(I), T> chamfer,
+ const I& input,
+ mln_ch_value(I, T)& outputDistance,
+ mln_ch_value(I, mln_point(I))& outputNearest)
+ {
+ typedef w_window<mln_dpoint(I), T> W;
+
+ Q p(input.domain());
+ mln_qiter(W) q(chamfer, p);
+ for_all(p)
+ {
+ std::pair<T, mln_point(I)> min(mln_max(T), p);
+
+ for_all(q)
+ if (input.has(q) && outputDistance(q) != mln_max(T))
+ {
+ T v = outputDistance(q) + q.w();
+
+ if (v < min.first)
+ {
+ min.first = v;
+ min.second = outputNearest(q);
+ }
+ }
+
+ if (min.first < outputDistance(p))
+ {
+ outputDistance(p) = min.first;
+ outputNearest(p) = min.second;
+ }
+ }
+ }
+
+ } // end of namespace mln::dt::impl
+
+
+
+ // Facade.
+
+ template<typename I, typename T>
+ inline
+ std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+ chamfer(const Image<I>& input_,
+ w_window<mln_dpoint(I), T> chamfer)
+ {
+ typedef w_window<mln_dpoint(I), T> W;
+
+ const I& input = exact(input_);
+ mln_precondition(input.has_data());
+
+ mln_ch_value(I, T) outputDistance;
+ initialize(outputDistance, input);
+
+ mln_ch_value(I, mln_point(I)) outputNearest;
+ initialize(outputNearest, input);
+
+ // Initialization.
+ {
+ mln_fwd_piter(I) p(input.domain());
+ for_all(p)
+ {
+ outputDistance(p) = input(p) ? literal::zero : mln_max(T);
+ outputNearest(p) = p;
+ }
+ }
+
+ // First pass.
+ impl::chamfer_pass<mln_fwd_piter(I)>
+ (chamfer, input, outputDistance, outputNearest);
+
+ chamfer.sym();
+
+ // Second pass.
+ impl::chamfer_pass<mln_bkd_piter(I)>
+ (chamfer, input, outputDistance, outputNearest);
+
+ return std::pair<mln_ch_value(I, T), mln_ch_value(I, mln_point(I))>
+ (outputDistance, outputNearest);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::dt
+
+} // end of namespace mln
+
+#endif // ! MLN_DT_CHAMFER_HH
+
+// #include <iostream>
+// #include <mln/debug/println.hh>
+// #include <mln/core/image2d.hh>
+// #include <mln/make/win_chamfer.hh>
+// #include <mln/level/fill.hh>
+
+// int main()
+// {
+// using namespace mln;
+
+// w_window2d_int chamfer = make::mk_chamfer_3x3_int<3, 4>();
+
+// {
+// image2d<bool> ima(5,5);
+// bool vals[] = { 1, 1, 1, 0, 0,
+// 0, 0, 1, 0, 0,
+// 0, 0, 1, 0, 0,
+// 0, 0, 0, 0, 0,
+// 0, 0, 0, 0, 0 };
+
+// level::fill(ima, vals);
+// debug::println(ima);
+
+// std::pair<image2d<int>, image2d<mln_point_(image2d<bool>)> >
+// out = dt::chamfer(ima, chamfer);
+
+// std::cerr << "Distance:" << std::endl;
+// debug::println(out.first);
+// std::cerr << "PPP:" << std::endl;
+// debug::println(out.second);
+// }
+// }
Index: sandbox/jardonnet/registration/cloud.hh
--- sandbox/jardonnet/registration/cloud.hh (revision 1809)
+++ sandbox/jardonnet/registration/cloud.hh (working copy)
@@ -32,9 +32,12 @@
// FIXME : move //exist for P?
template <typename P>
- float sqr_norm(const P& v)
+ mln_coord(P) sqr_norm(const P& v)
{
- return v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
+ mln_coord(P) tmp = 0;
+ for (unsigned i = 0; i < P::dim; i++)
+ tmp += v[i] * v[i];
+ return tmp;
}
template <typename P>
Index: sandbox/jardonnet/registration/icp.hh
--- sandbox/jardonnet/registration/icp.hh (revision 1809)
+++ sandbox/jardonnet/registration/icp.hh (working copy)
@@ -35,14 +35,12 @@
# include <mln/algebra/quat.hh>
# include <mln/algebra/vec.hh>
-
-
-//typedef mln::algebra::vec<3, float> vec3f;
-//typedef mln::p_array< vec3f > vecs_t;
+# include <mln/core/w_window.hh>
#include "cloud.hh"
#include "quat7.hh"
#include "projection.hh"
+# include "chamfer.hh"
namespace mln
{
@@ -56,20 +54,23 @@
*/
template <typename I, typename J>
inline
- void
+ I
icp(const Image<I>& cloud,
- const Image<J>& surface);
+ const Image<J>& surface,
+ I& r);
# ifndef MLN_INCLUDE_ONLY
namespace impl
{
- template <typename P>
+ template <typename P, typename T1, typename T2>
inline
void
icp_(const p_array<P>& C,
- const p_array<P>& X)
+ const p_array<P>& X,
+ std::pair<T1,T2>&,
+ p_array<P>& Ck)
{
trace::entering("registration::impl::icp_");
@@ -77,9 +78,12 @@
quat7<P::dim> old_qk, qk;
float err, err_bis;
- p_array<P> Ck, Xk;
- Ck.reserve(C.npoints());
- Xk.reserve(Ck.npoints());
+ assert(Ck.npoints() == C.npoints());
+ p_array<P> Xk(C); //FIXME:is it correct?
+ /// Ck.reserve(C.npoints());
+ //Xk.reserve(C.npoints());
+ //assert(C.npoints() != 0);
+
algebra::vec<P::dim,float> mu_C = center(C), mu_Xk;
const float epsilon = 1e-3;
@@ -89,15 +93,19 @@
Ck = C;
do {
+ std::cout << "step2" << std::endl;
//step 2 FIXME : etienne
projection::de_base(Ck, X, Xk, err_bis);
+ std::cout << "step2.1 center" << std::endl;
mu_Xk = center(Xk);
+ std::cout << "step3" << std::endl;
// step 3
old_qk = qk;
qk = match(C, mu_C, Xk, mu_Xk);
+ std::cout << "step4" << std::endl;
// step 4
qk.apply_on(C, Ck); // Ck+1 = qk(C)
@@ -105,6 +113,7 @@
err = rms(Ck, Xk);
++k;
+ std::cout << err << std::endl;
} while (k < 3 || (qk - old_qk).sqr_norm() > epsilon);
trace::exiting("registration::impl::icp_");
@@ -113,20 +122,97 @@
} // end of namespace mln::registration::impl
- // this version could convert image cloud in a vector of point?
+ //FIXME: move?
+ namespace convert
+ {
+ template <typename T>
+ const image3d<T>&
+ to_image_3d(const image3d<T>& img)
+ {
+ return img;
+ }
+
+ template <typename T>
+ image3d<T>&
+ to_image_3d(image3d<T>& img)
+ {
+ return img;
+ }
+
+ template <typename T>
+ image3d<T>
+ to_image_3d(const image2d<T>& img)
+ {
+ point3d pmin(img.domain().pmin()[0], img.domain().pmin()[1], -10);
+ point3d pmax(img.domain().pmax()[0], img.domain().pmax()[1], 10);
+ image3d<T> img3d(box3d(pmin,pmax));
+
+ mln_piter(image3d<T>) p(img3d.domain());
+ for_all(p)
+ {
+ if (p[2] == 0)
+ img3d(p) = exact(img)(point2d(p[0],p[1]));
+ }
+ return img3d;
+ }
+ }
+
+
+ //Only for 2d and 3d image
template <typename I, typename J>
inline
- void
- icp(const Image<I>& cloud,
- const Image<J>& surface)
+ I
+ icp(Image<I>& cloud_,
+ const Image<J>& surface_,
+ I& r)
{
trace::entering("registration::icp");
- mln_precondition(exact(cloud).has_data());
- mln_precondition(exact(surface).has_data());
+ mln_precondition(exact(cloud_).has_data());
+ mln_precondition(exact(surface_).has_data());
- p_array<mln_point(I)> a,b; // FIXME : to built.
+ std::cout << "convert to image3d" << std::endl;
+ //convert to image: time consuming
+ typedef image3d<mln_value(I)> I3d;
+ I3d cloud = convert::to_image_3d(exact(cloud_));
+ const I3d surface = convert::to_image_3d(exact(surface_));
- impl::icp_(a, b);
+
+ std::cout << "chamfer" << std::endl;
+ /*
+ //FIXME: not a chamfer. etienne?
+ //create a pair (distance map, closest point)
+ w_window<mln_dpoint(I3d), float> chamfer;
+ */
+ std::pair<mln_ch_value(I3d,float), mln_ch_value(I3d,mln_point(I3d)) > maps;
+ /*
+ dt::chamfer(surface, chamfer);
+ */
+
+ std::cout << "Build p_array" << std::endl;
+ //build p_arrays.
+ p_array<mln_point(I3d)> c,x;
+
+ mln_piter(I3d) p1(cloud.domain());
+ for_all(p1)
+ if (exact(cloud)(p1))
+ c.append(p1);
+
+ mln_piter(I3d) p2(surface.domain());
+ for_all(p2)
+ if (exact(surface)(p2))
+ x.append(p2);
+
+ std::cout << "Start ICP" << std::endl;
+
+ p_array<mln_point(I3d)> res(c);
+ impl::icp_(c, x, maps, res);
+
+ //to 2d
+ for (unsigned e; e < res.npoints(); e++)
+ {
+ point2d p(res[e][0], res[e][1]);
+ r(p) = true;
+ }
trace::exiting("registration::icp");
}
Index: sandbox/jardonnet/registration/projection.hh
--- sandbox/jardonnet/registration/projection.hh (revision 1809)
+++ sandbox/jardonnet/registration/projection.hh (working copy)
@@ -18,7 +18,7 @@
p_array<P>& Xk,
float& err)
{
- assert(Ck.npoints() == Xk.npoints());
+ // assert(Ck.npoints() == Xk.npoints());
err = 0.f;
@@ -37,6 +37,7 @@
best_x = Xj;
}
}
+ if (i < Xk.npoints()) // FIXME:double hack
Xk.hook_()[i] = algebra::to_point<P>(best_x);
err += best_d;
}
Index: sandbox/jardonnet/registration/quat/rotation.hh
--- sandbox/jardonnet/registration/quat/rotation.hh (revision 1809)
+++ sandbox/jardonnet/registration/quat/rotation.hh (working copy)
@@ -35,9 +35,14 @@
assert(q.is_unit());
algebra::vec<n,float>
tmp = make::vec(rand(), rand(), rand()),
- p = tmp / norm::l2(tmp),
+ p;
+ float nl2= norm::l2(tmp);
+ if(nl2 != 0)
+ p = tmp / nl2;
+ algebra::vec<n,float>
p_rot_1 = rotate(q, p),
p_rot_2 = mat * p;
+
return about_equal(norm::l2(p_rot_1 - p_rot_2), 0.f);
}
Index: sandbox/folio/naive.cc
--- sandbox/folio/naive.cc (revision 1809)
+++ sandbox/folio/naive.cc (working copy)
@@ -54,8 +54,9 @@
*
* \fixme Use instead of R the result type of F::operator().
*/
- template <typename I, typename F, typename R>
- mln_ch_value(I, R)
+ template <typename I, typename F>
+ inline
+ mln_ch_value(I, typename F::ret)
naive(const Image<I>& input_, F& fun_);
@@ -63,15 +64,15 @@
// Facade.
- template <typename I, typename F, typename R>
+ template <typename I, typename F>
inline
- mln_ch_value(I, R)
+ mln_ch_value(I, typename F::ret)
naive(const Image<I>& input_, F& fun_)
{
const I& input = exact(input_);
mln_precondition(input.has_data());
- mln_ch_value(I, R) output;
+ mln_ch_value(I, typename F::ret) output;
initialize(input.domain());
mln_piter(I) p(input.domain());
@@ -82,7 +83,7 @@
else
{
// p is in the background so the distance has to be computed.
- accu::min_<R> min;
+ accu::min_<typename F::ret> min;
min.init();
mln_piter(I) q(input.domain());
@@ -117,6 +118,7 @@
struct l2norm
{
+ typedef float ret;
template <typename C, typename D>
D
operator()(C a, C b)
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Enable tests/core/graph_elt_neighborhood.
* tests/core/Makefile.am (check_PROGRAMS): Add
graph_elt_neighborhood.
(graph_elt_neighborhood_SOURCES): New.
Makefile.am | 2 ++
1 file changed, 2 insertions(+)
Index: tests/core/Makefile.am
--- tests/core/Makefile.am (revision 1808)
+++ tests/core/Makefile.am (working copy)
@@ -8,6 +8,7 @@
exact \
h_vec \
initialize \
+ graph_elt_neighborhood \
graph_elt_window \
graph_image \
line_graph_elt_window \
@@ -33,6 +34,7 @@
exact_SOURCES = exact.cc
h_vec_SOURCES = h_vec.cc
initialize_SOURCES = initialize.cc
+graph_elt_neighborhood_SOURCES = graph_elt_neighborhood.cc
graph_elt_window_SOURCES = graph_elt_window.cc
graph_image_SOURCES = graph_image.cc
line_graph_elt_window_SOURCES = line_graph_elt_window.cc
1
0
1807: Have piters on graph neighborhoods actually use the neighborhood.
by Roland Levillain 26 Mar '08
by Roland Levillain 26 Mar '08
26 Mar '08
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Have piters on graph neighborhoods actually use the neighborhood.
* mln/core/graph_neighborhood_piter.hh
(mln::graph_neighborhood_fwd_piter<P, W>)
(mln::graph_neighborhood_bkd_piter<P, W>):
Have these class templates take a neighborhood type as second,
additional parameter.
(mln::graph_neighborhood_fwd_piter<P, W>::nbh_)
(mln::graph_neighborhood_bkd_piter<P, W>::nbh_):
New attributes.
(mln::graph_neighborhood_fwd_piter<P, W>::graph_neighborhood_fwd_piter)
(mln::graph_neighborhood_bkd_piter<P, W>::graph_neighborhood_bkd_piter):
Adjust ctors.
(mln::graph_neighborhood_fwd_piter<P, W>::first_)
(mln::graph_neighborhood_fwd_piter<P, W>::step_)
(mln::graph_neighborhood_bkd_piter<P, W>::first_)
(mln::graph_neighborhood_bkd_piter<P, W>::step_):
New methods.
(mln::graph_neighborhood_fwd_piter<P, W>::start)
(mln::graph_neighborhood_fwd_piter<P, W>::next_)
(mln::graph_neighborhood_bkd_piter<P, W>::start)
(mln::graph_neighborhood_bkd_piter<P, W>::next_):
Delegate the body of the routine to the neighborhood.
* mln/core/graph_elt_neighborhood.hh
(mln::graph_elt_neighborhood<P>::fwd_qiter)
(mln::graph_elt_neighborhood<P>::bkd_qiter):
Adjust typedefs.
(mln::graph_elt_neighborhood<P>::psite):
New typedef.
(mln::graph_elt_neighborhood<P>::start)
(mln::graph_elt_neighborhood<P>::next_):
New methods.
* tests/core/graph_elt_neighborhood.cc: New test.
mln/core/graph_elt_neighborhood.hh | 70 +++++++--
mln/core/graph_neighborhood_piter.hh | 250 +++++++++++++++++++----------------
tests/core/graph_elt_neighborhood.cc | 22 +--
3 files changed, 205 insertions(+), 137 deletions(-)
Index: mln/core/graph_neighborhood_piter.hh
--- mln/core/graph_neighborhood_piter.hh (revision 1807)
+++ mln/core/graph_neighborhood_piter.hh (working copy)
@@ -57,16 +57,15 @@
template <typename P> class graph_psite;
- /*----------------------------------.
- | graph_neighborhood_fwd_piter<P>. |
- `----------------------------------*/
+ /*-------------------------------------.
+ | graph_neighborhood_fwd_piter<P, N>. |
+ `-------------------------------------*/
- /// \brief Forward iterator on graph neighborhood.
- template <typename P>
+ template <typename P, typename N>
class graph_neighborhood_fwd_piter :
- public Point_Iterator< graph_neighborhood_fwd_piter<P> > // or Iterator<...>?
+ public Point_Iterator< graph_neighborhood_fwd_piter<P, N> >
{
- typedef graph_neighborhood_fwd_piter<P> self_;
+ typedef graph_neighborhood_fwd_piter<P, N> self_;
typedef Point_Iterator< self_ > super_;
public:
@@ -83,7 +82,7 @@
public:
/// Construction.
/// \{
- template <typename N, typename Pref>
+ template <typename Pref>
graph_neighborhood_fwd_piter(const N& nbh, const Point_Site<Pref>& p_ref);
/// \}
@@ -115,11 +114,23 @@
/// Read-only access to the \a i-th coordinate.
coord operator[](unsigned i) const;
+ /// Internals, used by the neighborhood.
+ /// \{
+ public:
+ /// Set the iterator to the first site of the graph.
+ void first_();
+ /// Advance the position of the iterator by one step.
+ void step_();
+
+ /// An internal iterator on the set of nodes of the underlying graph.
+ util::node_id id_;
+ /// \}
+
private:
+ /// The neighborhood.
+ const N& nbh_;
/// The ``central'' psite of the neighborhood.
const psite& p_ref_;
- /// An internal iterator on the set of nodes of the underlying graph.
- util::node_id id_;
/// The psite corresponding to this iterator.
psite psite_;
/// The point corresponding to this iterator.
@@ -127,16 +138,15 @@
};
- /*----------------------------------.
- | graph_neighborhood_bkd_piter<P>. |
- `----------------------------------*/
+ /*-------------------------------------.
+ | graph_neighborhood_bkd_piter<P, N>. |
+ `-------------------------------------*/
- /// \brief Backward iterator on graph neighborhood.
- template <typename P>
+ template <typename P, typename N>
class graph_neighborhood_bkd_piter :
- public Point_Iterator< graph_neighborhood_bkd_piter<P> > // or Iterator<...>?
+ public Point_Iterator< graph_neighborhood_bkd_piter<P, N> >
{
- typedef graph_neighborhood_bkd_piter<P> self_;
+ typedef graph_neighborhood_bkd_piter<P, N> self_;
typedef Point_Iterator< self_ > super_;
public:
@@ -153,7 +163,7 @@
public:
/// Construction.
/// \{
- template <typename N, typename Pref>
+ template <typename Pref>
graph_neighborhood_bkd_piter(const N& nbh, const Point_Site<Pref>& p_ref);
/// \}
@@ -185,11 +195,23 @@
/// Read-only access to the \a i-th coordinate.
coord operator[](unsigned i) const;
+ /// Internals, used by the neighborhood.
+ /// \{
+ public:
+ /// Set the iterator to the first site of the graph.
+ void first_();
+ /// Advance the position of the iterator by one step.
+ void step_();
+
+ /// An internal iterator on the set of nodes of the underlying graph.
+ util::node_id id_;
+ /// \}
+
private:
+ /// The neighborhood.
+ const N& nbh_;
/// The ``central'' psite of the neighborhood.
const psite& p_ref_;
- /// An internal iterator on the set of nodes of the underlying graph.
- util::node_id id_;
/// The psite corresponding to this iterator.
psite psite_;
/// The point corresponding to this iterator.
@@ -200,17 +222,17 @@
# ifndef MLN_INCLUDE_ONLY
- /*----------------------------------.
- | graph_neighborhood_fwd_piter<P>. |
- `----------------------------------*/
-
- // FIXME: Currently, argument nbh is ignored.
- template <typename P>
- template <typename N, typename Pref>
+ /*-------------------------------------.
+ | graph_neighborhood_fwd_piter<P, N>. |
+ `-------------------------------------*/
+
+ template <typename P, typename N>
+ template <typename Pref>
inline
- graph_neighborhood_fwd_piter<P>::graph_neighborhood_fwd_piter(const N& /* nbh */,
+ graph_neighborhood_fwd_piter<P, N>::graph_neighborhood_fwd_piter(const N& nbh,
const Point_Site<Pref>& p_ref)
- : p_ref_(exact(p_ref).to_psite()),
+ : nbh_(exact(nbh)),
+ p_ref_(exact(p_ref).to_psite()),
// Initialize psite_ to a dummy value.
psite_(),
p_()
@@ -219,10 +241,10 @@
invalidate();
}
- template <typename P>
+ template <typename P, typename N>
inline
bool
- graph_neighborhood_fwd_piter<P>::is_valid() const
+ graph_neighborhood_fwd_piter<P, N>::is_valid() const
{
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
@@ -230,60 +252,63 @@
return p_ref_.is_valid() && id_ < p_ref_.pg().gr_->nnodes();
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- graph_neighborhood_fwd_piter<P>::invalidate()
+ graph_neighborhood_fwd_piter<P, N>::invalidate()
{
- id_ = -1
+ id_ = -1;
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- graph_neighborhood_fwd_piter<P>::start()
+ graph_neighborhood_fwd_piter<P, N>::start()
{
- id_ = 0;
- if (!adjacent_or_equal_to_p_ref_())
- next_();
- /* FIXME: This is redundant with the end of next_(), but we might
- change the implementation of start_() when we'll fix it later,
- and no longer use next_(). */
+ nbh_.start(*this);
if (is_valid())
update_();
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- graph_neighborhood_fwd_piter<P>::next_()
+ graph_neighborhood_fwd_piter<P, N>::next_()
{
- /* FIXME: This is inefficient. The graph structure should be able
- to produce the set of adjacent nodes fast. Boost Graphs
- probably provides adequates structures to fetch these
- neighbors in constant time. */
- /* FIXME: Moreover, the behavior of next shall depend on the
- neighborhood, which is not the case now! (Currently, next_() behaves
- as nbh was always an elementary neighborhood.) */
- do
- ++id_;
- while (is_valid() && !adjacent_or_equal_to_p_ref_());
+ nbh_.next_(*this);
if (is_valid())
update_();
}
- template <typename P>
+ template <typename P, typename N>
+ inline
+ void
+ graph_neighborhood_fwd_piter<P, N>::first_()
+ {
+ id_ = 0;
+ }
+
+ template <typename P, typename N>
+ inline
+ void
+ graph_neighborhood_fwd_piter<P, N>::step_()
+ {
+ ++id_;
+ }
+
+
+ template <typename P, typename N>
inline
bool
- graph_neighborhood_fwd_piter<P>::adjacent_or_equal_to_p_ref_() const
+ graph_neighborhood_fwd_piter<P, N>::adjacent_or_equal_to_p_ref_() const
{
return p_ref_.pg().adjacent_or_equal(p_ref_.id(), id_);
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- graph_neighborhood_fwd_piter<P>::update_()
+ graph_neighborhood_fwd_piter<P, N>::update_()
{
// Update psite_.
psite_ = graph_psite<P>(p_ref_.pg(), id_);
@@ -291,51 +316,51 @@
p_ = p_ref_.pg().gr_->node_data(id_);
}
- template <typename P>
+ template <typename P, typename N>
inline
const P&
- graph_neighborhood_fwd_piter<P>::to_point() const
+ graph_neighborhood_fwd_piter<P, N>::to_point() const
{
return p_;
}
- template <typename P>
+ template <typename P, typename N>
inline
const graph_psite<P>&
- graph_neighborhood_fwd_piter<P>::to_psite() const
+ graph_neighborhood_fwd_piter<P, N>::to_psite() const
{
return psite_;
}
- template <typename P>
+ template <typename P, typename N>
inline
- graph_neighborhood_fwd_piter<P>::operator graph_psite<P>() const
+ graph_neighborhood_fwd_piter<P, N>::operator graph_psite<P>() const
{
mln_precondition(is_valid());
return psite_;
}
- template <typename P>
+ template <typename P, typename N>
inline
mln_coord(P)
- graph_neighborhood_fwd_piter<P>::operator[](unsigned i) const
+ graph_neighborhood_fwd_piter<P, N>::operator[](unsigned i) const
{
assert(i < dim);
return p_[i];
}
- /*----------------------------------.
- | graph_neighborhood_bkd_piter<P>. |
- `----------------------------------*/
-
- // FIXME: Currently, argument nbh is ignored.
- template <typename P>
- template <typename N, typename Pref>
+ /*-------------------------------------.
+ | graph_neighborhood_bkd_piter<P, N>. |
+ `-------------------------------------*/
+
+ template <typename P, typename N>
+ template <typename Pref>
inline
- graph_neighborhood_bkd_piter<P>::graph_neighborhood_bkd_piter(const N& /* nbh */,
+ graph_neighborhood_bkd_piter<P, N>::graph_neighborhood_bkd_piter(const N& nbh,
const Point_Site<Pref>& p_ref)
- : p_ref_(exact(p_ref).to_psite()),
+ : nbh_(nbh),
+ p_ref_(exact(p_ref).to_psite()),
// Initialize psite_ to a dummy value.
psite_(),
p_()
@@ -344,10 +369,10 @@
invalidate();
}
- template <typename P>
+ template <typename P, typename N>
inline
bool
- graph_neighborhood_bkd_piter<P>::is_valid() const
+ graph_neighborhood_bkd_piter<P, N>::is_valid() const
{
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
@@ -355,60 +380,63 @@
return p_ref_.is_valid() && id_ < p_ref_.pg().gr_->nnodes();
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- graph_neighborhood_bkd_piter<P>::invalidate()
+ graph_neighborhood_bkd_piter<P, N>::invalidate()
{
id_ = -1;
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- graph_neighborhood_bkd_piter<P>::start()
+ graph_neighborhood_bkd_piter<P, N>::start()
{
- id_ = p_ref_.pg().gr_->nnodes() - 1;
- if (!adjacent_or_equal_to_p_ref_())
- next_();
- /* FIXME: This is redundant with the end of next_(), but we might
- change the implementation of start_() when we'll fix it later,
- and no longer use next_(). */
+ nbh_.start(*this);
if (is_valid())
update_();
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- graph_neighborhood_bkd_piter<P>::next_()
+ graph_neighborhood_bkd_piter<P, N>::next_()
{
- /* FIXME: This is inefficient. The graph structure should be able
- to produce the set of adjacent nodes fast. Boost Graphs
- probably provides adequates structures to fetch these
- neighbors in constant time. */
- /* FIXME: Moreover, the behavior of next shall depend on the
- neighborhood, which is not the case now! (Currently, next_() behaves
- as nbh was always an elementary neighborhood.) */
- do
- --id_;
- while (is_valid() && !adjacent_or_equal_to_p_ref_());
+ nbh_.next_(*this);
if (is_valid())
update_();
}
- template <typename P>
+ template <typename P, typename N>
+ inline
+ void
+ graph_neighborhood_bkd_piter<P, N>::first_()
+ {
+ id_ = p_ref_.pg().gr_->nnodes() - 1;
+ }
+
+ template <typename P, typename N>
+ inline
+ void
+ graph_neighborhood_bkd_piter<P, N>::step_()
+ {
+ --id_;
+ }
+
+
+ template <typename P, typename N>
inline
bool
- graph_neighborhood_bkd_piter<P>::adjacent_or_equal_to_p_ref_() const
+ graph_neighborhood_bkd_piter<P, N>::adjacent_or_equal_to_p_ref_() const
{
return p_ref_.pg().adjacent_or_equal(p_ref_.id(), id_);
}
- template <typename P>
+ template <typename P, typename N>
inline
void
- graph_neighborhood_bkd_piter<P>::update_()
+ graph_neighborhood_bkd_piter<P, N>::update_()
{
// Update psite_.
psite_ = graph_psite<P>(p_ref_.pg(), id_);
@@ -416,34 +444,34 @@
p_ = p_ref_.pg().gr_->node_data(id_);
}
- template <typename P>
+ template <typename P, typename N>
inline
const P&
- graph_neighborhood_bkd_piter<P>::to_point() const
+ graph_neighborhood_bkd_piter<P, N>::to_point() const
{
return p_;
}
- template <typename P>
+ template <typename P, typename N>
inline
const graph_psite<P>&
- graph_neighborhood_bkd_piter<P>::to_psite() const
+ graph_neighborhood_bkd_piter<P, N>::to_psite() const
{
return psite_;
}
- template <typename P>
+ template <typename P, typename N>
inline
- graph_neighborhood_bkd_piter<P>::operator graph_psite<P>() const
+ graph_neighborhood_bkd_piter<P, N>::operator graph_psite<P>() const
{
mln_precondition(is_valid());
return psite_;
}
- template <typename P>
+ template <typename P, typename N>
inline
mln_coord(P)
- graph_neighborhood_bkd_piter<P>::operator[](unsigned i) const
+ graph_neighborhood_bkd_piter<P, N>::operator[](unsigned i) const
{
assert(i < dim);
return p_[i];
Index: mln/core/graph_elt_neighborhood.hh
--- mln/core/graph_elt_neighborhood.hh (revision 1807)
+++ mln/core/graph_elt_neighborhood.hh (working copy)
@@ -50,8 +50,8 @@
namespace mln
{
// Fwd decls.
- template <typename P> class graph_neighborhood_fwd_piter;
- template <typename P> class graph_neighborhood_bkd_piter;
+ template <typename P, typename W> class graph_neighborhood_fwd_piter;
+ template <typename P, typename W> class graph_neighborhood_bkd_piter;
/*! \brief Elementary neighborhood on graph class.
@@ -67,29 +67,69 @@
public:
/// Associated types.
/// \{
- /// The type of point stored into the neighborhood.
- // FIXME: Is this right, if we consider that this neighborhood stores
- // psites, not points?
+ /// The type of point corresponding to the neighborhood.
typedef P point;
+ /// The type of psite corresponding to the neighborhood.
+ typedef graph_psite<P> psite;
// FIXME: This is a dummy value.
typedef void dpoint;
- /*! \brief Point_Iterator type to browse the points of a generic
- * neighborhood w.r.t. the ordering of delta-points.
- */
- typedef graph_neighborhood_fwd_piter<P> fwd_qiter;
+ /// \brief Point_Iterator type to browse the psites of the
+ /// neighborhood w.r.t. the ordering of vertices.
+ typedef graph_neighborhood_fwd_piter<P, self_> fwd_niter;
+
+ /// \brief Point_Iterator type to browse the psites of the
+ /// neighborhood w.r.t. the ordering of vertices.
+ typedef graph_neighborhood_bkd_piter<P, self_> bkd_niter;
- /*! \brief Point_Iterator type to browse the points of a generic
- * neighborhood w.r.t. the reverse ordering of delta-points.
- */
- typedef graph_neighborhood_bkd_piter<P> bkd_qiter;
+ /// The default niter type.
+ typedef fwd_niter niter;
+ /// \}
- /// The default qiter type.
- typedef fwd_qiter qiter;
+ /// Services for iterators.
+ /// \{
+ /// Move \a piter to the beginning of the iteration on this neighborhood.
+ template <typename Piter>
+ void start(Point_Iterator<Piter>& piter) const;
+ /// Move \a piter to the next site on this neighborhood.
+ template <typename Piter>
+ void next_(Point_Iterator<Piter>& piter) const;
/// \}
};
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename P>
+ template <typename Piter>
+ inline
+ void
+ graph_elt_neighborhood<P>::start(Point_Iterator<Piter>& piter_) const
+ {
+ Piter& piter = exact(piter_);
+ piter.first_();
+ if (!piter.adjacent_or_equal_to_p_ref_())
+ next_(piter);
+ }
+
+ template <typename P>
+ template <typename Piter>
+ inline
+ void
+ graph_elt_neighborhood<P>::next_(Point_Iterator<Piter>& piter_) const
+ {
+ Piter& piter = exact(piter_);
+ /* FIXME: This is inefficient. The graph structure should be able
+ to produce the set of adjacent nodes fast. Boost Graphs
+ probably provides adequates structures to fetch these
+ neighbors in constant time. */
+ do
+ piter.step_();
+ while (piter.is_valid() && !piter.adjacent_or_equal_to_p_ref_());
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
} // end of namespace mln
Index: tests/core/graph_elt_neighborhood.cc
--- tests/core/graph_elt_neighborhood.cc (revision 1806)
+++ tests/core/graph_elt_neighborhood.cc (working copy)
@@ -25,9 +25,9 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/core/graph_elt_window.cc
+/*! \file tests/core/graph_elt_neighborhood.cc
*
- * \brief Tests on mln::graph_elt_window.
+ * \brief Tests on mln::graph_elt_neighborhood.
*/
#include <iostream>
@@ -35,7 +35,7 @@
#include <vector>
#include <mln/core/point2d.hh>
-#include <mln/core/graph_elt_window.hh>
+#include <mln/core/graph_elt_neighborhood.hh>
#include <mln/debug/iota.hh>
#include <mln/debug/println.hh>
@@ -84,24 +84,24 @@
g.add_edge(3, 4);
g.add_edge(4, 2);
- /*------------------.
- | Graph and window. |
- `------------------*/
+ /*-------------------------.
+ | Graph and neighborhood. |
+ `-------------------------*/
// Graph psite set.
p_graph<p_t> pg(g);
// Graph point site.
graph_psite<p_t> p(pg, 1);
- // ``Sliding'' window of a psite of PG.
- typedef graph_elt_window<p_t> win_t;
- win_t win;
+ // ``Sliding'' neighborhood of a psite of PG.
+ typedef graph_elt_neighborhood<p_t> nbh_t;
+ nbh_t nbh;
- mln_fwd_qiter_(win_t) fq(win, p);
+ mln_fwd_niter_(nbh_t) fq(nbh, p);
for_all(fq)
std::cout << fq << " ";
std::cout << std::endl;
- mln_bkd_qiter_(win_t) bq(win, p);
+ mln_bkd_niter_(nbh_t) bq(nbh, p);
for_all(bq)
std::cout << bq << " ";
std::cout << std::endl;
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Fix a bug in graph_neighborhood_bkd_piter.
* mln/core/graph_neighborhood_piter.hh
(mln::graph_neighborhood_bkd_piter<P>::start): Typo.
graph_neighborhood_piter.hh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: mln/core/graph_neighborhood_piter.hh
--- mln/core/graph_neighborhood_piter.hh (revision 1806)
+++ mln/core/graph_neighborhood_piter.hh (working copy)
@@ -368,7 +368,7 @@
void
graph_neighborhood_bkd_piter<P>::start()
{
- id_ = p_ref_.plg().gr_->nnodes() - 1;
+ id_ = p_ref_.pg().gr_->nnodes() - 1;
if (!adjacent_or_equal_to_p_ref_())
next_();
/* FIXME: This is redundant with the end of next_(), but we might
1
0