PyODM for use with ClusterODM

I’m trying to use ClusterODM for use with Distributed Split-Merge. Unfortunately there’s no real good documentation on this matter.
Rather than interfacing through CloudODM, can we use PyODM for Distributed Split-Merge using ClusterODM?

Something like:

import os
import sys
from pyodm import Node, exceptions
import argparse


parser = argparse.ArgumentParser(description="Input Mission JSON File")
parser.add_argument("-i", "--indir", help="Input directory", required=True)
args = parser.parse_args()
indir = args.indir


def main():
    sys.path.append('..')
    node = Node('<IP ADDRESS', 3000)
    new_list = []
    for root, dirs, files in os.walk(indir):
        for file in files:
            if file.endswith('.JPG' or '.jpg'):
                new_list.append(os.path.join(root, file))
    print(len(new_list), "images found for this process.")
    try:
        # Start a task
        print("Uploading images...")
        task = node.create_task(new_list,
                                {'split': 270, 'split-overlap': 75,
                                 'sm-cluster': 'http://<IP ADDRESS>:3000',
                                 'build-overviews': True, 'orthophoto-bigtiff': 'YES',
                                 'orthophoto-resolution': 0.5, 'rerun-all': True, 'verbose': True,
                                 'matcher-distance': 25, 'use-opensfm-dense': True, 'texturing-nadir-weight': 4,
                                 })
        print("task is", task)

        try:
            # This will block until the task is finished
            # or will raise an exception
            task.wait_for_completion()

            print("Task completed, downloading results...")

            # Retrieve results
            task.download_assets("./results")

            print("Assets saved in ./results (%s)" % os.listdir("./results"))

            # Restart task and this time compute dtm
            task.restart({'dtm': True})
            task.wait_for_completion()

            print("Task completed, downloading results...")

            task.download_assets("./results_with_dtm")

            print("Assets saved in ./results_with_dtm (%s)" % os.listdir("./results_with_dtm"))
        except exceptions.TaskFailedError as e:
            print("\n".join(task.output()))

    except exceptions.NodeConnectionError as e:
        print("Cannot connect: %s" % e)
    except exceptions.NodeResponseError as e:
        print("Error: %s" % e)


if __name__ == "__main__":
    main()

You can use distributed split-merge with either CloudODM or PyODM as clients.

The code above looks similar enough to the examples, so I’d say it would work.

Did you read https://docs.opendronemap.org/large.html ?

Also, check https://odmbook.com which has an entire chapter on splitting large datasets and setting up ClusterODM (disclaimer: I’ve wrote the book).

@pierotofy - I need some clarification on passing ODM run parameters through PyODM.

Is the below example correct? Parameters like orthophoto-bigtiff and build-overviews, don’t normally have an input option. I tried using True with orthophoto-bigtiff, but it didn’t like it. Maybe “YES”??

task = node.create_task(name=task_name, files=new_list, options=
                	    {'split': 270, 'split-overlap': 75,
                	    'build-overviews': True, 'orthophoto-bigtiff': "YES",
                	    'orthophoto-resolution': 0.5, 'rerun-all': True, 'verbose': True,
                	    'matcher-distance': 25, 'use-opensfm-dense': True, 'texturing-nadir-weight': 4,
                	    }, progress_callback=None)

The process finishes with and error message and only an odm_orthophoto.tif in the ./results folder, but nothing else. That geotiff is corrupt and won’t open in QGIS. The error message is:

Task completed, downloading results...
Assets saved in /results
Error: Action not supported. Please create a new task.