dellepiane: mutualglobal, added convergence control, first testing

This commit is contained in:
Matteo Dellepiane matteodelle 2012-12-05 19:10:24 +00:00
parent c3783ccb88
commit 63c8eb0986
4 changed files with 104 additions and 31 deletions

View File

@ -266,7 +266,7 @@ void AlignSet::initializeGL() {
if (w > 0.0)
{
clr /= w;
clr = color * clr / w;
}
else
{
@ -379,12 +379,9 @@ bool AlignSet::ProjectedMultiImageChanged()
/////// Image 2
if (arcImages.size()>=2)
{
tmp = QGLWidget::convertToGLFormat(*arcImages[1]);
tmp=tmp.scaled(wt,ht);
}
tmp = QGLWidget::convertToGLFormat(*arcImages[1]);
tmp=tmp.scaled(wt,ht);
//tmp.save("temp2.jpg");
glBindTexture(GL_TEXTURE_2D, depthTex2);
@ -414,12 +411,9 @@ bool AlignSet::ProjectedMultiImageChanged()
/////// Image 3
if (arcImages.size()>=3)
{
tmp = QGLWidget::convertToGLFormat(*arcImages[2]);
tmp=tmp.scaled(wt,ht);
}
tmp = QGLWidget::convertToGLFormat(*arcImages[2]);
tmp=tmp.scaled(wt,ht);
//tmp.save("temp3.jpg");
glBindTexture(GL_TEXTURE_2D, depthTex3);

View File

@ -24,6 +24,8 @@ class AlignSet {
//typedef vcg::Camera<float> Camera;
//typedef vcg::Shot<float> Shot;
//typedef vcg::Box3<float> Box;
public:

View File

@ -36,6 +36,8 @@
#include <wrap/gl/shot.h>
#include <wrap/gl/camera.h>
#include <vcg/complex/algorithms/point_sampling.h>
// Constructor usually performs only two simple tasks of filling the two lists
// - typeList: with all the possible id of the filtering actions
// - actionList with the corresponding actions. If you want to add icons to your filtering actions you can do here by construction the QActions accordingly
@ -43,6 +45,7 @@
AlignSet align;
FilterMutualInfoPlugin::FilterMutualInfoPlugin()
{
typeList << FP_IMAGE_GLOBALIGN;
@ -98,8 +101,8 @@ void FilterMutualInfoPlugin::initParameterSet(QAction *action,MeshDocument & md,
QStringList rendList;
switch(ID(action)) {
case FP_IMAGE_GLOBALIGN :
parlst.addParam(new RichMesh ("SourceMesh", md.mm(),&md, "Source Mesh",
"The mesh on which the image must be aligned"));
//parlst.addParam(new RichMesh ("SourceMesh", md.mm(),&md, "Source Mesh",
// "The mesh on which the image must be aligned"));
/*parlst.addParam(new RichRaster ("SourceRaster", md.rm(),&md, "Source Raster",
"The mesh on which the image must be aligned"));*/
@ -117,10 +120,14 @@ void FilterMutualInfoPlugin::initParameterSet(QAction *action,MeshDocument & md,
//parlst.addParam(new RichShotf ("Shot", vcg::Shotf(),"Smoothing steps", "The number of times that the whole algorithm (normal smoothing + vertex fitting) is iterated."));
parlst.addParam(new RichInt ("Number of refinement steps",
1,
"Number of minimaziations step on the global graph",
"Number of minimaziations step on the global graph"));
parlst.addParam(new RichInt ("Max number of refinement steps",
5,
"Maximum number of minimizations step",
"Maximum number of minimizations step on the global graph"));
parlst.addParam(new RichFloat ("Threshold for refinement convergence",
1.2,
"Threshold for refinement convergence (in pixels)",
"The threshold (average quadratic variation in the projection on image plane of some samples of the mesh before and after each step of refinement) that stops the refinement"));
parlst.addParam(new RichBool("Pre-alignment",false,"Pre-alignment step","Pre-alignment step"));
parlst.addParam(new RichBool("Estimate Focal",true,"Estimate focal length","Estimate focal length"));
@ -148,6 +155,26 @@ void FilterMutualInfoPlugin::initParameterSet(QAction *action,MeshDocument & md,
// Move Vertex of a random quantity
bool FilterMutualInfoPlugin::applyFilter(QAction *action, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos *cb)
{
QTime filterTime;
filterTime.start();
float thresDiff=par.getFloat("Threshold for refinement convergence");
std::vector<vcg::Point3f> myVec;
int leap=(int)((float)md.mm()->cm.vn/1000.0f);
CMeshO::VertexIterator vi;
for(int i=0;i<=md.mm()->cm.vn;i=i+leap)
{
myVec.push_back(md.mm()->cm.vert[i].P());
}
std::vector<vcg::Shotf> oldShots;
for (int r=0; r<md.rasterList.size();r++)
{
oldShots.push_back(md.rasterList[r]->shot);
}
Log(0,"Sampled has %i vertices",myVec.size());
std::vector<SubGraph> Graphs;
/// Preliminary singular alignment using classic MI
switch(ID(action)) {
@ -169,20 +196,23 @@ bool FilterMutualInfoPlugin::applyFilter(QAction *action, MeshDocument &md, Rich
preAlignment(md, par, cb);
}
this->glContext->doneCurrent();
this->glContext->makeCurrent();
this->initGL();
if (par.getInt("Number of refinement steps")!=0)
if (par.getInt("Max number of refinement steps")!=0)
{
Graphs=buildGraph(md);
Log(0, "BuildGraph completed");
for (int i=0; i<par.getInt("Number of refinement steps"); i++)
for (int i=0; i<par.getInt("Max number of refinement steps"); i++)
{
AlignGlobal(md, Graphs);
Log(0, "AlignGlobal %d of %d completed",i,par.getInt("Number of refinement steps"));
float diff=calcShotsDifference(md,oldShots,myVec);
Log(0, "AlignGlobal %d of %d completed, average improvement %f pixels",i+1,par.getInt("Max number of refinement steps"),diff);
if (diff<thresDiff)
break;
oldShots.clear();
for (int r=0; r<md.rasterList.size();r++)
{
oldShots.push_back(md.rasterList[r]->shot);
}
}
}
@ -193,10 +223,38 @@ bool FilterMutualInfoPlugin::applyFilter(QAction *action, MeshDocument &md, Rich
default : assert(0);
}
Log(0,"Filter completed in %i sec",(int)((float)filterTime.elapsed()/1000.0f));
return true;
}
float FilterMutualInfoPlugin::calcShotsDifference(MeshDocument &md, std::vector<vcg::Shotf> oldShots, std::vector<vcg::Point3f> points)
{
std::vector<float> distances;
for (int i=0; i<points.size(); i++)
{
for(int j=0; j<md.rasterList.size(); j++)
{
vcg::Point2f pp=md.rasterList[j]->shot.Project(points[i]);
if(pp[0]>0 && pp[1]>0 && pp[0]<md.rasterList[j]->shot.Intrinsics.ViewportPx[0] && pp[1]<md.rasterList[j]->shot.Intrinsics.ViewportPx[1])
{
vcg::Point2f ppOld=oldShots[j].Project(points[i]);
vcg::Point2f d=pp-ppOld;
distances.push_back(vcg::math::Sqrt( d[0]*d[0] + d[1]*d[1] ));
}
}
}
float totErr=0.0;
for (int i=0; i<distances.size(); i++)
{
totErr+=(distances[i]*distances[i]);
}
return totErr/(float)distances.size();
}
void FilterMutualInfoPlugin::initGL()
@ -742,14 +800,14 @@ bool FilterMutualInfoPlugin::AlignGlobal(MeshDocument &md, std::vector<SubGraph>
int n=0;
while (!allActive(graphs[i]))
{
Log(0, "Round %d of %d: get the right node",n+1,graphs[i].nodes.size());
//Log(0, "Round %d of %d: get the right node",n+1,graphs[i].nodes.size());
int curr= getTheRightNode(graphs[i]);
graphs[i].nodes[curr].active=true;
Log(0, "Round %d of %d: align the node",n+1,graphs[i].nodes.size());
//Log(0, "Round %d of %d: align the node",n+1,graphs[i].nodes.size());
AlignNode(md, graphs[i].nodes[curr]);
Log(0, "Round %d of %d: update the graph",n+1,graphs[i].nodes.size());
//Log(0, "Round %d of %d: update the graph",n+1,graphs[i].nodes.size());
UpdateGraph(md, graphs[i], curr);
Log(0, "Image %d completed",curr);
//Log(0, "Image %d completed",curr);
n++;
}
@ -829,6 +887,24 @@ bool FilterMutualInfoPlugin::AlignNode(MeshDocument &md, Node node)
}
if(align.arcImages.size()==0)
return true;
else if(align.arcImages.size()==1)
{
align.arcImages.push_back(&md.rasterList[node.arcs[0].projId]->currentPlane->image);
align.arcShots.push_back(&md.rasterList[node.arcs[0].projId]->shot);
align.arcMI.push_back(node.arcs[0].mutual);
align.arcImages.push_back(&md.rasterList[node.arcs[0].projId]->currentPlane->image);
align.arcShots.push_back(&md.rasterList[node.arcs[0].projId]->shot);
align.arcMI.push_back(node.arcs[0].mutual);
}
else if(align.arcImages.size()==2)
{
align.arcImages.push_back(&md.rasterList[node.arcs[0].projId]->currentPlane->image);
align.arcShots.push_back(&md.rasterList[node.arcs[0].projId]->shot);
align.arcMI.push_back(node.arcs[0].mutual);
}
align.ProjectedMultiImageChanged();
/*solver.optimize_focal=true;

View File

@ -71,6 +71,7 @@ public:
bool AlignNode(MeshDocument &md, Node node);
bool allActive(SubGraph graph);
bool UpdateGraph(MeshDocument &md, SubGraph graph, int n);
float calcShotsDifference(MeshDocument &md, std::vector<vcg::Shotf> oldShots, std::vector<vcg::Point3f> points);