cdcseacave / openMVS

open Multi-View Stereo reconstruction library
http://cdcseacave.github.io
GNU Affero General Public License v3.0
3.18k stars 891 forks source link

openMVS doesn't produce any results on windows 10 x64 #508

Open piecemakerz opened 4 years ago

piecemakerz commented 4 years ago

I'm trying to work openMVG & openMVS, and openMVG works but openMVS doesn't produce any results. I'm using the most recent openMVS version and followed every steps on Build without any critical error. I installed every dependencies using vcpkg on a folder where vcpkg is installed, and successfully configured and generated openMVS using cmake-gui, and built MSVC using visual studio 15 2017 on Release mode.

But when I try to run openMVS with OpenMVG + OpenMVS pipeline posted here, openMVG gives me results but openMVS 'runs' but doesn't 'generate' any results. It doesn't produce any error, but just doesn't produce anything except bunch of log files.

Below is the texture result when running MvgMvs_Pipeline.py with Python 3.7. Skipped openMVG part since it works fine.

(openMVG_Project) D:\Users\HyukWonLee\Desktop\openMVG_Project>python MvgMvs_Pipeline.py D:\Users\HyukWonLee\Desktop\openMVG_
Materials\Input\images D:\Users\HyukWonLee\Desktop\openMVG_Materials\Output
# Using input dir  :  D:\Users\HyukWonLee\Desktop\openMVG_Materials\Input\images
#       output_dir :  D:\Users\HyukWonLee\Desktop\openMVG_Materials\Output
# First step  :  0
# Last step :  10
#0. Intrinsics analysis
 You called :

...
...
...

- UNDISTORT IMAGES -
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
**********************************************
******
Scene saved to OpenMVS interface format:
 #platforms: 1
  platform ( 0 ) #cameras: 1
  11 images (11 calibrated)
  6061 Landmarks
#5. Densify point cloud
17:37:34 [App     ] Build date: Dec 19 2019, 17:23:38
17:37:34 [App     ] CPU: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz (8 cores)
17:37:34 [App     ] RAM: 15.91GB Physical Memory 128.00TB Virtual Memory
17:37:34 [App     ] OS: Windows 8 x64
17:37:34 [App     ] SSE & AVX compatible CPU & OS detected
17:37:34 [App     ] Command line: --input-file D:\Users\HyukWonLee\Desktop\openMVG_Materials\Output\mvs/scene.mvs --resoluti
on-level 0 -w D:\Users\HyukWonLee\Desktop\openMVG_Materials\Output\mvs
#6. Reconstruct the mesh
17:37:36 [App     ] Build date: Dec 19 2019, 17:23:38
17:37:36 [App     ] CPU: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz (8 cores)
17:37:36 [App     ] RAM: 15.91GB Physical Memory 128.00TB Virtual Memory
17:37:36 [App     ] OS: Windows 8 x64
17:37:36 [App     ] SSE & AVX compatible CPU & OS detected
17:37:36 [App     ] Command line: D:\Users\HyukWonLee\Desktop\openMVG_Materials\Output\mvs/scene_dense.mvs -w D:\Users\HyukW
onLee\Desktop\openMVG_Materials\Output\mvs

17:37:37 [App     ] Build date: Dec 19 2019, 17:23:38
17:37:37 [App     ] CPU: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz (8 cores)
17:37:37 [App     ] RAM: 15.91GB Physical Memory 128.00TB Virtual Memory
17:37:37 [App     ] OS: Windows 8 x64
17:37:37 [App     ] SSE & AVX compatible CPU & OS detected
17:37:37 [App     ] Command line: D:\Users\HyukWonLee\Desktop\openMVG_Materials\Output\mvs/scene_dense_mesh.mvs -w D:\Users\
HyukWonLee\Desktop\openMVG_Materials\Output\mvs
#8. Texture the mesh
17:37:38 [App     ] Build date: Dec 19 2019, 17:23:38
17:37:38 [App     ] CPU: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz (8 cores)
17:37:38 [App     ] RAM: 15.91GB Physical Memory 128.00TB Virtual Memory
17:37:38 [App     ] OS: Windows 8 x64
17:37:38 [App     ] SSE & AVX compatible CPU & OS detected
17:37:38 [App     ] Command line: D:\Users\HyukWonLee\Desktop\openMVG_Materials\Output\mvs/scene_dense_mesh_refine.mvs -w D:
\Users\HyukWonLee\Desktop\openMVG_Materials\Output\mvs

