Skip to content

Commit

Permalink
dense: implement Semi-Global Matching
Browse files Browse the repository at this point in the history
  • Loading branch information
cdcseacave committed Feb 16, 2020
1 parent 51b5bd0 commit efe02f4
Show file tree
Hide file tree
Showing 21 changed files with 4,162 additions and 279 deletions.
75 changes: 42 additions & 33 deletions MvgMvsPipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,43 @@
[--0 0 [0 ...]] [--1 1 [1 ...]] [--2 2 [2 ...]]
[--3 3 [3 ...]] [--4 4 [4 ...]] [--5 5 [5 ...]]
[--6 6 [6 ...]] [--7 7 [7 ...]] [--8 8 [8 ...]]
[--9 9 [9 ...]] [--10 10 [10 ...]]
[--11 11 [11 ...]] [--12 12 [12 ...]]
[--13 13 [13 ...]]
[--9 9 [9 ...]] [--10 10 [10 ...]] [--11 11 [11 ...]]
[--12 12 [12 ...]] [--13 13 [13 ...]]
[--14 14 [14 ...]] [--15 15 [15 ...]]
input_dir output_dir
Photogrammetry reconstruction with these steps:
0. Intrinsics analysis openMVG_main_SfMInit_ImageListing
1. Compute features openMVG_main_ComputeFeatures
2. Compute matches openMVG_main_ComputeMatches
3. Incremental reconstruction openMVG_main_IncrementalSfM
4. Global reconstruction openMVG_main_GlobalSfM
5. Colorize Structure openMVG_main_ComputeSfM_DataColor
6. Structure from Known Poses openMVG_main_ComputeStructureFromKnownPoses
7. Colorized robust triangulation openMVG_main_ComputeSfM_DataColor
8. Control Points Registration ui_openMVG_control_points_registration
9. Export to openMVS openMVG_main_openMVG2openMVS
10. Densify point cloud DensifyPointCloud
11. Reconstruct the mesh ReconstructMesh
12. Refine the mesh RefineMesh
13. Texture the mesh TextureMesh
0. Intrinsics analysis openMVG_main_SfMInit_ImageListing
1. Compute features openMVG_main_ComputeFeatures
2. Compute matches openMVG_main_ComputeMatches
3. Incremental reconstruction openMVG_main_IncrementalSfM
4. Global reconstruction openMVG_main_GlobalSfM
5. Colorize Structure openMVG_main_ComputeSfM_DataColor
6. Structure from Known Poses openMVG_main_ComputeStructureFromKnownPoses
7. Colorized robust triangulation openMVG_main_ComputeSfM_DataColor
8. Control Points Registration ui_openMVG_control_points_registration
9. Export to openMVS openMVG_main_openMVG2openMVS
10. Densify point-cloud DensifyPointCloud
11. Reconstruct the mesh ReconstructMesh
12. Refine the mesh RefineMesh
13. Texture the mesh TextureMesh
14. Estimate disparity-maps DensifyPointCloud
15. Fuse disparity-maps DensifyPointCloud
positional arguments:
input_dir the directory wich contains the pictures set.
output_dir the directory wich will contain the resulting files.
input_dir the directory wich contains the pictures set.
output_dir the directory wich will contain the resulting files.
optional arguments:
-h, --help show this help message and exit
--steps STEPS [STEPS ...]
steps to process
--preset PRESET steps list preset in
SEQUENTIAL = [0, 1, 2, 3, 9, 10, 11, 12, 13]
GLOBAL = [0, 1, 2, 4, 9, 10, 11, 12, 13]
MVG_SEQ = [0, 1, 2, 3, 5, 6, 7]
MVG_GLOBAL = [0, 1, 2, 4, 5, 6, 7]
default : SEQUENTIAL
-h, --help show this help message and exit
--steps STEPS [STEPS ...] steps to process
--preset PRESET steps list preset in
SEQUENTIAL = [0, 1, 2, 3, 9, 10, 11, 12, 13]
GLOBAL = [0, 1, 2, 4, 9, 10, 11, 12, 13]
MVG_SEQ = [0, 1, 2, 3, 5, 6, 7]
MVG_GLOBAL = [0, 1, 2, 4, 5, 6, 7]
MVS_SGM = [14, 15]
default : SEQUENTIAL
Passthrough:
Option to be passed to command lines (remove - in front of option names)
Expand Down Expand Up @@ -108,7 +110,8 @@ def find(afile):
PRESET = {'SEQUENTIAL': [0, 1, 2, 3, 9, 10, 11, 12, 13],
'GLOBAL': [0, 1, 2, 4, 9, 10, 11, 12, 13],
'MVG_SEQ': [0, 1, 2, 3, 5, 6, 7],
'MVG_GLOBAL': [0, 1, 2, 4, 5, 6, 7]}
'MVG_GLOBAL': [0, 1, 2, 4, 5, 6, 7],
'MVS_SGM': [14, 15]}

