Photogrammetry?

Hi, is anyone using an photogrammetry software on opensuse?

From what I can see, the usual suspects aren’t packaged, and by usual suspects, I mean COLMAP, e-foto, openMVG, openMVS, VisualSFM, and even most of the command-line apps. COLMAP won’t do me much good anyway, since it requires nvidia and cuda.

These are available in deb-package land, but there are two problems. First, a virtualbox running ubuntu can only use 70% of your computer’s resources, and you typically want all you can get for photogrammetry. The second problem is that I’ve tried this method and found nothing but trouble with either crash on start or failure to install due to deprecated dependencies. (I don’t have much experience compiling from source, and my attempts have been stymied by those same deprecated dependencies.) The packages I’ve converted to rpm with alien (COLMAP and e-foto) didn’t work either.

What I have been able to find is an older version of COLMAP available as a snap that seems to work, though I can’t test the most important part, the dense cloud reconstruction, because I have radeon instead of nvidia. Other photogrammetry software available as snaps doesn’t seem to work for various reasons. VisualSFM for instance opens but just has squares where the text should be (like in the menu entries).

What I have been able to find on at software.opensuse.org is micmac, a command-line tool packaged for centos. Because it’s designed with as few dependencies as possible, it installs and seems to run on Tumbleweed. (I also found a blogger who’s compiled patched versions of openMVG and openMVS for Fedora, but they don’t work for me.) Installing software packaged for another distro isn’t exactly best practice, but if there’s anything native (and preferable with a GUI), I’m haven’t found it. Is it there? And if not, what have you managed to compile from source?

In theory, the Python Photogrammetry Toolbox works with Python 2.7 and comes with everything else it needs (including some sample photos), from here: https://github.com/steve-vincent/photogrammetry

So I downloaded the zip, extracted the linux folder, edited the shell script that launches the GUI with the path to which I extraced it, created a menu entry, and launched. No joy - it runs awhile and then quits with no output. Fortunately, it showed me the command it was running, so I tried that in terminal myself:


gef@purplebox:~/PPT/linux> python ./RunBundler.py --photos=/home/gef/PPT/models/examples/kermit --featureExtractor=siftvlf
eat --maxPhotoDimension=1200
Working directory created: /tmp/osm-bundler-0o8AAU
BundlerMatching executable path: /home/gef/PPT/linux/software/bundler/bin/KeyMatchFull
Sift executable path: /home/gef/PPT/linux/software/vlfeat/bin/glx/sift

Processing photo 'kermit000.jpg':
        Extracting features with the SIFT method from VLFeat library...
Traceback (most recent call last):
  File "./RunBundler.py", line 9, in <module>
    manager.preparePhotos()
  File "/home/gef/PPT/linux/osmbundler/__init__.py", line 158, in preparePhotos
    self._preparePhoto(photoInfo)
  File "/home/gef/PPT/linux/osmbundler/__init__.py", line 270, in _preparePhoto
    self.extractFeatures(photo)
  File "/home/gef/PPT/linux/osmbundler/__init__.py", line 337, in extractFeatures
    self.featureExtractor.extract(photo, self.photoDict[photo])
  File "/home/gef/PPT/linux/osmbundler/features/siftvlfeat.py", line 16, in extract
    subprocess.call([self.executable, "%s.jpg.pgm" % photo, "-o", "%s.key" % photo])
  File "/usr/lib64/python2.7/subprocess.py", line 172, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib64/python2.7/subprocess.py", line 394, in __init__
    errread, errwrite)
  File "/usr/lib64/python2.7/subprocess.py", line 1047, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

I’m afraid I’ve precious little experience with either this software or with python in general, so I’m not sure how to troubleshoot errno 2 or whatever error will be next. Any ideas?

I’m not even into 3D modelling myself, just investigating on behalf of a friend who’s brand new to linux, so I’m looking for something that’s straightforward to use. PPT fills the bill, if I can get it to work with your help, but I’m open to any other tool that does the same job and has a simple GUI, if you know of one that’ll work.

It looks like you’ve dipped your toe into what other resources there are out there to obtain apps when they might not already be packaged in openSUSE. openSUSE has a lot of apps, but the universe of <all> apps is immensely larger than any single organization can provide.

So, it looks like you’ve identified that there are deb packages, and you’ve found for at least one app that the project’s sources are on Github and it was originally written in Python.

