Skip to content

Commit 89b1337

Browse files
authored
Merge pull request #14 from unclearness/feature/voxel_smooth
Feature/voxel smooth
2 parents 8a3eac7 + 38821fe commit 89b1337

File tree

10 files changed

+2831
-60
lines changed

10 files changed

+2831
-60
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,8 @@ if(UGU_USE_CUDA)
315315
src/cuda/voxel.cc
316316
src/cuda/voxel.cuh
317317
src/cuda/voxel.cu
318+
src/cuda/mesh.cuh
319+
src/cuda/mesh.cu
318320
src/cuda/helper_cuda.h
319321
src/cuda/helper_string.h
320322
)

examples/ex21_fusion.cc

Lines changed: 241 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ int main(int argc, char* argv[]) {
117117

118118
Eigen::Affine3d c2w = (Eigen::Translation3f(pos) * R).cast<double>();
119119
ugu::PinholeCameraPtr camera =
120-
std::make_shared<ugu::PinholeCamera>(640, 480, fov_y_deg);
120+
std::make_shared<ugu::PinholeCamera>(320, 240, fov_y_deg);
121121
renderer->set_camera(camera);
122122
camera->set_c2w(c2w);
123123

@@ -264,70 +264,119 @@ int main(int argc, char* argv[]) {
264264
timer.Start();
265265
voxel_grid_naive.GetFacesCpu(faces);
266266
timer.End();
267-
std::cout << "GetFacesCpu " << timer.elapsed_msec() << " ms"
268-
<< std::endl;
267+
std::cout << "GetFacesCpu " << timer.elapsed_msec() << " ms" << std::endl;
269268
out_mesh.set_vertices(vertices);
270269
out_mesh.set_vertex_indices(faces);
271270
out_mesh.set_default_material();
272271
out_mesh.CalcNormal();
273272
out_mesh.WriteObj("cuda_mc.obj");
274273

275-
ugu::VoxelGrid voxel_grid_cpu;
276-
voxel_grid_cpu.Init(combined->stats().bb_max + offset,
277-
combined->stats().bb_min - offset, resolution);
278-
voxel_grid_naive.GetVoxelGridCpu(voxel_grid_cpu);
279-
ugu::MarchingCubes(voxel_grid_cpu, &out_mesh);
274+
//timer.Start();
275+
//voxel_grid_naive.ReduceFlyingNoiseOnVoxels(30, 1, 0.f, 150, false);
276+
//timer.End();
277+
//std::cout << "ReduceFlyingNoiseOnVoxels " << timer.elapsed_msec() << " ms"
278+
// << std::endl;
279+
timer.Start();
280+
voxel_grid_naive.ExtractMesh();
281+
timer.End();
282+
std::cout << "ExtractMesh " << timer.elapsed_msec() << " ms" << std::endl;
283+
284+
timer.Start();
285+
voxel_grid_naive.RemoveSmallConnectedComponents(50, 100);
286+
timer.End();
287+
std::cout << "RemoveSmallConnectedComponents " << timer.elapsed_msec()
288+
<< " ms" << std::endl;
289+
//timer.Start();
290+
//voxel_grid_naive.RemoveSmallConnectedComponents(100, 100, 10);
291+
//timer.End();
292+
//std::cout << "RemoveSmallConnectedComponents " << timer.elapsed_msec()
293+
// << " ms" << std::endl;
294+
//timer.Start();
295+
//voxel_grid_naive.RemoveSmallConnectedComponents(100, 100, 10);
296+
//timer.End();
297+
//std::cout << "RemoveSmallConnectedComponents " << timer.elapsed_msec()
298+
// << " ms" << std::endl;
299+
timer.Start();
300+
voxel_grid_naive.ComputeVertexNormals();
301+
timer.End();
302+
std::cout << "ComputeVertexNormals " << timer.elapsed_msec() << " ms"
303+
<< std::endl;
304+
timer.Start();
305+
voxel_grid_naive.GetVerticesCpu(vertices);
306+
timer.End();
307+
std::cout << "GetVerticesCpu " << timer.elapsed_msec() << " ms"
308+
<< std::endl;
309+
timer.Start();
310+
voxel_grid_naive.GetFacesCpu(faces);
311+
timer.End();
312+
std::cout << "GetFacesCpu " << timer.elapsed_msec() << " ms" << std::endl;
313+
out_mesh.set_vertices(vertices);
314+
out_mesh.set_vertex_indices(faces);
280315
out_mesh.set_default_material();
281316
out_mesh.CalcNormal();
282-
out_mesh.WriteObj("cpu_mc.obj");
283-
284-
{
285-
ugu::VoxelGridCudaNaive voxel_grid_naive2;
286-
voxel_grid_naive2.Init(combined->stats().bb_max + offset,
287-
combined->stats().bb_min - offset, resolution);
288-
289-
timer.Start();
290-
voxel_grid_naive2.FuseDepthMulti(
291-
h_depths_pinned, width, height, num_images, h_fx_vec.data(),
292-
h_fy_vec.data(), h_cx_vec.data(), h_cy_vec.data(), h_R_vec.data(),
293-
h_t_vec.data(), fusion_option, true);
294-
timer.End();
295-
std::cout << "FuseDepthMulti " << timer.elapsed_msec() << " ms"
296-
<< std::endl;
297-
298-
ugu::Mesh out_mesh;
299-
std::vector<Eigen::Vector3f> vertices;
300-
std::vector<Eigen::Vector3i> faces;
301-
timer.Start();
302-
voxel_grid_naive2.ExtractMesh();
303-
timer.End();
304-
std::cout << "ExtractMesh " << timer.elapsed_msec() << " ms"
305-
<< std::endl;
306-
timer.Start();
307-
voxel_grid_naive2.GetVerticesCpu(vertices);
308-
timer.End();
309-
std::cout << "GetVerticesCpu " << timer.elapsed_msec() << " ms"
310-
<< std::endl;
311-
timer.Start();
312-
voxel_grid_naive2.GetFacesCpu(faces);
313-
timer.End();
314-
std::cout << "GetFacesCpu " << timer.elapsed_msec() << " ms"
315-
<< std::endl;
316-
out_mesh.set_vertices(vertices);
317-
out_mesh.set_vertex_indices(faces);
318-
out_mesh.set_default_material();
319-
out_mesh.CalcNormal();
320-
out_mesh.WriteObj("cuda_mc2.obj");
321-
322-
ugu::VoxelGrid voxel_grid_cpu;
323-
voxel_grid_cpu.Init(combined->stats().bb_max + offset,
324-
combined->stats().bb_min - offset, resolution);
325-
voxel_grid_naive2.GetVoxelGridCpu(voxel_grid_cpu);
326-
ugu::MarchingCubes(voxel_grid_cpu, &out_mesh);
327-
out_mesh.set_default_material();
328-
out_mesh.CalcNormal();
329-
out_mesh.WriteObj("cpu_mc2.obj");
330-
}
317+
out_mesh.WriteObj("cuda_mc_cleaned.obj");
318+
319+
// return 1;
320+
321+
// ugu::VoxelGrid voxel_grid_cpu;
322+
// voxel_grid_cpu.Init(combined->stats().bb_max + offset,
323+
// combined->stats().bb_min - offset, resolution);
324+
// voxel_grid_naive.GetVoxelGridCpu(voxel_grid_cpu);
325+
// ugu::MarchingCubes(voxel_grid_cpu, &out_mesh);
326+
// out_mesh.set_default_material();
327+
// out_mesh.CalcNormal();
328+
// out_mesh.WriteObj("cpu_mc.obj");
329+
330+
// std::cout << "diff: " << std::endl;
331+
// std::cout << vertices[10] - out_mesh.vertices()[10] << std::endl;
332+
333+
// {
334+
// ugu::VoxelGridCudaNaive voxel_grid_naive2;
335+
// voxel_grid_naive2.Init(combined->stats().bb_max + offset,
336+
// combined->stats().bb_min - offset, resolution);
337+
338+
// timer.Start();
339+
// voxel_grid_naive2.FuseDepthMulti(
340+
// h_depths_pinned, width, height, num_images, h_fx_vec.data(),
341+
// h_fy_vec.data(), h_cx_vec.data(), h_cy_vec.data(), h_R_vec.data(),
342+
// h_t_vec.data(), fusion_option, true);
343+
// timer.End();
344+
// std::cout << "FuseDepthMulti " << timer.elapsed_msec() << " ms"
345+
// << std::endl;
346+
347+
// ugu::Mesh out_mesh;
348+
// std::vector<Eigen::Vector3f> vertices;
349+
// std::vector<Eigen::Vector3i> faces;
350+
// timer.Start();
351+
// voxel_grid_naive2.ExtractMesh();
352+
// timer.End();
353+
// std::cout << "ExtractMesh " << timer.elapsed_msec() << " ms"
354+
// << std::endl;
355+
// timer.Start();
356+
// voxel_grid_naive2.GetVerticesCpu(vertices);
357+
// timer.End();
358+
// std::cout << "GetVerticesCpu " << timer.elapsed_msec() << " ms"
359+
// << std::endl;
360+
// timer.Start();
361+
// voxel_grid_naive2.GetFacesCpu(faces);
362+
// timer.End();
363+
// std::cout << "GetFacesCpu " << timer.elapsed_msec() << " ms"
364+
// << std::endl;
365+
// out_mesh.set_vertices(vertices);
366+
// out_mesh.set_vertex_indices(faces);
367+
// out_mesh.set_default_material();
368+
// out_mesh.CalcNormal();
369+
// out_mesh.WriteObj("cuda_mc2.obj");
370+
371+
// ugu::VoxelGrid voxel_grid_cpu;
372+
// voxel_grid_cpu.Init(combined->stats().bb_max + offset,
373+
// combined->stats().bb_min - offset, resolution);
374+
// voxel_grid_naive2.GetVoxelGridCpu(voxel_grid_cpu);
375+
// ugu::MarchingCubes(voxel_grid_cpu, &out_mesh);
376+
// out_mesh.set_default_material();
377+
// out_mesh.CalcNormal();
378+
// out_mesh.WriteObj("cpu_mc2.obj");
379+
// }
331380
}
332381
#endif
333382

@@ -349,13 +398,148 @@ int main(int argc, char* argv[]) {
349398

350399
ugu::FuseDepth(*cameras[i], depths[i], option, voxel_grid);
351400
}
401+
timer.Start();
402+
const auto [labels, counts] =
403+
ugu::ConnectedComponentLabelingVoxels(voxel_grid, 1, 100, false, 0.f);
404+
//const auto [labels, counts] =
405+
// ugu::ConnectedComponentLabelingVoxelsZeroCrossing(voxel_grid, 1000, 1);
406+
timer.End();
407+
ugu::LOGI("ConnectedComponentLabelingVoxels %f ms\n", timer.elapsed_msec());
408+
409+
std::vector<Eigen::Vector3f> points;
410+
std::vector<Eigen::Vector3f> colors;
411+
std::vector<Eigen::Vector3f> label_colors;
412+
413+
for (size_t i = 0; i < counts.size(); i++) {
414+
label_colors.push_back(122.5f *(Eigen::Vector3f::Random() +
415+
Eigen::Vector3f::Constant(1.f)));
416+
}
417+
418+
for (size_t i = 0; i < voxel_grid.get_all().size(); i++) {
419+
if (labels[i] > 0) {
420+
const auto& voxel = voxel_grid.get_all()[i];
421+
points.push_back(voxel.pos);
422+
colors.push_back(label_colors[labels[i]]);
423+
}
424+
}
425+
426+
ugu::Mesh pc;
427+
pc.set_vertices(points);
428+
pc.set_vertex_colors(colors);
429+
pc.set_default_material();
430+
pc.WritePly(data_dir + "voxel_cc_label.ply");
352431

353432
ugu::MarchingCubes(voxel_grid, depth_fused.get());
354433
depth_fused->set_default_material();
355434
depth_fused->CalcNormal();
356435
depth_fused->WriteObj(data_dir, "depthfuse");
436+
437+
438+
std::vector<Eigen::Vector3f> verts;
439+
std::vector<Eigen::Vector3i> tris;
440+
timer.Start();
441+
ugu::RemoveSmallComponentsParallel(depth_fused->vertices(),
442+
depth_fused->vertex_indices(), 1000,
443+
100, verts, tris);
444+
timer.End();
445+
ugu::LOGI("RemoveSmallComponentsParallel %f ms\n", timer.elapsed_msec());
446+
depth_fused->Clear();
447+
depth_fused->set_vertices(verts);
448+
depth_fused->set_vertex_indices(tris);
449+
depth_fused->set_default_material();
450+
depth_fused->CalcNormal();
451+
depth_fused->WriteObj(data_dir, "depthfuse_removedpara");
452+
depth_fused->Clear();
453+
454+
const std::vector<Eigen::Vector3i> neighbor6_offsets = {
455+
Eigen::Vector3i(-1, 0, 0), Eigen::Vector3i(1, 0, 0),
456+
Eigen::Vector3i(0, -1, 0), Eigen::Vector3i(0, 1, 0),
457+
Eigen::Vector3i(0, 0, -1), Eigen::Vector3i(0, 0, 1)};
458+
459+
const std::vector<Eigen::Vector3i> neighbor27_offsets = {
460+
Eigen::Vector3i(-1, -1, -1), Eigen::Vector3i(0, -1, -1),
461+
Eigen::Vector3i(1, -1, -1), Eigen::Vector3i(-1, 0, -1),
462+
Eigen::Vector3i(0, 0, -1), Eigen::Vector3i(1, 0, -1),
463+
Eigen::Vector3i(-1, 1, -1), Eigen::Vector3i(0, 1, -1),
464+
Eigen::Vector3i(1, 1, -1), Eigen::Vector3i(-1, -1, 0),
465+
Eigen::Vector3i(0, -1, 0), Eigen::Vector3i(1, -1, 0),
466+
Eigen::Vector3i(-1, 0, 0), Eigen::Vector3i(0, 0, 0),
467+
Eigen::Vector3i(1, 0, 0), Eigen::Vector3i(-1, 1, 0),
468+
Eigen::Vector3i(0, 1, 0), Eigen::Vector3i(1, 1, 0),
469+
Eigen::Vector3i(-1, -1, 1), Eigen::Vector3i(0, -1, 1),
470+
Eigen::Vector3i(1, -1, 1), Eigen::Vector3i(-1, 0, 1),
471+
Eigen::Vector3i(0, 0, 1), Eigen::Vector3i(1, 0, 1),
472+
Eigen::Vector3i(-1, 1, 1), Eigen::Vector3i(0, 1, 1),
473+
Eigen::Vector3i(1, 1, 1)};
474+
const std::vector<Eigen::Vector3i> neighbor8_offsets = {
475+
Eigen::Vector3i(-1, -1, -1), Eigen::Vector3i(0, -1, -1),
476+
Eigen::Vector3i(-1, 0, -1), Eigen::Vector3i(-1, 1, -1),
477+
478+
Eigen::Vector3i(-1, -1, 0), Eigen::Vector3i(0, -1, 0),
479+
Eigen::Vector3i(1, -1, 0), Eigen::Vector3i(-1, 0, 0)};
480+
481+
for (size_t i = 0; i < voxel_grid.get_all().size(); i++) {
482+
if (labels[i] > 0 && counts[labels[i]] < 10) {
483+
std::cout << i << " label " << labels[i] << " count "
484+
<< counts[labels[i]] << std::endl;
485+
auto& voxel = voxel_grid.get_all()[i];
486+
487+
//bool all_good = true;
488+
//for (const auto& neighbor : neighbor27_offsets) {
489+
// Eigen::Vector3i neighbor_index =
490+
// voxel_grid.get_index(voxel.pos) + neighbor;
491+
492+
// if (neighbor_index.x() < 0 ||
493+
// neighbor_index.x() >= voxel_grid.resolution().x() ||
494+
// neighbor_index.y() < 0 ||
495+
// neighbor_index.y() >= voxel_grid.resolution().y() ||
496+
// neighbor_index.z() < 0 ||
497+
// neighbor_index.z() >= voxel_grid.resolution().z()) {
498+
// continue;
499+
// }
500+
501+
// size_t neighbor_flat_index =
502+
// neighbor_index.x() +
503+
// neighbor_index.y() * voxel_grid.resolution().x() +
504+
// neighbor_index.z() * voxel_grid.resolution().x() *
505+
// voxel_grid.resolution().y();
506+
// //voxel_grid.get_all()[neighbor_flat_index].sdf = 1.f;
507+
// //voxel_grid.get_all()[neighbor_flat_index].update_num = 0.f;
508+
//
509+
// if (labels[neighbor_flat_index] == 0 ||
510+
// counts[labels[neighbor_flat_index]] < 10) {
511+
// all_good = false;
512+
// break;
513+
// }
514+
//}
515+
voxel.sdf = 1.f;
516+
voxel.update_num = 0;
517+
518+
//if (!all_good) {
519+
// voxel.sdf = 1.f;
520+
// //ugu::InvalidSdf::kVal;
521+
// voxel.update_num = 0;
522+
//}
523+
524+
//voxel.sdf = ugu::InvalidSdf::kVal;
525+
//voxel.update_num = 0;
526+
527+
}
528+
}
529+
530+
for (size_t i = 0; i < counts.size(); ++i) {
531+
std::cout << " Label " << i << ": " << counts[i] << " voxels."
532+
<< std::endl;
533+
}
534+
535+
ugu::MarchingCubes(voxel_grid, depth_fused.get());
536+
depth_fused->set_default_material();
537+
depth_fused->CalcNormal();
538+
depth_fused->WriteObj(data_dir, "depthfuse_cleaned");
357539
}
358540