PRESET_DEFAULT = 'SEQUENTIAL'

Expand Down Expand Up @@ -199,16 +202,22 @@ def __init__(self):
["-i", "%reconstruction_dir%/sfm_data.bin", "-o", "%mvs_dir%/scene.mvs", "-d", "%mvs_dir%/images"]],
["Densify point cloud", # 10
os.path.join(OPENMVS_BIN, "DensifyPointCloud"),
["--input-file", "%mvs_dir%/scene.mvs", "--resolution-level", "1", "-w", "%mvs_dir%"]],
["scene.mvs", "--dense-config-file", "Densify.ini", "--resolution-level", "1", "-w", "%mvs_dir%"]],
["Reconstruct the mesh", # 11
os.path.join(OPENMVS_BIN, "ReconstructMesh"),
["%mvs_dir%/scene_dense.mvs", "-w", "%mvs_dir%"]],
["scene_dense.mvs", "-w", "%mvs_dir%"]],
["Refine the mesh", # 12
os.path.join(OPENMVS_BIN, "RefineMesh"),
["%mvs_dir%/scene_dense_mesh.mvs", "--scales", "2", "-w", "%mvs_dir%"]],
["scene_dense_mesh.mvs", "--scales", "2", "-w", "%mvs_dir%"]],
["Texture the mesh", # 13
os.path.join(OPENMVS_BIN, "TextureMesh"),
["scene_dense_mesh_refine.mvs", "--decimate", "0.5", "-w", "%mvs_dir%"]]
["scene_dense_mesh_refine.mvs", "--decimate", "0.5", "-w", "%mvs_dir%"]],
["Estimate disparity-maps", # 14
os.path.join(OPENMVS_BIN, "DensifyPointCloud"),
["scene.mvs", "--dense-config-file", "Densify.ini", "--fusion-mode", "-1", "-w", "%mvs_dir%"]],
["Fuse disparity-maps", # 15
os.path.join(OPENMVS_BIN, "DensifyPointCloud"),
["scene.mvs", "--dense-config-file", "Densify.ini", "--fusion-mode", "-2", "-w", "%mvs_dir%"]]
]

def __getitem__(self, indice):
Expand Down
11 changes: 9 additions & 2 deletions apps/DensifyPointCloud/DensifyPointCloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ String strMeshFileName;
String strDenseConfigFileName;
float fSampleMesh;
int thFilterPointCloud;
int nFusionMode;
int nArchiveType;
int nProcessPriority;
unsigned nMaxThreads;
Expand Down Expand Up @@ -107,6 +108,7 @@ bool Initialize(size_t argc, LPCTSTR* argv)
("estimate-normals", boost::program_options::value(&nEstimateNormals)->default_value(0), "estimate the normals for the dense point-cloud")
("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)")
("filter-point-cloud", boost::program_options::value(&OPT::thFilterPointCloud)->default_value(0), "filter dense point-cloud based on visibility (0 - disabled)")
("fusion-mode", boost::program_options::value(&OPT::nFusionMode)->default_value(0), "depth map fusion mode (-2 - fuse disparity-maps, -1 - export disparity-maps only, 0 - depth-maps & fusion, 1 - export depth-maps only)")
;