That can lead you to another possible source… Apps written in python are often found in the official python repository, today called PyPi. Also, apps in PyPi are typically extremely well maintained, have the latest versions but you can also find versions written to run in older versions of Python. The app you use to access, query, manage, install, and remove apps from PyPi is called “pip” which should already be installed in your system. You can think of pip as the tool to access PyPi the same way that you use zypper to access openSUSE repositories.

So, for instance, the following command will run the verion of pip available by default on your system, reach out to PyPi and update to the latest version from PyPi

pip i pip

Just like any other command you can view the ip “help” and MAN pages.

You may find that other apps might be written in other languages, and for many your options may be similar, so for example there are similar “official” repositories for Ruby and Perl as well.

You should also know that although you found your app as a Snap, Snap is a user-friendly version of using Linux containers that is today infinitesimally tiny compared to what is available in Docker. So, go ahead and do a search for every one of the apps you listed and you’ll probably find them all already pre-built as Docker containers (I searched 3 and found them all here)

https://hub.docker.com/

As you may know, Linux containers of all types run as bare metal apps, so there is zero overhead always.

Lastly,
I don’t know where you heard about Virtualbox Guests uses only 70% of resources, that’s probably very inaccurate. Since VBox is a Gen2 virtualization technology, it makes full use of hardware extensions, so the overhead isn’t likely more than about 3% compared to if running in the HostOS of that machine. There are exceptions, perticularly when I/O is involved (performance varies greatly according to the virtualization technology), but CPU and RAM perform nearly the same as the HostOS. If you’re talking about GPU performance, then again that will vary greatly depending on the virtualiztion technology, and will also depend greatly on what you’re asking the GPU to do.


Ok,
Now after saying all that above which might lead you to prefer running pre-compiled apps,
Regarding your specific error…

I’d say that the simplest thing to check is to read your error literally and check whether the following file exists

/usr/lib64/python2.7/subprocess.py

Also,
You should know that the python that’s installed by default in openSUSE is generally good enough to support running most apps, but often won’t be enough to compile code and often won’t be enough to run unusual apps. To have the full capability of the entire python libraries and apps, you should first add and configure the language library specific to your app (In this case Python 2) with the following

Run the following command in an elevated console

zypper ar -f https://download.opensuse.org/repositories/devel:/languages:/python/openSUSE_Tumbleweed/ Tumblewee_Python2_repo

And if that isn’t sufficient (usually is), then install a Python from PyPi
Recommend opening a separate Forum thread for that)

HTH,
TSU

Wow TSU, thanks for a thorough answer!

I’ve configured docker and found some images that look promising, so I’ll post back how it goes after I’ve had a chance to download and test. -GEF

PS: As for 70% resources on vbox, that what the settings config tool recommends as max. For instance, I have 12GB on this host, and it throws up a warning if I allocate more than 8 to the guest. I’d think I could allocate 11, because normally my memory monitor shows around 600MB in use for just the desktop. Ironically, it’s happy to allocate all 4 processors (but seems to think I have 8, and as far as I know, my amd cpu doesn’t support hyperthreading).

On Sun 08 Jul 2018 06:56:03 AM CDT, gfagan wrote:

Hi, is anyone using an photogrammetry software on opensuse?

From what I can see, the usual suspects aren’t packaged, and by usual
suspects, I mean COLMAP, e-foto, openMVG, openMVS, VisualSFM, and even
most of the command-line apps. COLMAP won’t do me much good anyway,
since it requires nvidia and cuda.

These are available in deb-package land, but there are two problems.
First, a virtualbox running ubuntu can only use 70% of your computer’s
resources, and you typically want all you can get for photogrammetry.
The second problem is that I’ve tried this method and found nothing but
trouble with either crash on start or failure to install due to
deprecated dependencies. (I don’t have much experience compiling from
source, and my attempts have been stymied by those same deprecated
dependencies.) The packages I’ve converted to rpm with alien (COLMAP and
e-foto) didn’t work either.

What I have been able to find is an older version of COLMAP available as
a snap that seems to work, though I can’t test the most important part,
the dense cloud reconstruction, because I have radeon instead of nvidia.
Other photogrammetry software available as snaps doesn’t seem to work
for various reasons. VisualSFM for instance opens but just has squares
where the text should be (like in the menu entries).