I get bunch of log text files in mvs folder, not mvs files that I need. I want to know the reason why openMVS doesn't generate any result without error. Maybe because openMVS detects wrong OS? (since I'm using windows 10 x64 but openMVS detects it as Windows 8 x64)

This is the python code I used. only change PATH variables for my system.

#!/usr/bin/python
# ! -*- encoding: utf-8 -*-
#
# Created by @FlachyJoe
# Edited by @petern3
#
# this script is for easy use of OpenMVG and OpenMVS
#
# usage: MvgMvs_Pipeline.py [-h] [-f FIRST_STEP] [-l LAST_STEP] [--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 ...]]
#                          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). Colorize Structure             openMVG_main_ComputeSfM_DataColor
#   (5). Structure from Known Poses     openMVG_main_ComputeStructureFromKnownPoses
#   (6). Colorized robust triangulation openMVG_main_ComputeSfM_DataColor
#    4. Export to openMVS               openMVG_main_openMVG2openMVS
#    5. Densify point cloud             OpenMVS/DensifyPointCloud
#    6. Reconstruct the mesh            OpenMVS/ReconstructMesh
#    7. Refine the mesh                 OpenMVS/RefineMesh
#    8. Texture the mesh                OpenMVS/TextureMesh
#
# positional arguments:
#  input_dir             the directory which contains the pictures set.
#  output_dir            the directory which will contain the resulting files.
#
# optional arguments:
#  -h, --help            show this help message and exit
#  -f FIRST_STEP, --first_step FIRST_STEP
#                        the first step to process
#  -l LAST_STEP, --last_step LAST_STEP
#                        the last step to process
#
# Passthrough:
#  Option to be pass to command lines (remove - in front of option names)
#  e.g. --1 p ULTRA to use the ULTRA preset in openMVG_main_ComputeFeatures

import os
import subprocess
import sys

# CHANGE THE FOLLOWING PATHS TO SUIT YOUR SYSTEM

platform = sys.platform
if platform.startswith("win32"):
    # Indicate the openMVG and openMVS binary directories
    OPENMVG_SFM_BIN = "D:/Users/HyukWonLee/Desktop/openMVG-build/Windows-AMD64-Release/Release"
    OPENMVS_BIN = "D:/Users/HyukWonLee/Desktop/openMVS/build/bin/vc15/x64/Release"
    # Indicate the openMVG camera sensor width directory
    CAMERA_SENSOR_WIDTH_DIRECTORY = "D:/Users/HyukWonLee/Desktop/openMVG/src/openMVG/exif/sensor_width_database"

elif platform.startswith("linux"):
    # Indicate the openMVG and openMVS binary directories
    OPENMVG_SFM_BIN = "/usr/local/bin/"
    OPENMVS_BIN = "/usr/local/bin/OpenMVS/"
    # Indicate the openMVG camera sensor width directory
    CAMERA_SENSOR_WIDTH_DIRECTORY = "/usr/local/share/openMVG/"

DEBUG = False

## HELPERS for terminal colors
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
NO_EFFECT, BOLD, UNDERLINE, BLINK, INVERSE, HIDDEN = (0, 1, 4, 5, 7, 8)

# from Python cookbook, #475186
def has_colours(stream):
    if not hasattr(stream, "isatty"):
        return False
    if not stream.isatty():
        return False  # auto color only on TTYs
    try:
        import curses
        curses.setupterm()
        return curses.tigetnum("colors") > 2
    except:
        # guess false in case of error
        return False

has_colours = has_colours(sys.stdout)

def printout(text, colour=WHITE, background=BLACK, effect=NO_EFFECT):
    if has_colours:
        seq = "\x1b[{};{};{}m".format(effect, 30 + colour, 40 + background) + text + "\x1b[0m"
        sys.stdout.write(seq + '\r\n')
    else:
        sys.stdout.write(text + '\r\n')

