diff --git a/modules/odm_25dmeshing/src/Odm25dMeshing.cpp b/modules/odm_25dmeshing/src/Odm25dMeshing.cpp index ba8ecd91..ac5aa3b5 100644 --- a/modules/odm_25dmeshing/src/Odm25dMeshing.cpp +++ b/modules/odm_25dmeshing/src/Odm25dMeshing.cpp @@ -190,38 +190,49 @@ void Odm25dMeshing::buildMesh(){ } } + log << "OK\nMedian filter..."; + + vtkSmartPointer medianFilter = + vtkSmartPointer::New(); + medianFilter->SetInputData(image); + medianFilter->SetKernelSize( + std::max(1.0, resolution), + std::max(1.0, resolution), + 1); + medianFilter->Update(); + log << "OK\n"; +// double diffuseIterations = std::max(1.0, resolution / 2.0); +// vtkSmartPointer diffuse1 = +// vtkSmartPointer::New(); +// diffuse1->SetInputConnection(medianFilter->GetOutputPort()); +// diffuse1->FacesOn(); +// diffuse1->EdgesOn(); +// diffuse1->CornersOn(); +// diffuse1->SetDiffusionFactor(1); // Full strength +// diffuse1->GradientMagnitudeThresholdOn(); +// diffuse1->SetDiffusionThreshold(0.2); // Don't smooth jumps in elevation > than 0.20m +// diffuse1->SetNumberOfIterations(diffuseIterations); +// diffuse1->Update(); if (outputDsmFile != ""){ log << "Saving DSM to file... "; vtkSmartPointer tiffWriter = vtkSmartPointer::New(); tiffWriter->SetFileName(outputDsmFile.c_str()); - tiffWriter->SetInputData(image); + tiffWriter->SetInputData(medianFilter->GetOutput()); tiffWriter->Write(); log << "OK\n"; } - vtkSmartPointer surfaceDiffusion = - vtkSmartPointer::New(); - surfaceDiffusion->SetInputData(image); - surfaceDiffusion->FacesOn(); - surfaceDiffusion->EdgesOn(); - surfaceDiffusion->CornersOn(); - surfaceDiffusion->SetDiffusionFactor(1); // Full strength - surfaceDiffusion->GradientMagnitudeThresholdOn(); - surfaceDiffusion->SetDiffusionThreshold(0.2); // Don't smooth jumps in elevation > than 0.20m - surfaceDiffusion->SetNumberOfIterations(resolution / 2.0); - surfaceDiffusion->Update(); - log << "Triangulate... "; vtkSmartPointer terrain = vtkSmartPointer::New(); terrain->SetErrorMeasureToNumberOfTriangles(); terrain->SetNumberOfTriangles(maxVertexCount * 2); // Approximate - terrain->SetInputData(surfaceDiffusion->GetOutput()); + terrain->SetInputData(medianFilter->GetOutput()); terrain->BoundaryVertexDeletionOn(); terrain->Update(); diff --git a/modules/odm_25dmeshing/src/Odm25dMeshing.hpp b/modules/odm_25dmeshing/src/Odm25dMeshing.hpp index e750c3e8..2f2b6a3b 100644 --- a/modules/odm_25dmeshing/src/Odm25dMeshing.hpp +++ b/modules/odm_25dmeshing/src/Odm25dMeshing.hpp @@ -30,6 +30,7 @@ #include #include #include +#include // For compatibility with new VTK generic data arrays #ifdef vtkGenericDataArray_h diff --git a/scripts/mvstex.py b/scripts/mvstex.py index bc672c4f..47adea24 100644 --- a/scripts/mvstex.py +++ b/scripts/mvstex.py @@ -50,7 +50,8 @@ class ODMMvsTexCell(ecto.Cell): runs = [{ 'out_dir': tree.odm_texturing, - 'model': tree.odm_mesh + 'model': tree.odm_mesh, + 'force_skip_vis_test': False }] if args.fast_orthophoto: @@ -59,7 +60,14 @@ class ODMMvsTexCell(ecto.Cell): if args.use_25dmesh: runs += [{ 'out_dir': tree.odm_25dtexturing, - 'model': tree.odm_25dmesh + 'model': tree.odm_25dmesh, + + # We always skip the visibility test when using the 2.5D mesh + # because many faces end up being narrow, and almost perpendicular + # to the ground plane. The visibility test improperly classifies + # them as "not seen" since the test is done on a single triangle vertex, + # and while one vertex might be occluded, the other two might not. + 'force_skip_vis_test': True }] for r in runs: @@ -77,7 +85,7 @@ class ODMMvsTexCell(ecto.Cell): skipHoleFilling = "" keepUnseenFaces = "" - if (self.params.skip_vis_test): + if (self.params.skip_vis_test or r['force_skip_vis_test']): skipGeometricVisibilityTest = "--skip_geometric_visibility_test" if (self.params.skip_glob_seam_leveling): skipGlobalSeamLeveling = "--skip_global_seam_leveling"