What I have been able to find on at software.opensuse.org is micmac, a
command-line tool packaged for centos. Because it’s designed with as few
dependencies as possible, it installs and seems to run on Tumbleweed. (I
also found a blogger who’s compiled patched versions of openMVG and
openMVS for Fedora, but they don’t work for me.) Installing software
packaged for another distro isn’t exactly best practice, but if there’s
anything native (and preferable with a GUI), I’m haven’t found it. Is it
there? And if not, what have you managed to compile from source?

Hi
Here is a test build of openMVS;

https://download.opensuse.org/repositories/home:/malcolmlewis:/TESTING/openSUSE_Tumbleweed/x86_64/openMVS-0.8-1.1.x86_64.rpm


Cheers Malcolm °¿° SUSE Knowledge Partner (Linux Counter #276890)
SLES 15 | GNOME Shell 3.26.2 | 4.12.14-23-default
If you find this post helpful and are logged into the web interface,
please show your appreciation and click on the star below… Thanks!

Cool, Malcolm. I’ll give it a try after work. I’ve got a version from docker but can’t get it to work (seems to crash on the step of making a folder for the output). -GEF

On Mon 09 Jul 2018 08:26:03 PM CDT, gfagan wrote:

Cool, Malcolm. I’ll give it a try after work. I’ve got a version from
docker but can’t get it to work (seems to crash on the step of making a
folder for the output). -GEF

Hi
Just working through openMVG, it takes awhile to build (1 hour
plus on 4 cores locally…). They still need clean up, but good enough
for a test :wink:


Cheers Malcolm °¿° SUSE Knowledge Partner (Linux Counter #276890)
SLES 15 | GNOME Shell 3.26.2 | 4.12.14-23-default
If you find this post helpful and are logged into the web interface,
please show your appreciation and click on the star below… Thanks!

If you want to max resources available to your virtualized guests (or, for that matter isolated isntances like Linux containers), you can build (or dual boot) a special stripped down, minimized instance of your HostOS.

I’d recommend something like the following to support Virtualbox (and to support VBox you likely need a full Desktop. If you used a Linux container or other virtualization, there’s a good chance you could install your HostOS either headless or running only a Window Manager, with no Desktop Manager.

openSUSE 15,
Installed in text (server) mode or running only openbox or icewm.
If Virtualbox is your choice for virtualization, then you can install XFCE, LXDE or LXQt as your Desktop. With these Desktops, you’ll need approx 2GB RAM allocated to your HostOS but you might be able to experiment with less.
If you can run Virtualbox without VBox virtual manager (ie manage your Guests entirely with command line),
You might be able to run your HostOS without a graphical Desktop and allocate only 768MB-1GB to your HostOS.

For any of the above possible configurations, your Guests can be allocated everything that’s left… and in almost all cases that’s vastly more than 70% of total system resources, no matter which specific resource you measure.

TSU

Well, docker’s giving me the same kinds of issues. With ryanfb/visualsfm, I get “cannot open display”. With spedenaave/dpg, which is openmvg and openmvs, I get a crash when it tries to create the output folder. (Heck, I can manually create the output folder, but I still get the crash.) As for PyPI, the famed photogrammetry toolkit isn’t there, as nearly as I can determine. So, I’m keeping my fingers crossed for Malcolm and happy to be the first tester, but openMVS requires a sparse point cloud as input, which I’ll need to generate with openMVG, so I’ll check your repo again tomorrow.

TSU, your experiment sounds interesting, but not in the cards at the moment because 1) my ssd is too small, 2) ironically I gave my only spare computer to the friend on whose behalf I’m now researching photogrammetry software, and 3) I haven’t forgotten your challenge to write a wiki on digital audio with opensuse! GEF

On Tue 10 Jul 2018 05:46:03 AM CDT, gfagan wrote:

Well, docker’s giving me the same kinds of issues. With
ryanfb/visualsfm, I get “cannot open display”. With spedenaave/dpg,
which is openmvg and openmvs, I get a crash when it tries to create the
output folder. (Heck, I can manually create the output folder, but I
still get the crash.) As for PyPI, the famed photogrammetry toolkit
isn’t there, as nearly as I can determine. So, I’m keeping my fingers
crossed for Malcolm and happy to be the first tester, but openMVS
requires a sparse point cloud as input, which I’ll need to generate with
openMVG, so I’ll check your repo again tomorrow.