## OBJECTS to store config and data in

class ConfContainer(object):
    """Container for all the config variables"""
    pass

conf = ConfContainer()

class aStep:
    def __init__(self, info, cmd, opt):
        self.info = info
        self.cmd = cmd
        self.opt = opt

class stepsStore:
    def __init__(self):
        self.steps_data = [
            ["Intrinsics analysis",
             os.path.join(OPENMVG_SFM_BIN, "openMVG_main_SfMInit_ImageListing"),
             ["-i", "%input_dir%", "-o", "%matches_dir%", "-d", "%camera_file_params%"]],
            ["Compute features",
             os.path.join(OPENMVG_SFM_BIN, "openMVG_main_ComputeFeatures"),
             ["-i", "%matches_dir%/sfm_data.json", "-o", "%matches_dir%", "-m", "SIFT"]],
            ["Compute matches",
             os.path.join(OPENMVG_SFM_BIN, "openMVG_main_ComputeMatches"),
             ["-i", "%matches_dir%/sfm_data.json", "-o", "%matches_dir%"]],
            ["Incremental reconstruction",
             os.path.join(OPENMVG_SFM_BIN, "openMVG_main_IncrementalSfM"),
             ["-i", "%matches_dir%/sfm_data.json", "-m", "%matches_dir%", "-o", "%reconstruction_dir%"]],
            # [   "Colorize Structure",
            #    os.path.join(OPENMVG_SFM_BIN,"openMVG_main_ComputeSfM_DataColor"),
            #    ["-i", "%reconstruction_dir%/sfm_data.bin", "-o", "%reconstruction_dir%/colorized.ply"]],
            # [   "Structure from Known Poses",
            #    os.path.join(OPENMVG_SFM_BIN,"openMVG_main_ComputeStructureFromKnownPoses"),
            #    ["-i", "%reconstruction_dir%/sfm_data.bin", "-m", "%matches_dir%", "-f", "%matches_dir%/matches.f.bin", "-o", "%reconstruction_dir%/robust.bin"]],
            # [   "Colorized robust triangulation",
            #    os.path.join(OPENMVG_SFM_BIN,"openMVG_main_ComputeSfM_DataColor"),
            #    ["-i", "%reconstruction_dir%/robust.bin", "-o", "%reconstruction_dir%/robust_colorized.ply"]],
            ["Export to openMVS",
             os.path.join(OPENMVG_SFM_BIN, "openMVG_main_openMVG2openMVS"),
             ["-i", "%reconstruction_dir%/sfm_data.bin", "-o", "%mvs_dir%/scene.mvs", "-d", "%mvs_dir%"]],
            ["Densify point cloud",
             os.path.join(OPENMVS_BIN, "DensifyPointCloud"),
             ["--input-file", "%mvs_dir%/scene.mvs", "--resolution-level", "0", "-w", "%mvs_dir%"]],
            ["Reconstruct the mesh",
             os.path.join(OPENMVS_BIN, "ReconstructMesh"),
             ["%mvs_dir%/scene_dense.mvs", "-w", "%mvs_dir%"]],
            ["Refine the mesh",
             os.path.join(OPENMVS_BIN, "RefineMesh"),
             ["%mvs_dir%/scene_dense_mesh.mvs", "-w", "%mvs_dir%"]],
            ["Texture the mesh",
             os.path.join(OPENMVS_BIN, "TextureMesh"),
             ["%mvs_dir%/scene_dense_mesh_refine.mvs", "-w", "%mvs_dir%"]]
        ]

    def __getitem__(self, indice):
        return aStep(*self.steps_data[indice])

    def length(self):
        return len(self.steps_data)

    def apply_conf(self, conf):
        """ replace each %var% per conf.var value in steps data """
        for s in self.steps_data:
            o2 = []
            for o in s[2]:
                co = o.replace("%input_dir%", conf.input_dir)
                co = co.replace("%output_dir%", conf.output_dir)
                co = co.replace("%matches_dir%", conf.matches_dir)
                co = co.replace("%reconstruction_dir%", conf.reconstruction_dir)
                co = co.replace("%mvs_dir%", conf.mvs_dir)
                co = co.replace("%camera_file_params%", conf.camera_file_params)
                o2.append(co)
            s[2] = o2