// hidden options, allowed both on command line and
Expand Down Expand Up @@ -256,8 +258,13 @@ int main(int argc, LPCTSTR* argv)
}
if ((ARCHIVE_TYPE)OPT::nArchiveType != ARCHIVE_MVS) {
TD_TIMER_START();
if (!scene.DenseReconstruction())
return EXIT_FAILURE;
if (!scene.DenseReconstruction(OPT::nFusionMode)) {
if (ABS(OPT::nFusionMode) != 1)
return EXIT_FAILURE;
VERBOSE("Depth-maps estimated (%s)", TD_TIMER_GET_FMT().c_str());
Finalize();
return EXIT_SUCCESS;
}
VERBOSE("Densifying point-cloud completed: %u points (%s)", scene.pointcloud.GetSize(), TD_TIMER_GET_FMT().c_str());
}

Expand Down
13 changes: 13 additions & 0 deletions libs/Common/EventQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,16 @@ uint_t EventQueue::GetSize() const
return m_events.GetSize();
}
/*----------------------------------------------------------------*/



/*-----------------------------------------------------------*
* EventThreadPool class implementation *
*-----------------------------------------------------------*/

void EventThreadPool::stop()
{
ThreadPool::stop();
EventQueue::Clear();
}
/*----------------------------------------------------------------*/
14 changes: 14 additions & 0 deletions libs/Common/EventQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ class GENERAL_API EventQueue
};
/*----------------------------------------------------------------*/


// basic event and thread pool
class GENERAL_API EventThreadPool : public ThreadPool, public EventQueue
{
public:
inline EventThreadPool() {}
inline EventThreadPool(size_type nThreads) : ThreadPool(nThreads) {}
inline EventThreadPool(size_type nThreads, Thread::FncStart pfnStarter, void* pData=NULL) : ThreadPool(nThreads, pfnStarter, pData) {}
inline ~EventThreadPool() {}

void stop(); //stop threads, reset locks state and empty event queue
};
/*----------------------------------------------------------------*/

} // namespace SEACAVE

#endif // __SEACAVE_EVENTQUEUE_H__
92 changes: 88 additions & 4 deletions libs/Common/File.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,66 @@

#include "Streams.h"

// Under both Windows and Unix, the stat function is used for classification

// Under Gnu/Linux, the following classifications are defined
// source: Gnu/Linux man page for stat(2) http://linux.die.net/man/2/stat
// S_IFMT 0170000 bitmask for the file type bitfields
// S_IFSOCK 0140000 socket (Note this overlaps with S_IFDIR)
// S_IFLNK 0120000 symbolic link
// S_IFREG 0100000 regular file
// S_IFBLK 0060000 block device
// S_IFDIR 0040000 directory
// S_IFCHR 0020000 character device
// S_IFIFO 0010000 FIFO
// There are also some Posix-standard macros:
// S_ISREG(m) is it a regular file?
// S_ISDIR(m) directory?
// S_ISCHR(m) character device?
// S_ISBLK(m) block device?
// S_ISFIFO(m) FIFO (named pipe)?
// S_ISLNK(m) symbolic link? (Not in POSIX.1-1996.)
// S_ISSOCK(m) socket? (Not in POSIX.1-1996.)
// Under Windows, the following are defined:
// source: Header file sys/stat.h distributed with Visual Studio 10
// _S_IFMT (S_IFMT) 0xF000 file type mask
// _S_IFREG (S_IFREG) 0x8000 regular
// _S_IFDIR (S_IFDIR) 0x4000 directory
// _S_IFCHR (S_IFCHR) 0x2000 character special
// _S_IFIFO 0x1000 pipe