TSU, your experiment sounds interesting, but not in the cards at the
moment because 1) my ssd is too small, 2) ironically I gave my only
spare computer to the friend on whose behalf I’m now researching
photogrammetry software, and 3) I haven’t forgotten your challenge to
write a wiki on digital audio with opensuse! GEF

Hi
Need to delve into the code, gcc8 DSO issues (seems to have hit a
few programs)… might need to create an upstream bug report, so might
be a few days :frowning:


Cheers Malcolm °¿° SUSE Knowledge Partner (Linux Counter #276890)
SLES 15 | GNOME Shell 3.26.2 | 4.12.14-23-default
If you find this post helpful and are logged into the web interface,
please show your appreciation and click on the star below… Thanks!

>might be a few days :frowning:

No worries. I’m just grateful there are people like you who can do this. I’ve heard the work described as non-trivial, and from what I’ve been able to tell with just a little research, any photogrammetry app has dependencies that aren’t commonly available, usually because they’re deprecated, which means that even if you roll your own, they could conflict with the versions already installed.

I’m curious how you picked openMVG+openMVS as your starting point. Do you have a preference for command-line tools, did you evaluate multiple pipelines and find this gave the best output, or was this just the pipeline where the scope of the project fit in with your capabilities and schedule?

GEF

Hi
Both openMVG and openMVS come with the libraries it needs if it determines the system libraries are not compatible, in the case of openMVS it needs vcglib, which in essence it’s just header files, however it uses the system eigen3 library so had to add a patch for it to be compatible…

For openMVG until a DSO fix is forthcoming I forced it to use gcc7, I’ve also enabled the Leap 15.0 build as this builds without problems…

I’m a packager… they where the ones I found sources for :wink: Not an end user for this stuff… but always need testers…

Found a script to automate the pipeline, but it requires changes at line 50. Paths for both OPENMVG_SFM_BIN and OPENMVS_BIN are just /usr/bin, but I can’t figure out where the camera width directory is.


#!/usr/bin/python
#! -*- encoding: utf-8 -*-
#
# Created by @FlachyJoe
#
# this script is for easy use of OpenMVG and OpenMVS
#
#usage: SfM_MyPipeline.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
#	7. Export to openMVS	 openMVG_main_openMVG2openMVS
#	8. Densify point cloud	 OpenMVS/DensifyPointCloud
#	9. Reconstruct the mesh	 OpenMVS/ReconstructMesh
#	10. Refine the mesh	 OpenMVS/RefineMesh
#
#positional arguments:
#  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
#  -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 commands
import os
import subprocess
import sys


# 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%d;%d;%dm" % (effect, 30+colour, 40+background) + text + "\x1b[0m"
                sys.stdout.write(seq+'
')
        else:
                sys.stdout.write(text+'
')


## 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", "-n", "4"] ],
               "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%"]]
            ]


    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 : 
"+
        "
