twmitchel / FieldConv

Official implementation of Field Convolutions for Surface CNNs [ICCV 2021 Oral]
17 stars 5 forks source link

Parallel transport not working on custom datasets. #3

Open sinAshish opened 2 years ago

sinAshish commented 2 years ago

Hi @twmitchel,

Thanks for open-sourcing this amazing work. I am trying your code on my own dataset of high-res meshes, but while applying the pre-transform functions, the computeLogXport() gives foll. error:

RuntimeError: checkFinite() failure: Non-finite matrix entry [176441,176441] = -nan

I tried to visualize the VH method on the mesh, and it looks like:

Screenshot from 2022-02-21 19-47-27 The transport is not happening across the complete mesh. Do you have any idea why this is happening or a solution for this?

Thanks.

twmitchel commented 2 years ago

Hi @sinAshish,

Thanks for your kind words and for your interest -- more than happy to help you get things running.

I believe the error you're referring to is happening in the construction of the Laplacian eigensystem during the calculation of distances + transport using the VH method.

The author of the VH method directly addresses a similar issue in this thread.

From this it looks like there two potential reasons as to why you're getting this error.

The first is that you could have a bad triangulation, which is how I've come across this error in my experience. As Nick mentions, a few triangles in the mesh may be very small/thin, so much so that computing the associated area becomes numerically unstable, hence the non-finite entry.

The other potential reason is that your meshes could be very large and the diffusion time could be too small.

The second reason is unlikely (the default diffusion time is t = 1.0, already large) but it's an easier fix so it makes sense to try it first.

On line 30 of fcutils/src/main.cpp try setting tCoef to 5.0 or 10.0. Then uninstall and re-install the fcutils library by running the command

pip uninstall fcutils -y && pip install ./fcutils

in the root directory, and try running the pre-processing again. If this doesn't end up fixing things,

If this doesn't fix things, then it's likely that a bad triangulation is an issue (and make sure to set tCoef back to 1.0). As discussed by Nick, there are a few ways to go about fixing your mesh.

If you're already familiar with Geometry Central, then Nick's suggested solution of converting the VertexPositionGeometry object to an EdgeLengthGeometry could be a simple and elegant way to handle this. I haven't tried this, but it looks like you'd want to add something along the lines of his code snippet after line 108 in fcutils/src/main.cpp (depending on what you do, you might want to declare an EdgeLengthGeometry pointer at the beginning of the file as is done for VertexPositionGeometry on line 26).

Otherwise, or if it's just a few meshes you're having this problem with, you can try to repair your meshes manually. To do so, I'd recommend installing OpenFlipper. With it, you can load your meshes and use their extensive and easy to use repair module to both detect and remove/fix problematic triangles. This is what I've done to successfully fix this problem in the past. MeshLab or other mesh-editing software could potentially do this for you too, though I'm only familiar with OpenFlipper. It can be a bit of a pain to install, but I've found it very helpful for quick fixes to problems like you've described.

Please let me know how things go. If you take a crack at it and are having trouble getting things working, you can send me some of the problematic meshes and I'll do my best to get you a serviceable solution.

Also, out of curiosity, what's the average resolution of your meshes? (i.e. about how many vertices?)

If you're looking to to run FC on high resolution meshes (> 5-10K vertices) there is an alternative implementation (in theory) using filters supported on one rings that could potentially scale to very high resolutions. It would require some new code, but it would be simple and straightforward to implement, and would not require the VH method for pre-processing. Let me know if this sounds interesting to you.

-- Tommy

sinAshish commented 2 years ago

Thanks @twmitchel for the quick reply. I'll try out the 2 solutions. Btw the meshes have an avg. res of about 300k vertices. Could you pls describe more on how to scale FC to high-res meshes?

sinAshish commented 2 years ago

I tried the first soln of increasing the coefficient value but it didn't work. So going with the 2nd solution: I included 2 files:

#include "geometrycentral/surface/edge_length_geometry.h"
#include "geometrycentral/surface/intrinsic_mollification.h"

Then declared a new pointer after VertexPositionGeometry

std::unique_ptr<EdgeLengthGeometry> edgeLengths;

Then I followed Nick's solution after L108, and added:

geometry ->requireEdgeLengths();
EdgeLengthGeometry intrinsicGeometry(*mesh, geometry->edgeLengths);
mollifyIntrinsic(*mesh, intrinsicGeometry.inputEdgeLengths);
//change L112 in main.cpp to ->
solver.reset(new VectorHeatMethodSolver(intrinsicGeometry, tCoef));

But still, it is not working. Sorry but I'm not familiar w/ GeometryCentral and new to this area of research, hence these questions.

twmitchel commented 2 years ago

@sinAshish No problem.

Do your changes compile and successfully pre-process meshes from one of the experimental datasets? (i.e. if you run the code to pre-process the SHREC `11 dataset (shape classification experiments) does it work?)

sinAshish commented 2 years ago

@twmitchel Yes. It compiles and runs on other datasets for segmentation and classification. Is there a problem that I have such high-res meshes? I can't remesh it to low-res as the ground truth that I have are defined for high-res meshes, and I'd end up losing the correspondence if I reduce the res. Moreover, each mesh in the dataset has diff. number of vertices.

twmitchel commented 2 years ago

@sinAshish
It's not so much that high-res meshes are 'bad' in any sense, but rather that it gets tricky to fit a usable network into GPU memory. (The same reason why images are usually downsampled to lower resolution before being processed by a network).

Given that you have a correspondence problem, it sounds like the other solution of repairing the meshes manually is not going to work either.

When you get the chance, shoot me an email at tmitchel 'at' jhu.edu. We can discuss how to put together an alternative implementation of FC that could work for your case.

sinAshish commented 2 years ago

Thanks. FC seemed like a good solution because of its efficiency for our application.