Problems with deformation functions

Hello !

I’m a beginner with ITK… What I really need is to use the Laplacian Deformation for an object. However, I don’t really understand how to do that stuff. Is there any example I can get or any guidelines because I’m kind of lost in the header files… I didn’t find examples though, so perhaps someone has either an example or some guidance.

Thanks!

Hello @Micholas,

Welcome to ITK!

This example may be helpful. Also, see Image Warping with Kernel Splines in the ITK Software Guide.

Hope this helps,
Matt

Thanks.

Though I feel kind of stupid at the moment… I’m trying to access itkLaplacianDeformationQuadEdgeMeshFilterWithHardConstraints.h’s (and .hxx) functions, why is it so complicated? I know my C++ is not extremely strong since I only gained a few basics out of it (about OOP and stuff) and I haven’t been doing C++ for a while, but I’ve never had this much trouble using a simple method from another class in any language… Could someone explain?

Basically, just this piece of code generates hundreds of errors and I’m lost through the code right now… Do I really need to #include EVERYTHING? This is mad…

(Source.cpp)

#include “itkLaplacianDeformationQuadEdgeMeshFilterWIthHardConstraints.h”

using namespace std;

int Main() {

cout << "Hello!" << endl;

}

Please help.

Oh, and if I create an actual .cpp/.cxx in the project which contains the file I need (itkLaplacianDeformationQuadEdgeMeshFilterWIthHardConstraints.h), building the same code will provide an error saying it can’t find the path of the project, oddly enough.

Thank you!

The build system will need to know how to find the headers.

Please try walking through the Configuring and Building ITK section of the ITK Software Guide. This has instructions on how to use CMake, to generate a hello world project that can find the ITK headers.

We could also create a Python version of the example if that would be helpful.

I think I somewhat get it, but there’s one thing I can’t quite find out yet. Whenever I’m doing the next line :

typedef itk::LaplacianDeformationQuadEdgeMeshFilterWithHardConstraints<aMesh, anotherMesh, someTraits> LaplacianDeformation

I can’t quite figure out what someTraits should be as a class. Meshes weren’t that complicated, but the third and expected element I can’t find it. Any idea?

Thank you for everything!

The mystery can be solved by looking at the super-class. TSolverTraits are only used in itkLaplacianDeformationQuadEdgeMeshFilter.h, like this:

typedef TSolverTraits                     SolverTraits;
typedef typename SolverTraits::ValueType  ValueType;
typedef typename SolverTraits::MatrixType MatrixType;
typedef typename SolverTraits::VectorType VectorType;

The docs say: Linear Sparse Solver Traits see VNLIterativeSparseSolverTraits and VNLSparseLUSolverTraits.

Thanks!

