{
  "schemaVersion": 4,
  "key": "CELLPOSE_SAM",
  "meta": {
    "name": "Cellpose-SAM",
    "shortDescription": "Cell segmentation with Cellpose-SAM, set up to match the Cellpose Python package",
    "description": "Segments cells with a Cellpose-SAM model (select the exported .pt file in the module's \"Model\" parameter; the model must be exported with --channels 3, see docs/convert_cellpose.py). The steps reproduce what the Cellpose Python package does: the image is stretched so the 1st percentile becomes 0 and the 99th becomes 1 (Enhance Contrast, saturated pixels 2 % = 1 % per side; computed per analysis tile, Cellpose uses the whole image), the gray image goes into all three model channels, objects are built from the flows like Cellpose (seed-based masks), holes inside each object are filled (Fill Object Holes), and objects whose shape does not match the predicted flows are removed (flow threshold 0.4). For RGB images, add a Color Filter step first to get a gray image. The Cellpose web demo additionally shrinks images to 1000 px (set 'max resize' to 1000) and uses 250 iterations. The last step removes very large objects (Cellpose removes objects above 40 % of the image) - set \"Max area\" for your images. The class the objects get is the module's \"Cells\" parameter.",
    "authors": [
      {
        "fullName": "Joachim Danmayr",
        "organization": "University of Salzburg"
      }
    ],
    "creationTime": "2026-10-03T00:00:00Z",
    "version": 1,
    "category": "",
    "tags": [],
    "appVersion": "0.1.0"
  },
  "classes": [],
  "steps": [
    {
      "id": 1,
      "enabled": true,
      "command": {
        "type": "ENHANCE_CONTRAST",
        "saturatedPixels": 2.0,
        "normalize": false,
        "equalizeHistogram": false
      }
    },
    {
      "id": 2,
      "enabled": true,
      "command": {
        "type": "CELLPOSE",
        "modelPath": "",
        "segmentationClass": 1,
        "inputChannels": 3,
        "probabilityThreshold": 0.4,
        "flowIterations": 250,
        "minObjectSize": 15,
        "maxResize": 1000,
        "flowThreshold": 0.4,
        "cellposePostprocessing": true,
        "replicateGrayChannel": true
      }
    },
    {
      "id": 3,
      "enabled": true,
      "command": {
        "type": "FILL_OBJECT_HOLES"
      }
    },
    {
      "id": 4,
      "enabled": true,
      "command": {
        "type": "EXTRACT_OBJECTS",
        "maxObjectsBeforeFail": 100000,
        "classMapping": [
          {
            "segmentationClass": 1,
            "objectClass": {
              "GLOBAL": 1
            }
          }
        ]
      }
    },
    {
      "id": 5,
      "enabled": true,
      "command": {
        "type": "CLASSIFY_OBJECTS",
        "originSegmentation": [],
        "inputClasses": [
          {
            "GLOBAL": 1
          }
        ],
        "matchHandling": "REMOVE_ALL_CLASSES_IF_NOT_MATCH",
        "outputClass": "UNSET",
        "overlappingWith": "UNSET",
        "minIntersectionArea": 0.0,
        "sizeUnit": "PIXELS",
        "minArea": 0.0,
        "maxArea": 1000000.0,
        "minCircularity": 0.0,
        "maxCircularity": 1.0,
        "minSolidity": 0.0,
        "maxSolidity": 1.0,
        "minAspectRatio": 0.0,
        "maxAspectRatio": 2147483600.0,
        "minEccentricity": 0.0,
        "maxEccentricity": 1.0,
        "minFeret": 0.0,
        "maxFeret": 2147483600.0,
        "allowEdgeTouching": true,
        "intensityFilters": []
      }
    }
  ],
  "parameters": [
    {
      "key": "cells",
      "label": "Cells",
      "description": "",
      "section": "Classes",
      "default": "1",
      "bindings": [
        {
          "step": 4,
          "param": "class_mapping.0.object_class"
        },
        {
          "step": 5,
          "param": "input_classes"
        }
      ]
    },
    {
      "key": "model",
      "label": "Model",
      "description": "",
      "section": "Detection",
      "default": "",
      "bindings": [
        {
          "step": 2,
          "param": "model_path"
        }
      ]
    },
    {
      "key": "probability_threshold",
      "label": "Probability threshold",
      "description": "",
      "section": "Detection",
      "default": 0.4,
      "bindings": [
        {
          "step": 2,
          "param": "probability_threshold"
        }
      ]
    },
    {
      "key": "flow_threshold",
      "label": "Flow threshold",
      "description": "",
      "section": "Detection",
      "default": 0.4,
      "bindings": [
        {
          "step": 2,
          "param": "flow_threshold"
        }
      ]
    },
    {
      "key": "min_object_size",
      "label": "Min object size",
      "description": "",
      "section": "Detection",
      "default": 15,
      "bindings": [
        {
          "step": 2,
          "param": "min_object_size"
        }
      ]
    },
    {
      "key": "max_resize",
      "label": "Max resize",
      "description": "",
      "section": "Detection",
      "default": 1000,
      "bindings": [
        {
          "step": 2,
          "param": "max_resize"
        }
      ]
    },
    {
      "key": "min_area",
      "label": "Min area",
      "description": "",
      "section": "Filter",
      "default": 0,
      "bindings": [
        {
          "step": 5,
          "param": "min_area"
        }
      ]
    },
    {
      "key": "max_area",
      "label": "Max area",
      "description": "",
      "section": "Filter",
      "default": 1000000,
      "bindings": [
        {
          "step": 5,
          "param": "max_area"
        }
      ]
    },
    {
      "key": "size_unit",
      "label": "Size unit",
      "description": "",
      "section": "Filter",
      "default": "px",
      "bindings": [
        {
          "step": 5,
          "param": "size_unit"
        }
      ]
    }
  ],
  "uses": []
}