".join(("	%i. %s	 %s" % (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)
e.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("%s : path not found" % 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  :  %s" % conf.input_dir
print "#       output_dir :  %s" % conf.output_dir
print "# First step  :  %i" % conf.first_step
print "# Last step :  %i" % conf.last_step
for cstep in range(conf.first_step, conf.last_step+1):
    printout("#%i. %s" % (cstep, steps[cstep].info), effect=INVERSE)


    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 '#	'+'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 '	'+' '.join(cmdline)

Aha - you’ll can download the sensor file here:

https://github.com/openMVG/openMVG/blob/master/src/openMVG/exif/sensor_width_database/sensor_width_camera_database.txt

In the script above, the directory would then be where you save it.

So, Python Photogrammetry Toolkit has two sets of sample images, a dozen apiece. I ran the script above, the process went quickly with so few images, and now I have output. So, that’s a result, and I’m posting it here for the benefit of the packager. However, I’m not quite sure what to do with the output - what I see in meshlab and blender looks like garbage or nothing at all - so I’m waiting for a call from my friend who knows this material, and I’ll provide a better evaluation at that time. -GEF

This is with the sample data provided for openMVG; as you see, I picked up some errors just near the end that look to my untrained eye like bugs in the script above:


gef@purplebox:~/System Use> MvgMvs_Pipeline.py /home/gef/datasets/images /home/gef/datasets/images/out  
# Using input dir  :  /home/gef/datasets/images
#       output_dir :  /home/gef/datasets/images/out
# First step  :  0
# Last step :  10
#0. Intrinsics analysis
 You called : 
/usr/bin/openMVG_main_SfMInit_ImageListing
--imageDirectory /home/gef/datasets/images
--sensorWidthDatabase /usr/local/bin/sensor_width_camera_database.txt
--outputDirectory /home/gef/datasets/images/out/matches
--focal -1
--intrinsics 
--camera_model 3
--group_camera_model 1


- Image listing -
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************


Warning & Error messages:
K.txt: Unkown image file format.
Readme.txt: Unkown image file format.




SfMInit_ImageListing report:
listed #File(s): 13
usable #File(s) listed in sfm_data: 11
usable #Intrinsic(s) listed in sfm_data: 1
#1. Compute features
 You called : 
/usr/bin/openMVG_main_ComputeFeatures
--input_file /home/gef/datasets/images/out/matches/sfm_data.json
--outdir /home/gef/datasets/images/out/matches
--describerMethod SIFT
--upright 0
--describerPreset NORMAL
--force 0
--numThreads 4




- EXTRACT FEATURES -
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************
Task done in (s): 16
#2. Compute matches
 You called : 
/usr/bin/openMVG_main_ComputeMatches
--input_file /home/gef/datasets/images/out/matches/sfm_data.json
--out_dir /home/gef/datasets/images/out/matches
Optional parameters:
--force 0
--ratio 0.8
--geometric_model f
--video_mode_matching -1
--pair_list 
--nearest_matching_method AUTO
--guided_matching 0
--cache_size unlimited


- Regions Loading -
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************


 - PUTATIVE MATCHES - 
Use: exhaustive pairwise matching
Using FAST_CASCADE_HASHING_L2 matcher
Using the OPENMP thread interface


- Matching -
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************
Task (Regions Matching) done in (s): 1


- Geometric filtering -
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************
Task done in (s): 0


 Export Adjacency Matrix of the pairwise's geometric matches
#3. Incremental reconstruction
Sequential/Incremental reconstruction
 Perform incremental SfM (Initial Pair Essential + Resection).




- Features Loading -
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************


Track building


Track filtering


Track export to internal struct


Track stats
------------------
-- Tracks Stats --
 Tracks number: 6160
 Images Id: 
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
------------------
TrackLength, Occurrence
        2       2949
        3       1196
        4       679
        5       435
        6       247
        7       231
        8       193
        9       151
        10      68
        11      11


Automatic selection of an initial pair:
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************
A-Contrario initial pair residual: 98.0546


Bundle Adjustment statistics (approximated RMSE):
 #views: 2
 #poses: 2
 #intrinsics: 1
 #tracks: 169
 #residuals: 676
 Initial RMSE: 2.70666
 Final RMSE: 2.43938
 Time (s): 0.0388854




=========================
 MSE Residual InitialPair Inlier:






SequentialSfMReconstructionEngine::ComputeResidualsMSE.
        -- #Tracks:     169
        -- Residual min:        0.000141827
        -- Residual median:     0.246541
        -- Residual max:         80.7133
        -- Residual mean:        1.1572
=========================


-------------------------------
-- Robust Resection of view: 4
  nfa=-234.651 inliers=130/133 precisionNormalized=0.00294887 precision=156.462 (iter=0 ,sample=108,18,120,111,20,129,)
  nfa=-361.451 inliers=117/133 precisionNormalized=9.09931e-05 precision=27.4844 (iter=9 ,sample=69,5,82,73,46,97,)
  nfa=-384.042 inliers=118/133 precisionNormalized=6.25499e-05 precision=22.7874 (iter=10 ,sample=123,127,98,60,78,54,)
  nfa=-431.094 inliers=119/133 precisionNormalized=2.62578e-05 precision=14.7642 (iter=11 ,sample=53,26,107,45,123,94,)
  nfa=-499.371 inliers=120/133 precisionNormalized=7.22746e-06 precision=7.74594 (iter=16 ,sample=3,100,67,114,31,80,)
  nfa=-529.345 inliers=122/133 precisionNormalized=4.94251e-06 precision=6.40553 (iter=81 ,sample=53,21,28,11,24,123,)
  nfa=-544.482 inliers=125/133 precisionNormalized=5.19121e-06 precision=6.56471 (iter=193 ,sample=21,43,67,40,74,94,)


-------------------------------
-- Robust Resection 
-- Resection status: 1
-- #Points used for Resection: 133
-- #Points validated by robust Resection: 125
-- Threshold: 6.56471
-------------------------------


Bundle Adjustment statistics (approximated RMSE):
 #views: 1
 #poses: 1
 #intrinsics: 1
 #tracks: 125
 #residuals: 250
 Initial RMSE: 1.50323
 Final RMSE: 1.22581
 Time (s): 0.00144942


###EDIT: snipped more "Robust Resection of view: X" because other wise this is too lon to post. 

-------------------------------
-- Structure from Motion (statistics):
-- #Camera calibrated: 11 from 11 input images.
-- #Tracks, #3D points: 6081
-------------------------------






SequentialSfMReconstructionEngine::ComputeResidualsMSE.
        -- #Tracks:     6081
        -- Residual min:        2.03824e-06
        -- Residual median:     0.151845
        -- Residual max:         3.96937
        -- Residual mean:        0.265477


Histogram of residuals:
0       |       32677
0.397   |       5722
0.794   |       1604
1.19    |       587
1.59    |       285
1.98    |       125
2.38    |       78
2.78    |       36
3.18    |       28
3.57    |       9
3.97




 Total Ac-Sfm took (s): 6
...Generating SfM_Report.html
...Export SfM_Data to disk.
#4. Colorize Structure


Compute scene structure color
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************
#5. Structure from Known Poses
Compute Structure from the provided poses


- Regions Loading -
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************
Loaded a sfm_data scene with:
 #views: 11
 #poses: 11
 #intrinsics: 1
 #tracks: 0
=============================================================
Robust triangulation of the tracks
 - Triangulation of guided epipolar geometry matches
=============================================================
Compute pairwise fundamental guided matching:
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************
Per triplet tracks validation (discard spurious correspondences):
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************
Tracks to structure conversion:
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
*****************************************************
Structure estimation took (s): 1.


#landmark found: 4514
...Generating SfM_Report.html
Found a sfm_data scene with:
 #views: 11
 #poses: 11
 #intrinsics: 1
 #tracks: 4514
#6. Colorized robust triangulation


Compute scene structure color
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************
#7. Export to openMVS


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)
  6081 Landmarks