541+
return 1;
542+
359543
#if 0
360544
// Merge naive
361545
{

include/ugu/cuda/voxel.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ class VoxelGridCudaNaive {
9393
const float* h_t,
9494
const VoxelGridCudaNaiveFuseOption& option,
9595
bool sync = true);
96-
9796
void ExtractMesh(bool with_face_normals = true);
97+
void RemoveSmallConnectedComponents(int max_iter, int min_face,
98+
int early_exit_check_interval = -1);
9899
void ComputeVertexNormals();
99100
void SmoothFaceNormalsWithVertexNormals();
100101
void GetVerticesCpu(std::vector<Eigen::Vector3f>& vertices);
@@ -112,6 +113,10 @@ class VoxelGridCudaNaive {
112113
const int* GetVerticesNumGpu() const;
113114
const int* GetFacesNumGpu() const;
114115

116+
void SetVerticesGpu(const std::vector<Eigen::Vector3f>& vertices);
117+
void SetFacesGpu(const std::vector<Eigen::Vector3i>& faces);
118+
void SetFaceNormalsGpu(const std::vector<Eigen::Vector3f>& face_normals);
119+
115120
void Clear();
116121

117122
private:

include/ugu/util/geom_util.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,18 @@ void BuildFaceAdjacencyCSR(const std::vector<Eigen::Vector3i>& faces,
198198
void BuildFaceAdjacencyCSRParallel(const std::vector<Eigen::Vector3i>& faces,
199199
std::vector<int>& offsets,
200200
std::vector<int>& neighbors);
201+
202+
void RemoveSmallComponentsParallel(const std::vector<Eigen::Vector3f>& verts,
203+
const std::vector<Eigen::Vector3i>& tris,
204+
int K, int min_faces,
205+
std::vector<Eigen::Vector3f>& out_verts,
206+
std::vector<Eigen::Vector3i>& out_tris);
207+
208+
void RemoveSmallComponentsParallel(const std::vector<Eigen::Vector3f>& verts,
209+
const std::vector<Eigen::Vector3i>& tris,
210+
const std::vector<Eigen::Vector3f>& fnormals,
211+
int K, int min_faces,
212+
std::vector<Eigen::Vector3f>& out_verts,
213+
std::vector<Eigen::Vector3i>& out_tris,
214+
std::vector<Eigen::Vector3f>& out_fnormals);
201215
} // namespace ugu

0 commit comments

Comments
 (0)