steps = stepsStore()

## ARGS
import argparse

parser = argparse.ArgumentParser(
    formatter_class=argparse.RawDescriptionHelpFormatter,
    description="Photogrammetry reconstruction with these steps : \r\n" +
                "\r\n".join(("\t{}. {}\t {}".format(t, steps[t].info, steps[t].cmd) for t in range(steps.length())))
)
parser.add_argument('input_dir', help="the directory wich contains the pictures set.")
parser.add_argument('output_dir', help="the directory wich will contain the resulting files.")
parser.add_argument('-f', '--first_step', type=int, default=0, help="the first step to process")
parser.add_argument('-l', '--last_step', type=int, default=10, help="the last step to process")

group = parser.add_argument_group('Passthrough',
                                  description="Option to be passed to command lines (remove - in front of option names)\r\ne.g. --1 p ULTRA to use the ULTRA preset in openMVG_main_ComputeFeatures")
for n in range(steps.length()):
    group.add_argument('--' + str(n), nargs='+')

parser.parse_args(namespace=conf)  # store args in the ConfContainer

## FOLDERS

def mkdir_ine(dirname):
    """Create the folder if not presents"""
    if not os.path.exists(dirname):
        os.mkdir(dirname)

# Absolute path for input and ouput dirs
conf.input_dir = os.path.abspath(conf.input_dir)
conf.output_dir = os.path.abspath(conf.output_dir)

if not os.path.exists(conf.input_dir):
    sys.exit("{} : path not found".format(conf.input_dir))

conf.matches_dir = os.path.join(conf.output_dir, "matches")
conf.reconstruction_dir = os.path.join(conf.output_dir, "reconstruction_sequential")
conf.mvs_dir = os.path.join(conf.output_dir, "mvs")
conf.camera_file_params = os.path.join(CAMERA_SENSOR_WIDTH_DIRECTORY, "sensor_width_camera_database.txt")

mkdir_ine(conf.output_dir)
mkdir_ine(conf.matches_dir)
mkdir_ine(conf.reconstruction_dir)
mkdir_ine(conf.mvs_dir)

steps.apply_conf(conf)

## WALK
print("# Using input dir  :  {}".format(conf.input_dir))
print("#       output_dir :  {}".format(conf.output_dir))
print("# First step  :  {}".format(conf.first_step))
print("# Last step :  {}".format(conf.last_step))
for cstep in range(conf.first_step, conf.last_step + 1):
    try:
        printout("#{}. {}".format(cstep, steps[cstep].info), effect=INVERSE)
    except IndexError:
        # There are not enough steps in stepsStore.step_data to get to last_step
        break

    opt = getattr(conf, str(cstep))
    if opt is not None:
        # add - sign to short options and -- to long ones
        for o in range(0, len(opt), 2):
            if len(opt[o]) > 1:
                opt[o] = '-' + opt[o]
            opt[o] = '-' + opt[o]
    else:
        opt = []

    # Remove steps[cstep].opt options now defined in opt
    for anOpt in steps[cstep].opt:
        if anOpt in opt:
            idx = steps[cstep].opt.index(anOpt)
            if DEBUG:
                print('#\t' + 'Remove ' + str(anOpt) + ' from defaults options at id ' + str(idx))
            del steps[cstep].opt[idx:idx + 2]

    cmdline = [steps[cstep].cmd] + steps[cstep].opt + opt

    if not DEBUG:
        pStep = subprocess.Popen(cmdline)
        pStep.wait()
    else:
        print('\t' + ' '.join(cmdline))
cdcseacave commented 4 years ago

pls download the binaries and try to run the reconstruction as instructed in the wiki

Yzhbuaa commented 3 years ago

I have the same issue with DensifyPointCloud and ReconstructMesh.

Yzhbuaa commented 3 years ago

It seems the scene.mvs file exported using openMVG is corrupted. Cause when I use the scene.mvs file provided in openMVS_Sample(https://github.com/cdcseacave/openMVS_sample) as the input of openMVS's Reconstructmesh, everything works fine.