#ifdef _MSC_VER
#include <io.h>
// file type tests are not defined for some reason on Windows despite them providing the stat() function!
#define F_OK 0
#define X_OK 1
#define W_OK 2
#define R_OK 4
// Posix-style macros for Windows
#ifndef S_ISREG
#define S_ISREG(mode) ((mode & _S_IFMT) == _S_IFREG)
#endif
#ifndef S_ISDIR
#define S_ISDIR(mode) ((mode & _S_IFMT) == _S_IFDIR)
#endif
#ifndef S_ISCHR
#define S_ISCHR(mode) ((mode & _S_IFMT) == _S_IFCHR)
#endif
#ifndef S_ISBLK
#define S_ISBLK(mode) (false)
#endif
#ifndef S_ISFIFO
#define S_ISFIFO(mode) ((mode & _S_IFMT) == _S_IFIFO)
#endif
#ifndef S_ISLNK
#define S_ISLNK(mode) (false)
#endif
#ifndef S_ISSOCK
#define S_ISSOCK(mode) (false)
#endif
#else
#include <unistd.h>
#include <dirent.h>
#define _taccess access
#endif

Expand Down Expand Up @@ -282,7 +338,7 @@ class GENERAL_API File : public IOStream {
size_f_t totalSize = 0;
String strPath(_strPath);
Util::ensureFolderSlash(strPath);
//Find all the files in this folder.
// Find all the files in this folder.
hFind = FindFirstFile((strPath + strMask).c_str(), &fd);
if (hFind != INVALID_HANDLE_VALUE)
{
Expand All @@ -304,7 +360,7 @@ class GENERAL_API File : public IOStream {
while (FindNextFile(hFind, &fd));
FindClose(hFind);
}
//Process the subfolders also...
// Process the subfolders also...
if (!bProcessSubdir)
return totalSize;
hFind = FindFirstFile((strPath + '*').c_str(), &fd);
Expand All @@ -318,7 +374,7 @@ class GENERAL_API File : public IOStream {
continue;
if (!_tcscmp(fd.cFileName, _T("..")))
continue;
// Processe all subfolders recursively
// Process all subfolders recursively
totalSize += findFiles(strPath + fd.cFileName + PATH_SEPARATOR, strMask, true, arrFiles);
}
while (FindNextFile(hFind, &fd));
Expand Down Expand Up @@ -490,7 +546,35 @@ class GENERAL_API File : public IOStream {

#endif // _MSC_VER

static bool access(LPCTSTR aFileName, int mode=CA_EXIST) { return ::_taccess(aFileName, mode) == 0; }
// test for whether there's something (i.e. folder or file) with this name
// and what access mode is supported
static bool isPresent(LPCTSTR path) {
struct stat buf;
return stat(path, &buf) == 0;
}
static bool access(LPCTSTR path, int mode=CA_EXIST) {
return ::_taccess(path, mode) == 0;
}
// test for whether there's something present and its a folder
static bool isFolder(LPCTSTR path) {
struct stat buf;
if (!(stat(path, &buf) == 0))
return false;
// If the object is present, see if it is a directory
// this is the Posix-approved way of testing
return S_ISDIR(buf.st_mode);
}
// test for whether there's something present and its a file
// a file can be a regular file, a symbolic link, a FIFO or a socket, but not a device
static bool isFile(LPCTSTR path) {
struct stat buf;
if (!(stat(path, &buf) == 0))
return false;
// If the object is present, see if it is a file or file-like object
// Note that devices are neither folders nor files
// this is the Posix-approved way of testing
return S_ISREG(buf.st_mode) || S_ISLNK(buf.st_mode) || S_ISSOCK(buf.st_mode) || S_ISFIFO(buf.st_mode);
}

template <class VECTOR>
inline size_t write(const VECTOR& arr) {
Expand Down
Loading

0 comments on commit efe02f4

Please sign in to comment.