cpu_tsdf
cpu_tsdf copied to clipboard
Import TSDF from other algorithms
Hi,
I am trying to use the Kinfu remake algorithm (https://github.com/Nerei/kinfu_remake) to create a TSDF volume and then save it in a file. Later on, I would like to use your library to load this TSDF and either integrate some other point clouds or just creating a mesh file with your marching cubes code.
To import the TSDF, I was thinking of creating a tsdf structure and load the data of each voxel to be the same as the one in the imported data, but I was wondering if you can give me a suggestion of how to do this, since I don't see any function to set a voxel. I was thinking probably something like the updateVoxel function.
Thanks in advance for your help, Pablo
Hi @api55, thanks for checking out the code!
At the moment there's no simple way to do it, though it is technically possible with the current codebase (albeit not as efficient as reimplementing properly.) As a remnant of some no-longer-especially-clean logic, the TSDFVolumeOctree stores its data in a public member Octree::octree_ (see include/cpu_tsdf/octree.h). This Octree has a couple methods that could be of use:
cpu_tsdf::OctreeNode*
getContainingVoxel (float x, float y, float z, float min_size=-1);
is a non-const accessor to the OctreeNode (i.e. voxel) that contains point x,y,z, where the size is no smaller than min_size. At -1, this means "Give me the leaf node which contains x,y,z". If you'd prefer to not iterate yourself, you can also use
void
getLeaves (std::vector<OctreeNode::Ptr> &leaves, float max_size_x, flaot max_size_y, float max_size_z) const;
To get all at once. Either way, the OctreeNode type now has a method:
bool
setData (float d, float w);
So assuming you've initialized the octree with the proper resolution and size, you should be able to build a loading function as is. Ideally this would be propagated up, with something like:
bool
TSDFVolumeOctree::setDataInContainingVoxel (float x, float y, float z, float d, float w)
{
OctreeNode* voxel = octree_->getContainingVoxel (x,y,z);
if (!voxel) return false;
else
{
voxel->setData(d, w);
return (true);
}
}
(this is off the top of my head, I'd encourage you to test it and submit a PR if you find it useful!)
With that said, I'd encourage you to dig into the code and modify as you see fit -- if you already know your values per leaf, and especially if things are on a regular grid, you'll want to be accessing by ID rather than actually using an expensive Octree lookup. It may even be that an octree is not the way to go: or certainly that some of the logic we use here (initializing voxels as big as possible, moving from coarse-to-fine only as needed) will be less than ideal.
Hi @sdmiller, thanks for the advice, I will try to do it this week and I will post the results as soon as I get them, and if it works correctly I will do a PR. Probably in the future I will modify it to be a little more efficient importing a TSDF from another source, but for now I think that the way you describe will be good for what I need at the moment.
By the way, thanks for sharing this code, that I have found quite useful to build some mesh representations for my SLAM algortihms.
Regards, Pablo
Hi @api55 I am trying to use the Kinfu remake algorithm (https://github.com/Nerei/kinfu_remake) to create a TSDF volume but please how to save TSDF in a file ?
Regards,