24 #ifndef CCORRELATION_OPTICALFLOW
25 #define CCORRELATION_OPTICALFLOW
52 template<
typename T,
typename Timg>
58 std::string m_shape_type, m_interpLoop, m_interpFinal;
65 this->class_name =
"Correlation : Optical Flow";
69 virtual void init(CParameterNetCDF &fp)
76 std::string attribute_name(
"shape");
77 int error = fp.loadAttribute(attribute_name,m_shape_type);
78 if (this->m_verbose){printf(
"\tShape function type : %s\n", m_shape_type.c_str());}
80 attribute_name =
"convergence_speed";
81 error = fp.loadAttribute(attribute_name,m_epsilon);
82 if (this->m_verbose){printf(
"\tLimit speed of convergence : %f\n", m_epsilon);}
84 attribute_name =
"interpolation_loop";
85 m_interpLoop =
"linear";
86 error = fp.loadAttribute(attribute_name,m_interpLoop);
87 if (this->m_verbose){printf(
"\tLoop interpolator : %f\n", m_interpLoop.c_str());}
89 attribute_name =
"interpolation_final";
90 m_interpFinal =
"linear";
91 error = fp.loadAttribute(attribute_name,m_interpFinal);
92 if (this->m_verbose){printf(
"\tFinal iterpolator : %f\n", m_interpFinal.c_str());}
102 this->_3D = oMesh._3D;
106 T previous_res(1e10);
109 CImg<int> p(this->m_threadNB,1,1,1,0);
110 CImgList<T> solution(oField.m_mode);
111 CImg<T> current_res(this->m_threadNB,1,1,1,0);
112 assignG(oMesh, K,Ke);
125 CImgList<T> N(oMesh.num_var(), oMesh.num_mod(),1,1,1, 0);
126 T residue(0), deformed(0);
127 std::vector<T> ref, offset, lCoor, gCoor, grad, U;
128 ref.assign(3,0);offset.assign(3,0);lCoor.assign(3,0); gCoor.assign(3,0); U.assign(3,0); grad.assign(oMesh.num_var(),0);
134 metric(oImage,oMesh,solution,oField,N,Ve,Ke,ref,offset,lCoor,gCoor,U,grad,residue,deformed,list, p,current_res,K);
142 solve(K,oMesh,solution);
143 if (this->m_medianFilter){this->
regularize(oMesh, oImage, solution);}
146 metric(oImage,oMesh,solution,oField,N,Ve,Ke,ref,offset,lCoor,gCoor,U,grad,residue,deformed,list, p,current_res,K);
150 test(solution, m_epsilon, oField, previous_res, iter, converged);
156 if (oImage.m_storeActiv)
157 {export_res(oImage,oMesh,oField, N,ref,offset,lCoor,gCoor,U,residue,deformed,list);}
163 virtual void assignG(
const Cmesh<T,Timg> &oMesh, CImgList<T> &K, CImgList<T> &Ke)
171 virtual void assignL(
const Cmesh<T,Timg> &oMesh, CImgList<T> &Ve) = 0;
173 virtual void reset(
const int &thread, CImgList<T> &Ke)
176 cimglist_for(Ke, var)
178 cimg_forXYZ(Ke[var], x,y,z)
180 Ke[var](x,y,z,thread) = 0;
186 virtual void evalGN(
const std::vector<T> &grad,
const CImgList<T> &N, CImgList<T> &Ve) = 0;
190 virtual void evalU(
const CImgList<T> &solution,
const Cmesh<T,Timg> &oMesh,
const int &elem,
const CImgList<T> &N, std::vector<T> &U) = 0;
192 virtual void evalShape(
const CImg<Timg> &list,
const Cimage<Timg> &oImage,
const Cfield<T,Timg> &oField,
const std::vector<T> &ref,
const std::vector<T> &lCoor,
const std::vector<T> &gCoor, CImgList<T> &N) = 0;
201 grad[0] = (T)( oImage.m_curImg[0](x[0]+1,x[1],x[2], 0) - oImage.m_curImg[0](x[0]-1,x[1],x[2], 0) )/(2.*oImage.m_pix[0]);
202 grad[1] = (T)( oImage.m_curImg[0](x[0],x[1]+1,x[2], 0) - oImage.m_curImg[0](x[0],x[1]-1,x[2], 0) )/(2.*oImage.m_pix[1]);
205 {grad[2] = (T)( oImage.m_curImg[0](x[0],x[1],x[2]+1, 0) - oImage.m_curImg[0](x[0],x[1],x[2]-1, 0) )/(2.*oImage.m_pix[2]);}
214 if (m_interpLoop ==
"cubic")
216 deformed = oImage.m_curImg[1].cubic_atXYZ(x[0]+U[0]/oImage.m_pix[0],x[1]+U[1]/oImage.m_pix[1],x[2]+U[2]/oImage.m_pix[2], 0);
220 deformed = oImage.m_curImg[1].linear_atXYZC(x[0]+U[0]/oImage.m_pix[0],x[1]+U[1]/oImage.m_pix[1],x[2]+U[2]/oImage.m_pix[2], 0,0);
226 {residue = (T)oImage.m_curImg(0, x[0],x[1],x[2])- deformed;}
234 if (m_interpFinal ==
"cubic")
236 deformed = oImage.m_curImg[1].cubic_atXYZ(x[0]+U[0]/oImage.m_pix[0],x[1]+U[1]/oImage.m_pix[1],x[2]+U[2]/oImage.m_pix[2],0);
240 deformed = oImage.m_curImg[1].linear_atXYZC(x[0]+U[0]/oImage.m_pix[0],x[1]+U[1]/oImage.m_pix[1],x[2]+U[2]/oImage.m_pix[2], 0,0);
246 {residue = (T)oImage.m_curImg(0, x[0],x[1],x[2])- deformed;}
251 virtual void tensors(
const int &thread,
const CImgList<T> &Ve,
const T &residue, CImgList<T> &Ke)
254 cimg_forZ(Ke[0], dim)
256 cimg_forX(Ke[0],modi)
258 cimg_forY(Ke[0],modj)
260 Ke[0](modi,modj,dim,thread) += Ve[dim][modi] * Ve[dim][modj];
262 Ke[1](0, modi,dim,thread) += Ve[dim][modi] * residue;
268 virtual void assembly(
const int &thread,
const Cmesh<T,Timg> &oMesh,
const int &elem,
const CImgList<T> &Ke, CImgList<T> &K) = 0;
270 virtual void metric(
const Cimage<Timg> &oImage,
const Cmesh<T,Timg> &oMesh, CImgList<T> &solution,
Cfield<T,Timg> &oField, CImgList<T> &N, CImgList<T> &Ve, CImgList<T> &Ke, std::vector<T> &ref, std::vector<T> &offset, std::vector<T> &lCoor, std::vector<T> &gCoor, std::vector<T> &U, std::vector<T> &grad, T &residue, T &deformed, CImg<Timg> &list, CImg<int> &p, CImg<T> ¤t_res, CImgList<T> &K)
276 cimglist_for(K,var){K[var].fill(0);}
279 int thread(0),enter(1);
281 #pragma omp for schedule(runtime)
282 cimglist_for(oMesh.m_connect, elem)
285 if (oMesh.cropList(oImage, elem, list, offset))
289 thread = omp_get_thread_num();
292 e_ref(oImage, oMesh, elem, ref);
297 for (
int pix=0; pix<list.size(); pix++)
301 list.contains(list[pix],lCoor[0],lCoor[1],lCoor[2]);
302 for (
int i=0; i<gCoor.size(); i++){gCoor[i]=lCoor[i]+offset[i];}
306 if (!oImage.m_mask.is_empty()){enter = oImage.m_curMask(gCoor[0], gCoor[1], gCoor[2]);}
315 evalShape(list, oImage, oField, ref, lCoor, gCoor, N);
321 evalU(solution, oMesh, elem, N, U);
327 current_res[thread] += std::pow(residue,2);
330 tensors(thread, Ve, residue, Ke);
336 assembly(thread, oMesh, elem, Ke, K);
344 oField.m_meanRes.push_back(std::sqrt(current_res.sum())*100/oImage.m_res);
349 virtual void solve(CImgList<T> &K,
const Cmesh<T,Timg> &oMesh, CImgList<T> &solution)
352 solution = K[1].get_solve(K[0]);
356 virtual void test(
const CImgList<T> &solution,
const double &epsilon,
Cfield<T,Timg> &oField, T &previous_res,
int &iter,
int &converged)
359 if (std::abs(oField.m_meanRes.back() - previous_res) >= epsilon and oField.m_meanRes.back()<=previous_res)
363 previous_res = oField.m_meanRes.back();
364 oField.m_mode = solution;
366 if(this->m_verbose){std::cout<<
"(iter "<<iter<<
") : "<<oField.m_meanRes.back()<<
" \%\n\n";}
373 if (oField.m_meanRes.back()>previous_res){printf(
"Warning : last step has diverged\n");}
374 else{printf(
"Last step has converged\n");}
375 oField.m_meanRes.back() = previous_res;
376 std::cout<<this->class_name.c_str()<<
" -> ultimate residue ("<<iter<<
" iter) : "<<previous_res<<
" \%\n";
382 virtual void export_res(
const Cimage<Timg> &oImage,
const Cmesh<T,Timg> &oMesh,
Cfield<T,Timg> &oField, CImgList<T> &N, std::vector<T> &ref, std::vector<T> &offset, std::vector<T> &lCoor, std::vector<T> &gCoor, std::vector<T> &U, T &residue, T &deformed, CImg<Timg> &list)
385 int thread(0), enter(1);
387 #pragma omp for schedule(runtime)
388 cimglist_for(oMesh.m_connect, elem)
391 if (oMesh.cropList(oImage, elem, list, offset))
395 thread = omp_get_thread_num();
398 e_ref(oImage, oMesh, elem, ref);
400 for (
int pix=0; pix<list.size(); pix++)
404 list.contains(list[pix],lCoor[0],lCoor[1],lCoor[2]);
405 for (
int i=0; i<gCoor.size(); i++){gCoor[i]=lCoor[i]+offset[i];}
409 if (!oImage.m_mask.is_empty()){enter = oImage.m_curMask(gCoor[0], gCoor[1], gCoor[2]);}
415 evalShape(list, oImage, oField, ref, lCoor, gCoor, N);
418 evalU(oField.m_mode, oMesh, elem, N, U);
424 store(oField,oImage,gCoor,U,deformed,residue);
436 virtual void store(
Cfield<T,Timg> &oField,
const Cimage<Timg> &oImage,
const std::vector<T> gCoor,
const std::vector<T> &U,
const T &deformed,
const T &residue)
439 if (oImage.m_storeField)
441 cimglist_for(oField.m_field, dim)
445 oField.m_field(dim, gCoor[0],gCoor[1],gCoor[2]) = U[dim];
450 if (oImage.m_storeDef)
454 oField.m_def(gCoor[0],gCoor[1],gCoor[2]) = deformed;
458 if (oImage.m_storeRes)
462 oField.m_res(gCoor[0],gCoor[1],gCoor[2]) = residue;
virtual void regularize(const Cmesh< T, Timg > &oMesh, const Cimage< Timg > &oImage, CImgList< T > &solution)
Definition: Ccorrelation.h:96
void evalRes_final(const Cimage< Timg > &oImage, const std::vector< T > &U, const std::vector< T > &x, T &residue, T &deformed)
Definition: Ccorrelation_opticalFlow.h:230
void evalRes_loop(const Cimage< Timg > &oImage, const std::vector< T > &U, const std::vector< T > &x, T &residue, T &deformed)
Definition: Ccorrelation_opticalFlow.h:209
this is the mother class of every correlation classes. m_correl_type refers to the the type of correl...
Definition: Ccorrelation.h:65
This is the mother class of Optical Flow strategies: It implements different steps required for the i...
Definition: Ccorrelation_opticalFlow.h:53
virtual void gradient(const Cimage< Timg > &oImage, const std::vector< T > &x, std::vector< T > &grad)
Definition: Ccorrelation_opticalFlow.h:194
virtual void init(CParameterNetCDF &fp)
Definition: Ccorrelation_opticalFlow.h:69