#8. Densify point cloud
01:22:08 [App     ] Build date: Jul  9 2018, 12:00:00
01:22:08 [App     ] CPU: AMD A12-9700P RADEON R7, 10 COMPUTE CORES 4C+6G
01:22:08 [App     ] RAM: 11.27GB Physical Memory 16.00GB Virtual Memory
01:22:08 [App     ] OS: Linux 4.17.4-1-default (x86_64)
01:22:08 [App     ] SSE & AVX compatible CPU & OS detected
01:22:08 [App     ] Command line: --input-file /home/gef/datasets/images/out/mvs/scene.mvs --resolution-level 0
01:22:08 [App     ] Camera model loaded: platform 0; camera  0; f 1.054x1.054; poses 11
01:22:08 [IO      ] error: unknown image format '/home/gef/datasets/images/out/mvs/100_7100.JPG'
01:22:08 [App     ] error: failed loading image header
01:22:08 [App     ] error: failed reloading image '/home/gef/datasets/images/out/mvs/100_7100.JPG'
01:22:08 [App     ] error: invalid project
#9. Reconstruct the mesh
01:22:08 [App     ] Build date: Jul  9 2018, 12:00:00
01:22:08 [App     ] CPU: AMD A12-9700P RADEON R7, 10 COMPUTE CORES 4C+6G
01:22:08 [App     ] RAM: 11.27GB Physical Memory 16.00GB Virtual Memory
01:22:08 [App     ] OS: Linux 4.17.4-1-default (x86_64)
01:22:08 [App     ] SSE & AVX compatible CPU & OS detected
01:22:08 [App     ] Command line: /home/gef/datasets/images/out/mvs/scene_dense.mvs
#10. Refine the mesh
01:22:08 [App     ] Build date: Jul  9 2018, 12:00:00
01:22:08 [App     ] CPU: AMD A12-9700P RADEON R7, 10 COMPUTE CORES 4C+6G
01:22:08 [App     ] RAM: 11.27GB Physical Memory 16.00GB Virtual Memory
01:22:08 [App     ] OS: Linux 4.17.4-1-default (x86_64)
01:22:08 [App     ] SSE & AVX compatible CPU & OS detected
01:22:08 [App     ] Command line: /home/gef/datasets/images/out/mvs/scene_dense_mesh.mvs

