https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Sandbox: ICP: Add multi-scale registration.
* sandbox/jardonnet/test/icp.cc: Add nb_it as argument for a
registration.
* sandbox/jardonnet/test/Makefile: Remove icp_lazy test.
Add parameter for multi-scale icp:
* sandbox/jardonnet/registration/tools.hh: Update.
* sandbox/jardonnet/registration/quat7.hh: Use virtual length (c_length)
for p_array.
* sandbox/jardonnet/registration/cloud.hh: Use virtual length.
* sandbox/jardonnet/registration/icp.hh: Use virtual length.
Following files now exist eleswhere (registration/)
* sandbox/jardonnet/registration/quat: Remove.
* sandbox/jardonnet/registration/quat/all.hh: Remove.
* sandbox/jardonnet/registration/quat/misc.hh: Remove.
* sandbox/jardonnet/registration/quat/rotation.hh: Remove.
* sandbox/jardonnet/registration/projection.hh: Use virtual length.
registration/cloud.hh | 15 ++++++----
registration/icp.hh | 62 +++++++++++++++++++++++++++++++--------------
registration/projection.hh | 7 ++---
registration/quat7.hh | 24 ++++++++++-------
registration/tools.hh | 26 +-----------------
test/Makefile | 8 -----
test/icp.cc | 6 ++--
7 files changed, 77 insertions(+), 71 deletions(-)
Index: sandbox/jardonnet/test/icp.cc
--- sandbox/jardonnet/test/icp.cc (revision 1852)
+++ sandbox/jardonnet/test/icp.cc (working copy)
@@ -41,18 +41,20 @@
closest_point<mln_point_(I3d)> fun(x, box_<point3d>(1000,1000,1));
lazy_image< closest_point<mln_point_(I3d)> > map(fun);
- quat7<3> q = registration::icp(c, map);
+ quat7<3> q = registration::icp(c, map, 2);
#ifndef NDEBUG
std::cout << "closest_point(Ck[i]) = " << fun.i <<
std::endl;
std::cout << "Pts processed = " << registration::pts
<< std::endl;
#endif
+ //FIXME: register img1
+
//init output image
//FIXME: Should be
//mln_concrete(I) output(res.bbox()) = convert::to_image<I>(res)?
- q.apply_on(c, c);
+ q.apply_on(c, c, c.npoints());
const box_<point2d> box2d(1000,1000);
image2d<bool> output(box2d, 1);
Index: sandbox/jardonnet/test/Makefile
--- sandbox/jardonnet/test/Makefile (revision 1852)
+++ sandbox/jardonnet/test/Makefile (working copy)
@@ -48,14 +48,6 @@
g++ icp.cc -I../../.. -O3 -ffloat-store -o './bin/+icp_3f'
g++ icp.cc -I../../.. -O3 -DNDEBUG -o './bin/+icp_3D'
g++ icp.cc -I../../.. -O3 -DNDEBUG -ffloat-store -o './bin/+icp_3Df'
- g++ icp_lazy.cc -I../../.. -O0 -o './bin/+icp_lazy_0'
- g++ icp_lazy.cc -I../../.. -O0 -ffloat-store -o './bin/+icp_lazy_0f'
- g++ icp_lazy.cc -I../../.. -O0 -DNDEBUG -o './bin/+icp_lazy_0D'
- g++ icp_lazy.cc -I../../.. -O0 -DNDEBUG -ffloat-store -o './bin/+icp_lazy_0Df'
- g++ icp_lazy.cc -I../../.. -O3 -o './bin/+icp_lazy_3'
- g++ icp_lazy.cc -I../../.. -O3 -ffloat-store -o './bin/+icp_lazy_3f'
- g++ icp_lazy.cc -I../../.. -O3 -DNDEBUG -o './bin/+icp_lazy_3D'
- g++ icp_lazy.cc -I../../.. -O3 -DNDEBUG -ffloat-store -o './bin/+icp_lazy_3Df'
./icp_check.sh
clean:
Index: sandbox/jardonnet/registration/tools.hh
--- sandbox/jardonnet/registration/tools.hh (revision 1852)
+++ sandbox/jardonnet/registration/tools.hh (working copy)
@@ -10,6 +10,7 @@
namespace mln
{
+ //FIXME: groe length
template <typename P>
struct closest_point
{
@@ -18,11 +19,9 @@
closest_point(const p_array<P>& X, const box_<P>& box)
: X(X), box(box)
-
#ifndef NDEBUG
, i(0)
#endif
-
{ }
result
@@ -80,6 +79,7 @@
: value(nrows, ncols,1), is_known(nrows,ncols,1), fun(fun)
{ }
+ // FIXME: gore length
const mln_result(F)
//inline
operator () (const typename F::input& p) const
@@ -254,28 +254,6 @@
} // 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
{
Index: sandbox/jardonnet/registration/quat7.hh
--- sandbox/jardonnet/registration/quat7.hh (revision 1852)
+++ sandbox/jardonnet/registration/quat7.hh (working copy)
@@ -59,12 +59,15 @@
}
template <typename P>
- void apply_on(const p_array<P>& input, p_array<P>& output) const
+ void apply_on(const p_array<P>& input,
+ p_array<P>& output,
+ const size_t c_length) const
{
- assert(input.npoints() == output.npoints());
+ assert(c_length <= input.npoints());
+ assert(c_length <= output.npoints());
assert(_qR.is_unit());
- for (size_t i = 0; i < input.npoints(); i++)
+ for (size_t i = 0; i < c_length; i++)
output.hook_()[i] = algebra::to_point<P>((*this)(input[i]));
}
@@ -95,27 +98,30 @@
quat7<P::dim> match(const p_array<P>& C,
const algebra::vec<P::dim,float>& mu_C,
const p_array<P>& Ck,
- M& map)
+ M& map,
+ size_t c_length)
{
+ //FIXME: mix mu_Xk and qk loop
+
+
//mu_Xk = center map(Ck)
algebra::vec<P::dim,float> mu_Xk(literal::zero);
- for (size_t i = 0; i < Ck.npoints(); ++i)
+ for (size_t i = 0; i < c_length; ++i)
{
algebra::vec<P::dim,float> xki = map(Ck[i]);
mu_Xk += xki;
}
- mu_Xk /= Ck.npoints();
-
+ mu_Xk /= c_length;
// qR
algebra::mat<P::dim,P::dim,float> Mk(literal::zero);
- for (size_t i = 0; i < C.npoints(); ++i)
+ for (size_t i = 0; i < c_length; ++i)
{
algebra::vec<P::dim,float> Ci = C[i];
algebra::vec<P::dim,float> Xki = map(Ck[i]);
Mk += make::mat(Ci - mu_C) * trans(make::mat(Xki - mu_Xk));
}
- Mk /= C.npoints();
+ Mk /= c_length;
/*
Index: sandbox/jardonnet/registration/cloud.hh
--- sandbox/jardonnet/registration/cloud.hh (revision 1852)
+++ sandbox/jardonnet/registration/cloud.hh (working copy)
@@ -18,16 +18,16 @@
{
template <typename P>
- P center(const p_array<P>& a)
+ P center(const p_array<P>& a, size_t length)
{
algebra::vec<P::dim,float> c(literal::zero);
- for (size_t i = 0; i < a.npoints(); ++i)
+ for (size_t i = 0; i < length; ++i)
{
algebra::vec<P::dim,float> ai = a[i];
c += ai;
}
- return algebra::to_point<P>(c / a.npoints());
+ return algebra::to_point<P>(c / length);
}
@@ -43,16 +43,19 @@
template <typename P>
float rms(const p_array<P>& a1,
- const p_array<P>& a2)
+ const p_array<P>& a2,
+ const size_t length)
{
- assert(a1.npoints() == a2.npoints());
+ assert(length <= a1.npoints());
+ assert(length <= a2.npoints());
/*
float f = 0.f;
for (size_t i = 0; i < a1.npoints(); ++i)
f += sqr_norm(a1[i] - a2[i]);
return f / a1.npoints();*/
+
float f = 0.f;
- for (size_t i = 0; i < a1.npoints(); ++i)
+ for (size_t i = 0; i < length; ++i)
{
algebra::vec<3,float> a1f = a1[i];
algebra::vec<3,float> a2f = a2[i];
Index: sandbox/jardonnet/registration/icp.hh
--- sandbox/jardonnet/registration/icp.hh (revision 1852)
+++ sandbox/jardonnet/registration/icp.hh (working copy)
@@ -35,6 +35,7 @@
# include <iostream>
# include <string>
+# include <cmath>
# include <mln/algebra/quat.hh>
# include <mln/algebra/vec.hh>
@@ -78,48 +79,56 @@
p_array<P>
icp_(const p_array<P>& C,
M& map,
- quat7<P::dim>& qk)
+ quat7<P::dim>& qk,
+ const size_t c_length,
+ const float epsilon = 1e-3)
{
trace::entering("registration::impl::icp_");
#ifndef NDEBUG
//display registred points
std::cout << "Register "
- << C.npoints() << " points" << std::endl;
+ << c_length << " points" << std::endl;
std::cout << "k\terror\tdqk" << std::endl;
#endif
-
- unsigned int k;
quat7<P::dim> old_qk;
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;
+ algebra::vec<P::dim,float> mu_C = center(C, c_length), mu_Xk;
- const float epsilon = 1;//1e-3;
+ qk.apply_on(C, Ck, c_length);
- //// step 1
- k = 0;
+ unsigned int k = 0;
do {
//compute qk
old_qk = qk;
- qk = match(C, mu_C, Ck, map);
+ qk = match(C, mu_C, Ck, map, c_length);
//Ck+1 = qk(C)
- qk.apply_on(C, Ck);
+ qk.apply_on(C, Ck, c_length);
//err = d(Ck+1,Xk)
- err = rms(Ck, Xk);
+ err = rms(Ck, Xk, c_length);
#ifndef NDEBUG
-
{
using namespace std;
- image2d<bool> img = convert::to_image2d(Ck);
+
+ image2d<bool> img(box2d(500,800), 0);
+ for (size_t i = 0; i < c_length; i++)
+ {
+ point2d p = convert::to_point2d(Ck[i]);
+ if (img.has(p))
+ img(p) = true;
+ }
+
+ //image2d<bool> img = convert::to_image2d(Ck);
stringstream oss;
- oss << "reg" << k << ".pbm";
+ static int pimp = 0;
+ oss << "i_" << pimp++ << ".pbm";
io::pbm::save(img, oss.str());
}
@@ -128,10 +137,10 @@
<< (qk - old_qk).sqr_norm() << '\t'
<< std::endl;
//count the number of points processed
- pts += Ck.npoints();
+ pts += c_length;
#endif
- ++k;
+ k++;
} while (k < 3 || (qk - old_qk).sqr_norm() > epsilon);
trace::exiting("registration::impl::icp_");
@@ -145,19 +154,34 @@
template <typename P, typename M>
inline
quat7<P::dim>
- icp(const p_array<P>& cloud,
- M& map)
+ icp(p_array<P> cloud,
+ M& map,
+ const unsigned nb_it)
{
trace::entering("registration::icp");
mln_precondition(P::dim == 3);
mln_precondition(cloud.npoints() != 0);
+ // Shuffle cloud
+ for (size_t i = 0; i < cloud.npoints(); i++)
+ {
+ size_t r = rand() % cloud.npoints();
+ P tmp;
+ tmp = cloud[i];
+ cloud.hook_()[i] = cloud[r];
+ cloud.hook_()[r] = tmp;
+ }
+
//init rigid transform qk
quat7<P::dim> qk;
//run icp
- p_array<P> res = impl::icp_(cloud, map, qk);
+ for (int i = nb_it; i >= 0; i--)
+ {
+ size_t l = cloud.npoints() / std::pow(2., i); // 3 is arbitrary fixed
+ impl::icp_(cloud, map, qk, l, i + 1e-3);
+ }
trace::exiting("registration::icp");
Index: sandbox/jardonnet/registration/projection.hh
--- sandbox/jardonnet/registration/projection.hh (revision 1852)
+++ sandbox/jardonnet/registration/projection.hh (working copy)
@@ -70,11 +70,12 @@
template <typename P, typename T>
void memo(const p_array<P>& Ck,
p_array<P>& Xk,
- lazy_image<T>& map) // first: closest points, second:
is_computed
+ lazy_image<T>& map,
+ const size_t c_length) // first: closest points, second: is_computed
{
- assert(Ck.npoints() == Xk.npoints());
+ //assert(Ck.npoints() == Xk.npoints()); //FIXME:
- for (size_t i = 0; i < Ck.npoints(); ++i)
+ for (size_t i = 0; i < c_length; ++i)
Xk.hook_()[i] = map(Ck[i]);
}