Optmizing segmentation process

Configuration setup

My system: *Windows11, *
Version of the OTB: 8.1.9

If relevant, you may also provide:
QGIS version: 3.28.11
Python version: 3.11.6

Description of my issue

*I am performing image segmentation using the mean-shift algorithm within OTB. I have been trying to overcome the issue of undersegmentation experimenting with different sets of parameters for spatial radius and range radius. I generated a possible combination of range radius and spatial radius. I saved them as a JSON and I have been running them as a batch script. Oftentimes I saw that my computer struggled to open the script with nearly 5,000 parameter values, so I am only using a small part of the segmentation parameters. So I have the following questions, are there other optimal approaches of testing OTB parameters other than my current approach -reading a JSON as a batch script? Secondary to this, aren’t there any developments to supervise the segmentation process?

import json


# base parameters

base_parameters = {

    "in": "'C:/Users/pkalonde/Documents/GISfolder/projects/test_plastics/Demostration.tif'",

    "filter": "'meanshift'",

    "filter.meanshift.thres": "0.1",

    "filter.meanshift.maxiter": "100",

    "filter.meanshift.minsize": "100",

    "filter.cc.expr": "''",

    "filter.watershed.threshold": "0.01",

    "filter.watershed.level": "0.1",

    "filter.mprofiles.size": "5",

    "filter.mprofiles.start": "1",

    "filter.mprofiles.step": "1",

    "filter.mprofiles.sigma": "1",

    "mode": "'vector'",

    "mode.vector.outmode": "'ulco'",

    "mode.vector.inmask": "None",

    "mode.vector.neighbor": "False",

    "mode.vector.stitch": "True",

    "mode.vector.minsize": "1",

    "mode.vector.simplify": "0.1",

    "mode.vector.layername": "''",

    "mode.vector.fieldname": "''",

    "mode.vector.tilesize": "1024",

    "mode.vector.startlabel": "1",

    "mode.vector.ogroptions": "''",

    "outputpixeltype": "5"



# Generate combinations

combinations = []


for spatial_radius in range(20, 51, 10): 

    for range_radius in range(20, 51, 10): 

        parameters = base_parameters.copy()

        parameters["filter.meanshift.spatialr"] = str(spatial_radius)

        parameters["filter.meanshift.ranger"] = str(range_radius)


        output = {

            "PARAMETERS": parameters,

            "OUTPUTS": {

                "mode.vector.out": f"C:/Users/pkalonde/Documents/GISfolder/projects/test_plastics/test/good/sr{spatial_radius}rr{range_radius}.shp",

                "mode.raster.out": f"C:/Users/pkalonde/Documents/GISfolder/projects/test_plastics/test/good/sr{spatial_radius}rr{range_radius}.tif"





# Convert to JSON

json_script = json.dumps(combinations, indent=4)


# Print or save the json_script as needed



To start you can call the OTB applications directly from Python, you can install it with the following commands (valid for Ubuntu Linux):

#!/usr/bin/env sh

# create an empty conda environment: otb-env
conda create --name otb-env

# enable it
conda activate otb-env

# install recent python 3.9
conda install python=3.9

# install mamba
conda install mamba

# install otb
mamba install otb -c iota2

# disable environment and reload it
conda deactivate

modified from How to get iota2? — iota2 documentation

I understand this works on Windows Subsystem For Linux (WSL2)

And to reduce the memory impact for all possible parameter combinations, you can use a python generator with minimal memory consumption:

#!/usr/bin/env python3

# create dummy params
param_1 = ['a', 'b', 'c']
param_2 = ['z', 'y', 'x']

# iterate memory efficient :

def combine_params(param_1, param_2):
    Create all possible combinations
    between 2 parameters

    for i in param_1:
        for j in param_2:
            yield (i,j)

# test the param combination
for i in combine_params(param_1, param_2):

I hope it is useful:

Here you can see examples on how to use the OTB API