If I understand correctly, the 3 steps with openMVS didn’t work, either because openMVS doesn’t read jpg or because the openMVG part of the script was supposed to create an output file that isn’t there.

Sorry Malcolm, I haven’t forgotten about you but my free time’s been et up, probably through Sunday. -GEF

Hey Malcolm, the Ultimate Multi-View Environment (UMVE) looked promising, command line tool with a GUI that looks good in the one pic I found, and few dependencies (just image formats). I compiled it, and in spite of warnings (dynamic exception specifications are deprecated), it worked great! But now I have no idea how to package it.

The GUI component failed to compile. It has a couple more dependencies, openGL and Qt5, and gives errors about QOpenGLWidget and QtConcurrent not being found. And if it doesn’t compile when following instructions directly, I have no idea how to troubleshoot. Still, I ran the command line steps and imported the result into meshlab. Even the point cloud is recognizeable, and meshlab can finish the job by adding texture.

Also, a command-line app from the same folks, called TexRecon or mvs-texturing, can finish the job. The toolchain of MVE+TexRecon is equivalent to openMVG+openMVS, except that the former is supposed to scale better for large projects. I got TexRecon to compile too; I just haven’t figured out how to use it yet - the instructions aren’t as clear as for the first component.

These projects live here (https://github.com/simonfuhrmann/mve/wiki/MVE-Users-Guide) and here (https://github.com/nmoehrle/mvs-texturing/blob/master/README.md).

GEF

Okay, figured out how to use TexRecon - I just had an error in a directory path. Output is rather impressive. With just 11 photos of a busy scene, I got a very recognizeable model of the main object and several secondary objects in the scene, and a background object rendered with holes where shadows were in the original photos. Really pretty good.

By comparison, openMVG gave me point clouds that weren’t recognizeable except for basic shapes, and that still might have been enough for openMVS to work with, but I haven’t succeeded with it yet, though as I wrote above, hopefully I’ll have time to troubleshoot it Sunday.

That said, I’m impressed with how easy MVE+TexRecon were to compile even for an utter newbie, and how well they worked afterwards. Malcolm, if you’ve an interest in the project, I’d love some help troubleshooting how to compile the graphical interface, UMVE, and even with just the command-line tools, I think this would be an excellent addition to the openSUSE repos. That’s based on one test; I could run a couple more but I’m not sure where’d be most convenient to post the object files for inspection.

GEF

On Fri 13 Jul 2018 10:56:03 AM CDT, gfagan wrote:

Okay, figured out how to use TexRecon - I just had an error in a
directory path. Output is rather impressive. With just 11 photos of a
busy scene, I got a very recognizeable model of the main object and
several secondary objects in the scene, and a background object rendered
with holes where shadows were in the original photos. Really pretty
good.

By comparison, openMVG gave me point clouds that weren’t recognizeable
except for basic shapes, and that still might have been enough for
openMVS to work with, but I haven’t succeeded with it yet, though as I
wrote above, hopefully I’ll have time to troubleshoot it Sunday.

That said, I’m impressed with how easy MVE+TexRecon were to compile even
for an utter newbie, and how well they worked afterwards. Malcolm, if
you’ve an interest in the project, I’d love some help troubleshooting
how to compile the graphical interface, UMVE, and even with just the
command-line tools, I think this would be an excellent addition to the
openSUSE repos. That’s based on one test; I could run a couple more but
I’m not sure where’d be most convenient to post the object files for
inspection.

GEF

Hi
Will look at these over the weekend for you…

Can you provide links to where you downloaded please :slight_smile:


Cheers Malcolm °¿° SUSE Knowledge Partner (Linux Counter #276890)
SLES 15 | GNOME Shell 3.26.2 | 4.12.14-23-default
If you find this post helpful and are logged into the web interface,
please show your appreciation and click on the star below… Thanks!