Skip to content

Commit

Permalink
dense: implement dense fusion
Browse files Browse the repository at this point in the history
  • Loading branch information
cdcseacave committed Aug 6, 2024
1 parent b2a0d93 commit adaeecc
Show file tree
Hide file tree
Showing 7 changed files with 325 additions and 31 deletions.
5 changes: 4 additions & 1 deletion apps/DensifyPointCloud/DensifyPointCloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ bool Application::Initialize(size_t argc, LPCTSTR* argv)
unsigned nEstimationGeometricIters;
unsigned nEstimateColors;
unsigned nEstimateNormals;
unsigned nFuseFilter;
unsigned nOptimize;
int nIgnoreMaskLabel;
bool bRemoveDmaps;
Expand All @@ -146,7 +147,7 @@ bool Application::Initialize(size_t argc, LPCTSTR* argv)
("min-resolution", boost::program_options::value(&nMinResolution)->default_value(640), "do not scale images lower than this resolution")
("sub-resolution-levels", boost::program_options::value(&nSubResolutionLevels)->default_value(2), "number of patch-match sub-resolution iterations (0 - disabled)")
("number-views", boost::program_options::value(&nNumViews)->default_value(nNumViewsDefault), "number of views used for depth-map estimation (0 - all neighbor views available)")
("number-views-fuse", boost::program_options::value(&nMinViewsFuse)->default_value(3), "minimum number of images that agrees with an estimate during fusion in order to consider it inlier (<2 - only merge depth-maps)")
("number-views-fuse", boost::program_options::value(&nMinViewsFuse)->default_value(2), "minimum number of images that agrees with an estimate during fusion in order to consider it inlier (<2 - only merge depth-maps)")
("ignore-mask-label", boost::program_options::value(&nIgnoreMaskLabel)->default_value(-1), "label value to ignore in the image mask, stored in the MVS scene or next to each image with '.mask.png' extension (<0 - disabled)")
("mask-path", boost::program_options::value<std::string>(&OPT::strMaskPath), "path to folder containing mask images with '.mask.png' extension")
("iters", boost::program_options::value(&nEstimationIters)->default_value(numIters), "number of patch-match iterations")
Expand All @@ -157,6 +158,7 @@ bool Application::Initialize(size_t argc, LPCTSTR* argv)
("sub-scene-area", boost::program_options::value(&OPT::fMaxSubsceneArea)->default_value(0.f), "split the scene in sub-scenes such that each sub-scene surface does not exceed the given maximum sampling area (0 - disabled)")
("sample-mesh", boost::program_options::value(&OPT::fSampleMesh)->default_value(0.f), "uniformly samples points on a mesh (0 - disabled, <0 - number of points, >0 - sample density per square unit)")
("fusion-mode", boost::program_options::value(&OPT::nFusionMode)->default_value(0), "depth-maps fusion mode (-2 - fuse disparity-maps, -1 - export disparity-maps only, 0 - depth-maps & fusion, 1 - export depth-maps only)")
("fusion-filter", boost::program_options::value(&nFuseFilter)->default_value(2), "filter used to fuse the depth-maps (0 - merge, 1 - fuse, 2 - dense-fuse)")
("postprocess-dmaps", boost::program_options::value(&nOptimize)->default_value(7), "flags used to filter the depth-maps after estimation (0 - disabled, 1 - remove-speckles, 2 - fill-gaps, 4 - adjust-filter)")
("filter-point-cloud", boost::program_options::value(&OPT::thFilterPointCloud)->default_value(0), "filter dense point-cloud based on visibility (0 - disabled)")
("export-number-views", boost::program_options::value(&OPT::nExportNumViews)->default_value(0), "export points with >= number of views (0 - disabled, <0 - save MVS project too)")
Expand Down Expand Up @@ -248,6 +250,7 @@ bool Application::Initialize(size_t argc, LPCTSTR* argv)
OPTDENSE::nEstimationGeometricIters = nEstimationGeometricIters;
OPTDENSE::nEstimateColors = nEstimateColors;
OPTDENSE::nEstimateNormals = nEstimateNormals;
OPTDENSE::nFuseFilter = nFuseFilter;
OPTDENSE::nOptimize = nOptimize;
OPTDENSE::nIgnoreMaskLabel = nIgnoreMaskLabel;
OPTDENSE::bRemoveDmaps = bRemoveDmaps;
Expand Down
8 changes: 4 additions & 4 deletions apps/Tests/Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,21 +82,21 @@ bool PipelineTest(bool verbose=false)
}
OPTDENSE::init();
OPTDENSE::bRemoveDmaps = true;
if (!scene.DenseReconstruction() || scene.pointcloud.GetSize() < 200000u) {
if (!scene.DenseReconstruction() || scene.pointcloud.GetSize() < 50000u) {
VERBOSE("ERROR: TestDataset failed estimating dense point cloud!");
return false;
}
if (verbose)
scene.pointcloud.Save(MAKE_PATH("scene_dense.ply"));
if (!scene.ReconstructMesh() || scene.mesh.faces.size() < 75000u) {
if (!scene.ReconstructMesh() || scene.mesh.faces.size() < 40000u) {
VERBOSE("ERROR: TestDataset failed reconstructing the mesh!");
return false;
}
if (verbose)
scene.mesh.Save(MAKE_PATH("scene_dense_mesh.ply"));
constexpr float decimate = 0.5f;
constexpr float decimate = 0.7f;
scene.mesh.Clean(decimate);
if (!ISINSIDE(scene.mesh.faces.size(), 35000u, 45000u)) {
if (!ISINSIDE(scene.mesh.faces.size(), 25000u, 45000u)) {
VERBOSE("ERROR: TestDataset failed cleaning the mesh!");
return false;
}
Expand Down
20 changes: 16 additions & 4 deletions libs/Common/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1298,9 +1298,15 @@ class TPoint2 : public cv::Point_<TYPE>
inline const TYPE* ptr() const { return &x; }
inline TYPE* ptr() { return &x; }

// iterator base access to enable range-based for loops
inline const TYPE* begin() const { return &x; }
inline const TYPE* end() const { return &x+3; }

// 1D element access
inline const TYPE& operator [](size_t i) const { ASSERT(i>=0 && i<2); return ptr()[i]; }
inline TYPE& operator [](size_t i) { ASSERT(i>=0 && i<2); return ptr()[i]; }
inline const TYPE& operator ()(int i) const { ASSERT(i>=0 && i<2); return ptr()[i]; }
inline TYPE& operator ()(int i) { ASSERT(i>=0 && i<2); return ptr()[i]; }
inline const TYPE& operator [](int i) const { ASSERT(i>=0 && i<2); return ptr()[i]; }
inline TYPE& operator [](int i) { ASSERT(i>=0 && i<2); return ptr()[i]; }

// Access point as Size equivalent
inline operator const Size& () const { return *((const Size*)this); }
Expand Down Expand Up @@ -1391,9 +1397,15 @@ class TPoint3 : public cv::Point3_<TYPE>
inline const TYPE* ptr() const { return &x; }
inline TYPE* ptr() { return &x; }

// iterator base access to enable range-based for loops
inline const TYPE* begin() const { return &x; }
inline const TYPE* end() const { return &x+3; }

// 1D element access
inline const TYPE& operator [](BYTE i) const { ASSERT(i<3); return ptr()[i]; }
inline TYPE& operator [](BYTE i) { ASSERT(i<3); return ptr()[i]; }
inline const TYPE& operator ()(int i) const { ASSERT(i>=0 && i<3); return ptr()[i]; }
inline TYPE& operator ()(int i) { ASSERT(i>=0 && i<3); return ptr()[i]; }
inline const TYPE& operator [](int i) const { ASSERT(i>=0 && i<3); return ptr()[i]; }
inline TYPE& operator [](int i) { ASSERT(i>=0 && i<3); return ptr()[i]; }

// Access point as vector equivalent
inline operator const Vec& () const { return *reinterpret_cast<const Vec*>(this); }
Expand Down
10 changes: 8 additions & 2 deletions libs/MVS/DepthMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,15 @@ MDEFVAR_OPTDENSE_uint32(nMinResolution, "Min Resolution", "Do not scale images l
DEFVAR_OPTDENSE_uint32(nSubResolutionLevels, "SubResolution levels", "Number of lower resolution levels to estimate the depth and normals", "2")
DEFVAR_OPTDENSE_uint32(nMinViews, "Min Views", "minimum number of agreeing views to validate a depth", "2")
MDEFVAR_OPTDENSE_uint32(nMaxViews, "Max Views", "maximum number of neighbor images used to compute the depth-map for the reference image", "12")
DEFVAR_OPTDENSE_uint32(nMinViewsFuse, "Min Views Fuse", "minimum number of images that agrees with an estimate during fusion in order to consider it inlier (<2 - only merge depth-maps)", "2")
DEFVAR_OPTDENSE_uint32(nMinViewsFuse, "Min Views Fuse", "minimum number of images that agrees with an estimate during fusion in order to consider it inlier", "2")
MDEFVAR_OPTDENSE_uint32(nMaxViewsFuse, "Max Views Fuse", "maximum number of neighbor depth-maps used during fusion", "32")
DEFVAR_OPTDENSE_uint32(nMinViewsFilter, "Min Views Filter", "minimum number of images that agrees with an estimate in order to consider it inlier", "2")
MDEFVAR_OPTDENSE_uint32(nMinViewsFilterAdjust, "Min Views Filter Adjust", "minimum number of images that agrees with an estimate in order to consider it inlier (0 - disabled)", "1")
MDEFVAR_OPTDENSE_uint32(nMinViewsTrustPoint, "Min Views Trust Point", "min-number of views so that the point is considered for approximating the depth-maps (<2 - random initialization)", "2")
MDEFVAR_OPTDENSE_uint32(nNumViews, "Num Views", "Number of views used for depth-map estimation (0 - all views available)", "0", "4", "8")
MDEFVAR_OPTDENSE_uint32(nMinPixelsFuse, "Min Pixels Fuse", "minimum number of depth-estimates that agree during fusion in order to consider it (multiple pixels can be from the same depth-map)", "5")
MDEFVAR_OPTDENSE_uint32(nMaxPointsFuse, "Max Points Fuse", "maximum number of pixels to fuse into a single point", "1000")
MDEFVAR_OPTDENSE_uint32(nMaxFuseDepth, "Max Fuse Depth", "maximum depth in fusion graph traversal", "100")
MDEFVAR_OPTDENSE_uint32(nPointInsideROI, "Point Inside ROI", "consider a point shared only if inside ROI when estimating the neighbor views (0 - ignore ROI, 1 - weight more ROI points, 2 - consider only ROI points)", "1")
MDEFVAR_OPTDENSE_bool(bFilterAdjust, "Filter Adjust", "adjust depth estimates during filtering", "1")
MDEFVAR_OPTDENSE_bool(bAddCorners, "Add Corners", "add support points at image corners with nearest neighbor disparities", "0")
Expand All @@ -89,6 +93,7 @@ MDEFVAR_OPTDENSE_float(fMinAngle, "Min Angle", "Min angle for accepting the dept
MDEFVAR_OPTDENSE_float(fOptimAngle, "Optim Angle", "Optimal angle for computing the depth triangulation", "12.0")
MDEFVAR_OPTDENSE_float(fMaxAngle, "Max Angle", "Max angle for accepting the depth triangulation", "65.0")
MDEFVAR_OPTDENSE_float(fDescriptorMinMagnitudeThreshold, "Descriptor Min Magnitude Threshold", "minimum patch texture variance accepted when matching two patches (0 - disabled)", "0.02") // 0.02: pixels with patch texture variance below 0.0004 (0.02^2) will be removed from depthmap; 0.12: patch texture variance below 0.02 (0.12^2) is considered texture-less
MDEFVAR_OPTDENSE_float(fDepthReprojectionErrorThreshold, "Depth Reprojection Error Threshold", "maximum relative difference between measured and depth projected pixel", "1.2")
MDEFVAR_OPTDENSE_float(fDepthDiffThreshold, "Depth Diff Threshold", "maximum variance allowed for the depths during refinement", "0.01")
MDEFVAR_OPTDENSE_float(fNormalDiffThreshold, "Normal Diff Threshold", "maximum variance allowed for the normal during fusion (degrees)", "25")
MDEFVAR_OPTDENSE_float(fPairwiseMul, "Pairwise Mul", "pairwise cost scale to match the unary cost", "0.3")
Expand All @@ -98,8 +103,9 @@ MDEFVAR_OPTDENSE_uint32(nSpeckleSize, "Speckle Size", "maximal size of a speckle
MDEFVAR_OPTDENSE_uint32(nIpolGapSize, "Interpolate Gap Size", "interpolate small gaps (left<->right, top<->bottom)", "7")
MDEFVAR_OPTDENSE_int32(nIgnoreMaskLabel, "Ignore Mask Label", "label id used during ignore mask filter (<0 - disabled)", "-1")
DEFVAR_OPTDENSE_uint32(nOptimize, "Optimize", "should we filter the extracted depth-maps?", "7") // see DepthFlags
DEFVAR_OPTDENSE_uint32(nFuseFilter, "Fuse Filter", "how to fuse the depth-maps into one dense point-cloud?", "2", "0", "1") // see FuseMode
MDEFVAR_OPTDENSE_uint32(nEstimateColors, "Estimate Colors", "should we estimate the colors for the dense point-cloud?", "2", "0", "1")
MDEFVAR_OPTDENSE_uint32(nEstimateNormals, "Estimate Normals", "should we estimate the normals for the dense point-cloud?", "0", "1", "2")
MDEFVAR_OPTDENSE_uint32(nEstimateNormals, "Estimate Normals", "should we estimate the normals for the dense point-cloud?", "2", "0", "1")
MDEFVAR_OPTDENSE_float(fNCCThresholdKeep, "NCC Threshold Keep", "Maximum 1-NCC score accepted for a match", "0.9", "0.5")
DEFVAR_OPTDENSE_uint32(nEstimationIters, "Estimation Iters", "Number of patch-match iterations", "3")
DEFVAR_OPTDENSE_uint32(nEstimationGeometricIters, "Estimation Geometric Iters", "Number of geometric consistent patch-match iterations (0 - disabled)", "2")
Expand Down
11 changes: 11 additions & 0 deletions libs/MVS/DepthMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,26 @@ enum DepthFlags {
ADJUST_FILTER = (1 << 2),
OPTIMIZE = (REMOVE_SPECKLES|FILL_GAPS)
};
enum FuseMode {
FUSE_NOFILTER = 0,
FUSE_FILTER,
FUSE_DENSEFILTER,
};
extern unsigned nResolutionLevel;
extern unsigned nMaxResolution;
extern unsigned nMinResolution;
extern unsigned nSubResolutionLevels;
extern unsigned nMinViews;
extern unsigned nMaxViews;
extern unsigned nMinViewsFuse;
extern unsigned nMaxViewsFuse;
extern unsigned nMinViewsFilter;
extern unsigned nMinViewsFilterAdjust;
extern unsigned nMinViewsTrustPoint;
extern unsigned nNumViews;
extern unsigned nMinPixelsFuse;
extern unsigned nMaxPointsFuse;
extern unsigned nMaxFuseDepth;
extern unsigned nPointInsideROI;
extern bool bFilterAdjust;
extern bool bAddCorners;
Expand All @@ -113,6 +122,7 @@ extern float fMinAngle;
extern float fOptimAngle;
extern float fMaxAngle;
extern float fDescriptorMinMagnitudeThreshold;
extern float fDepthReprojectionErrorThreshold;
extern float fDepthDiffThreshold;
extern float fNormalDiffThreshold;
extern float fPairwiseMul;
Expand All @@ -122,6 +132,7 @@ extern unsigned nSpeckleSize;
extern unsigned nIpolGapSize;
extern int nIgnoreMaskLabel;
extern unsigned nOptimize;
extern unsigned nFuseFilter;
extern unsigned nEstimateColors;
extern unsigned nEstimateNormals;
extern float fNCCThresholdKeep;
Expand Down
Loading

0 comments on commit adaeecc

Please sign in to comment.