Now, I came up with this with a bit of vélo and it seems to make sense to me (There might be a couple useless Includes which were used before but not anymore, I’ll pay attention to that later…

#include "itkQuadEdgeMesh.h"
#include "itkVTKPolyDataReader.h"
#include "itkVTKPolyDataWriter.h"
#include "itkQuadEdgeMeshParamMatrixCoefficients.h"
#include "itkLaplacianDeformationQuadEdgeMeshFilterWithHardConstraints.h"
#include "VNLSparseLUSolverTraits.h"
#include "itkMeshFileReader.h"
#include "itkMeshFileWriter.h"
#include <iostream>
#include "itkOBJMeshIO.h";

int main() {

	const char * inputPath = "A/path/to/my/original/Object.obj";
	const char * outputPath = "Another/path/to/ObjFile.obj";

	const unsigned int Dimension = 3;
	typedef double CoordType;
	typedef itk::QuadEdgeMesh<CoordType, Dimension> MeshType;
	typedef VNLSparseLUSolverTraits<CoordType> SolverTraits;

	typedef itk::MeshFileReader<MeshType> ReadType;

	ReadType::Pointer reader = ReadType::New();
	reader->SetFileName(inputPath);
	reader->Update();



	typedef itk::LaplacianDeformationQuadEdgeMeshFilterWithHardConstraints<MeshType, MeshType, SolverTraits> LaplacianDeformation;
	LaplacianDeformation::Pointer lp = LaplacianDeformation::New();

	lp->SetInput( reader->GetOutput() );

	typedef itk::ConformalMatrixCoefficients<MeshType> CoeffType;
	CoeffType coeff;
	lp->SetCoefficientsMethod(&coeff);

	MeshType::VectorType null(0.);

	lp->SetDisplacement(150, null);
	lp->SetDisplacement(2027, null);
	lp->SetDisplacement(292, null);
	lp->SetDisplacement(185, null);
	lp->SetDisplacement(180, null);
	lp->SetDisplacement(153, null);
	lp->SetDisplacement(183, null);
	lp->SetDisplacement(226, null);

	MeshType::VectorType vector(null);
	vector[2] = -0.1;

	lp->SetDisplacement(3912, vector);
	lp->SetDisplacement(729, vector);
	lp->SetDisplacement(938, vector);

	vector[1] = 0.1;
	lp->SetDisplacement(40, vector);
	lp->SetDisplacement(371, vector);

	lp->Update(); //Problem
	typedef itk::MeshFileWriter<MeshType> WriteType;

	WriteType::Pointer writer = WriteType::New();

	writer->SetInput(lp->GetOutput());

	writer->SetFileName(outputPath);
	writer->Update();



	return EXIT_SUCCESS;

}

It crashes upon execution though, and it outputs the following text :

In vnl_sparse_lu::solve(…) - error in factoring
sparse: internal error detected in file ‘…/ITK/Source/Modules/ThirdParty/VNL/src/vxl/v3p/netlib/sparse/spFactor.c’ at line 206. Error not cleared.

VS tells me I’ve triggered ASSERT_IS_NOT_FACTORED(Matrix); meaning the assertion failed but I’m not quite sure why? That is in spOrderAndFactor method in said spFactor.c file. Any idea how to fix that? Again, I’m really sorry about all those questions, but it feels like I’m lost in an endless maze. :neutral_face:

This didn’t crash on my computer, but I used some random small mesh. Can you provide the mesh you are using with this?

Are you using an older version of ITK? ASSERT_IS_NOT_FACTORED is on line 207 in a recent version of ITK I have.

My mistake! It stops on ASSERT_NO_ERRORS. I read the line wrong. ASSERT_IS_NOT_FACTORED is the next line (207). My bad!

The file can be found at this link. https://drive.google.com/open?id=1Vt8RGVay6aqczpzx8bWDtI84ocvZYa62

It’s basically a piece of clothing I’m trying to interact with, it can be anything, it just happens to be the first one I found. It can be any type of piece of clothing.

With even a single displacement set, spFactor.c, pPivot at line 278 becomes NULL, indicating a singular matrix. Without any displacements, the result has a ton of nonsensical vertices inserted (here I brought them close to the origin):

What your problem might be is that this mesh isn’t even in one piece, much less a closed surface:

Only closed surface meshes are representable via quad-edge data structure! By supplying this mesh to LaplacianDeformationQuadEdgeMeshFilterWithHardConstraints you are violating one of its constraints. No wonder you get a crash.

Ohhh. Okay, I see…

Do you have any idea of a way around that? Or another way to basically do the same thing but with such meshes?

You could try to make it a single closed mesh using this and this.Then establish vertex correspondences between combinedAndClosed mesh and the original one using vertex positions (possibly with some tolerance e.g. 1e-6).

Then pass combinedAndClosed mesh into LaplacianDeformationQuadEdgeMeshFilterWithHardConstraints. Finally take positions of vertices from deformedCombinedAndClosed mesh and copy them into the original mesh.

Note: this is just a suggestion, I don’t know whether it will work.