{"name":"napari-vipp","display_name":"napari-vipp","visibility":"public","icon":null,"categories":[],"schema_version":"0.2.1","on_activate":null,"on_deactivate":null,"contributions":{"commands":[{"id":"napari-vipp.make_widget","title":"VIPP Workflow","python_name":"napari_vipp._widget:VippWidget","short_title":null,"category":null,"icon":null,"enablement":null},{"id":"napari-vipp.sample_data","title":"VIPP synthetic microscopy samples","python_name":"napari_vipp._sample_data:make_sample_data","short_title":null,"category":null,"icon":null,"enablement":null}],"readers":null,"writers":null,"widgets":[{"command":"napari-vipp.make_widget","display_name":"VIPP Workflow","autogenerate":false}],"sample_data":[{"command":"napari-vipp.sample_data","key":"vipp_synthetic_volume","display_name":"VIPP synthetic microscopy samples"}],"themes":null,"menus":{},"submenus":null,"keybindings":null,"configuration":[]},"package_metadata":{"metadata_version":"2.4","name":"napari-vipp","version":"0.8.2a2","dynamic":["license-file"],"platform":null,"supported_platform":null,"summary":"Visual image processing pipelines for napari","description":"# napari-vipp\n\n## Alpha Disclaimer\n\nnapari-vipp is an early alpha build in active development.\n\n- Expect breaking changes between releases.\n- Workflows, node parameters, and file compatibility may change.\n- Validate outputs before scientific interpretation or publication use.\n\n`napari-vipp` is an early prototype of a napari-native Visual Image Processing\nPipeline (VIPP): an interactive node-graph workflow composer for bioimage\nanalysis.\n\nThe project is exploring a workflow where the graph is the main work surface:\nusers add processing nodes, connect outputs to inputs, tune parameters, inspect\nstage outputs in napari, and compare mask overlays or processing branches while\nthe pipeline updates live.\n\nThis is research/prototype software. The current code is useful for exploring\ninteraction patterns and metadata-aware pipeline execution, but it is not yet a\nreleased production analysis package.\n\n## Acknowledgement\n\nIf VIPP contributes to your work, please acknowledge the project by name\n(\"napari-vipp\") and include a link to the repository:\nhttps://github.com/rensutheart/napari-vipp\n\nCitation metadata is available in `CITATION.cff`. A DOI or manuscript citation\ncan be added once one is available.\n\n## License\n\nnapari-vipp is source-available under the PolyForm Shield License 1.0.0. The\npublic license permits many uses, including commercial internal use, but it does\nnot permit providing a product or service that competes with napari-vipp or with\nproducts provided by the licensor using napari-vipp.\n\nCommercial redistribution, white-labeling, hosted product offerings, or bundling\nnapari-vipp as a substantial commercial product feature require prior written\npermission. See `COMMERCIAL-LICENSE.md` for guidance.\n\nVersions published through `0.8.2a1` were released under the BSD 3-Clause\nLicense. Later releases use the license declared in their corresponding source\nand distribution metadata.\n\n## Current Status\n\nThe prototype currently supports:\n\n- a napari `npe2` plugin manifest and dock widget;\n- a large pan/zoom Qt graph canvas;\n- toolbar graph zoom controls with a `100%` reset plus Ctrl/trackpad wheel zoom;\n- draggable node cards with input/output ports and curved connectors;\n- adding nodes from a categorized, fuzzy-searchable node library;\n- connecting nodes by dragging or click-to-connect from output to input ports;\n- explicit image source nodes for napari layers, files, or bundled samples;\n- quick selected-output saving plus graph-level save nodes;\n- per-node thumbnails with global show/hide, `Slice`/`MIP` preview modes,\n  contrast modes (`Percentile`, `Min-max`, `Raw`), and monochrome colormaps;\n- optional per-node thumbnail disabling for heavier workflows;\n- selected-node parameter controls in the inspector;\n- slider plus numeric entry controls with soft range expansion where useful;\n- right-panel output histograms plus cutoff-node input histograms with\n  slice/stack and linear/log modes;\n- compact node metadata plus detailed selected-node metadata;\n- normalized axes, channel, acquisition, source, and provenance metadata;\n- OME-TIFF, ImageJ TIFF, conventional TIFF, OME-Zarr 0.4/0.5, and common\n  raster image import plus 2D raster export;\n- adaptive image/series selection for multi-image sources;\n- table outputs for object, intensity, skeleton, merged, and annotated results;\n- image/mask/label pinning as persistent napari preview layers;\n- generated inspect layers for full-resolution napari review.\n\n## Image Metadata\n\nThe graph carries an explicit image state object alongside each node output.\nThat state records:\n\n- shape and dtype;\n- axis names and axis types, such as `t`, `c`, `z`, `y`, `x`;\n- units, scale, and origin/translation where available;\n- value range, bit depth, memory estimate, and binary-value hints;\n- source layer and operation history.\n- channel names, fluorophore/wavelength fields where available;\n- acquisition and stable source identity records.\n\nWhen a napari layer provides OME-NGFF-style `multiscales` metadata, VIPP reads\nthe axis definitions and coordinate transforms. When the source is a plain array\nwithout reliable metadata, VIPP falls back to inferred axes and labels that\nfallback explicitly.\n\nOME-TIFF metadata and local OME-Zarr 0.4/0.5 images are supported through the\nshared headless I/O layer. OME-Zarr label groups, HCS plate browsing, generated\npyramids, remote stores, and full operation-level lazy execution remain future\nwork. See `docs/io-user-guide.md` for the current format contract.\n\n## Sample Data\n\nThe plugin contributes synthetic fluorescence-like sample data:\n\n- `VIPP synthetic volume`: grayscale `ZYX` stack;\n- `VIPP synthetic multichannel volume`: `CZYX` volume with three probe-like\n  channels;\n- `VIPP synthetic time-lapse multichannel`: `TCZYX` time-lapse, multichannel\n  stack.\n\nThe multichannel samples use separate intensity channels, not baked RGB images.\nGraph thumbnails render these as fluorescence-style pseudo-color composites\nwhile preserving the underlying channel axis in the carried metadata.\nWhen the full sample suite is open, the workflow automatically starts from the\n`VIPP synthetic time-lapse multichannel` layer so the input metadata should read\nas `TCZYX`. The simpler grayscale and `CZYX` examples are still available in the\ntoolbar input selector and in the graph-level `Image Source` node.\n\nOpen sample data from napari:\n\n```text\nFile > Open Sample > VIPP synthetic microscopy samples\n```\n\n## Documentation\n\n- End-user workflow usage: `docs/user-guide.md`\n- Operator tips and performance tuning: `docs/operator-tips.md`\n- Developer and architecture notes: `docs/developer-notes.md`\n\n## Node Library\n\nThe current node catalogue includes:\n\n- Image Data:\n  - Source & Output:\n    - Image Source\n    - Save Image\n  - Axes & Regions:\n    - Crop Stack\n    - Select Axis Slice\n    - Reorder Axes\n    - Set Pixel Size / Units\n    - Rescale Axes\n  - Channels & Composites:\n    - Extract Channel\n    - Combine Channels\n    - Split Channels\n    - Composite → RGB\n  - Utilities:\n    - Convert Dtype\n  - Math & Logic:\n    - Calculate New Image\n    - Add\n    - Subtract\n    - Ratio\n    - Mask Image\n    - Logical AND\n    - Logical OR\n    - Logical XOR\n    - Invert\n- Intensity & Contrast:\n  - Linear Scale + Offset\n  - Gamma Correction\n  - Rescale Intensity\n  - Normalize\n  - Clip\n- Filtering:\n  - Smoothing & Denoising:\n    - Average Blur\n    - Gaussian Blur\n    - Gaussian Blur 3D\n    - Median Filter\n    - Bilateral Filtering\n    - Non-Local Means\n  - Edge & Detail:\n    - Difference of Gaussians\n    - Unsharp Mask\n    - Sobel Edges\n    - Canny Edges\n    - Laplace Filter\n- Projection:\n  - Maximum Projection\n  - Project Image (axis-aware dropdown plus multiple projection methods)\n  - Orthogonal Projection\n- Segmentation:\n  - Global Thresholds:\n    - Otsu Threshold\n    - Triangle Threshold\n    - Li Threshold\n    - Yen Threshold\n    - Isodata Threshold\n    - Minimum Threshold\n    - Binary Threshold\n    - Hysteresis Threshold\n  - Local Thresholds:\n    - Adaptive Mean Threshold\n    - Adaptive Gaussian Threshold\n    - Sauvola Threshold\n    - Niblack Threshold\n- Morphology:\n  - Dilation\n  - Erosion\n  - Opening\n  - Closing\n  - Top Hat\n  - Black Hat\n  - Morphological Gradient\n  - Fill Holes\n  - Remove Small Objects\n  - Skeletonize\n- Label Operations:\n  - Label Connected Components\n  - Filter Labels By Volume\n  - Filter Labels By Property\n  - Clear Border Objects\n  - Relabel Sequential\n- Measurements:\n  - Measure Objects\n  - Measure Objects + Intensity\n  - Analyze Skeleton\n  - Merge Tables\n  - Select Table Columns\n  - Add Metadata Columns\n\nHistogram-based automatic threshold nodes show `Threshold uses` on stack inputs.\n`Stack histogram` computes one cutoff from the whole grayscale input and applies\nit to the full image; `Slice histogram` computes a separate cutoff per displayed\nplane while still producing a full-stack mask. The control is hidden for 2D\ninputs. These nodes also show the input histogram used for threshold selection\nwith a live marker at the chosen threshold.\n\nThe label pipeline converts binary masks into integer object IDs. Connected\ncomponents can run over full `ZYX` volumes or independently over `YX` images.\nVolume filtering currently uses pixel/voxel counts, preserves retained IDs, and\nleaves compact renumbering to the explicit `Relabel Sequential` node. Its\nvolume sliders use the largest observed object as their data-aware upper bound\nand a logarithmic scale for useful control across small and large structures;\nthe numeric fields still accept exact values up to one billion. Selecting\n`Filter Labels By Volume` also shows the incoming object-volume distribution\nabove the regular histogram. Dashed minimum and enabled maximum markers update\nwith the filter controls. Its `Log volume axis` toggle is enabled by\ndefault and can be switched off for a linear distribution.\n\n`Filter Labels By Property` accepts named `Labels` and `Measurements table`\ninputs and keeps or removes labels using any numeric table column, including\narea/volume, intensity, and skeleton/network measurements. It preserves label\nIDs and leaves compact renumbering to `Relabel Sequential`.\n\n`Clear Border Objects` accepts either a binary mask or integer labels and\npreserves that semantic type. In 3D it can remove objects touching all `ZYX`\nvolume boundaries or only the lateral `YX` boundaries, with an optional border\nbuffer. Timepoints and channels are processed independently.\n\n`Fill Holes` accepts binary masks and defaults to metadata-aware processing:\n2D images are filled in `YX`, while true z-stacks are filled as complete `ZYX`\nvolumes. An advanced 2D-per-slice mode remains available for deliberately\nslice-wise segmentations. A maximum size of `0` fills every enclosed hole;\npositive values fill only holes up to the selected pixel area or voxel volume.\nThe inspector hides 3D for true 2D inputs and warns when slice-wise filling is\nselected for a z-stack.\n\n`Remove Small Objects` accepts binary masks or integer labels and preserves the\nconnected semantic type. It removes objects below a minimum pixel area or voxel\nvolume, supports 2D or 3D processing, and exposes connectivity for mask inputs.\nIts logarithmic size control is bounded by the largest observed input object.\nFor labels-only cleanup with both minimum and maximum cutoffs, use\n`Filter Labels By Volume`.\n\n`Measure Objects` accepts a label image and produces a table output instead of\nan image. The default measurement set includes label ID, pixel/voxel area or\nvolume, calibrated physical area or volume when spatial scale metadata is\navailable, centroid, bounding box, equivalent diameter, extent, and Euler\nnumber. Optional checkboxes add shape descriptors, axis/inertia descriptors,\nand 2D boundary descriptors. The 2D boundary group is hidden for true 3D\ninputs because perimeter, Crofton perimeter, orientation, and eccentricity are\n2D concepts in the current implementation. Table outputs show a row preview in\nthe inspector and can be saved as CSV or TSV.\n\n`Measure Objects + Intensity` is the first named multi-input measurement node.\nIt has separate `Labels` and `Intensity image` input ports, then outputs the\nbasic object morphology columns plus per-label mean, minimum, maximum, sum, and\nstandard deviation intensity. It exposes the same optional morphology groups as\n`Measure Objects`. The example workflow\n`examples/red-channel-object-intensity-measurements.json` demonstrates this\npattern.\n\n`Merge Tables` joins two or more table outputs into a single table. In `auto`\nmode it joins on stable identity columns such as `t_index` and `label_id`; when\nno identity columns are shared, equal-length tables can be joined by row\nposition. `Select Table Columns` keeps, drops, or reorders table columns while\npreserving row order and column units. `Add Metadata Columns` appends constant\ntreatment, replicate, batch, or condition columns before CSV/TSV export. The\nexample workflow\n`examples/red-channel-merged-measurement-table.json` demonstrates a\nPCA-oriented table assembly path.\n\n`Skeletonize` accepts a binary mask and produces a skeleton mask using\nmetadata-aware 2D or 3D processing. `Analyze Skeleton` accepts a skeleton mask\nand outputs a per-component table with skeleton voxel count, endpoint voxels,\njunction voxels, isolated nodes, branch/graph edge counts, voxel-graph edge\ncount, cycle count, per-block component count, component voxel fraction, and\nskeleton length in pixel/voxel and physical units when scale metadata is\navailable. These nodes are generic and are intended for mitochondria, neurites,\nvessels, fibers, hyphae, and other curvilinear structures.\n\n`Extract Channel` pulls one selected channel from a multichannel image.\n`Split Channels` is its bulk counterpart: it emits one output port per channel\nin the image (losslessly, preserving dtype), with the port count following the\ntrue channel count. Each channel also preserves the semantic type of its input,\nso splitting a threshold mask produces mask ports that connect directly to\n`Label Connected Components`. `Combine Channels` is the inverse multi-input\nnode: set the expected channel/input count, connect that many upstream images,\nand it stacks them into an explicit multichannel output. Channel pseudo-colours\nare carried as metadata from OME sources, Image Source overrides, Combine\nChannels, or the `Assign Channel Colors` pass-through node. `Composite → RGB`\nmaps a multichannel composite to a channel-last RGB image. Auto mode preserves\ntrue RGB/RGBA inputs, and otherwise blends all channels by their carried\npseudo-colours, so yellow contributes to red and green and cyan contributes to\ngreen and blue. Manual red/green/blue selectors remain available for forced\nsingle-channel plane mapping. `Calculate New Image` is a multi-input image-math\nnode that applies comma separated weights to connected inputs and then adds an\noffset.\n\n`Mask Image` is a typed two-input node with separate `Image` and `Mask` ports.\nThe mask port accepts binary masks or labels, treating nonzero values as inside\nthe mask. Spatial masks can be broadcast over compatible image axes, including\nchannel-last RGB/RGBA images and common channel-first multichannel arrays, so a\n`YX` or `ZYX` mask can mask all colour/channel planes without first splitting\nthe image.\n\n`Image Source` can point to an existing napari layer, a local `.npy`, TIFF,\nOME-Zarr, or common raster source such as PNG/JPEG/BMP/GIF/WebP, or one of the\nbundled synthetic samples. `Set Pixel Size / Units` repairs missing or incorrect\ninput calibration by setting X/Y pixel size, optional Z step size, and the\nshared physical unit carried in downstream metadata. Scale-aware nodes such as\n`Orthogonal Projection` use this metadata to preserve physical proportions for\nanisotropic z-stacks. `Rescale Axes` changes the sampled pixel grid along X/Y/Z\nwith optional X/Y aspect-ratio locking, nearest-neighbor through spline\ninterpolation choices, and anti-aliasing for intensity-image downsampling; it\nupdates physical scale metadata inversely to the requested scale factors.\n`Save Image` passes data through unchanged and, when `Auto-save on update` is\nset to `on`, writes the node input to disk every time the graph recomputes. For\nquick interactive work, the\ninspector also provides `Save selected output...` for the currently selected\nnode; that dialog defaults to TIFF but also allows `.npy` and PNG/JPEG-style\nformats when the selected output is 2D. TIFF output is written in ImageJ\nhyperstack format when axis metadata is available, and binary masks are saved\nas 8-bit `0`/`255` values.\n\n## Development\n\nCreate a local environment and install in editable mode:\n\n```bash\npython -m venv .venv\n.venv\\Scripts\\activate\npython -m pip install -e \".[dev]\"\n```\n\nValidate and test:\n\n```bash\npython -m npe2 validate src/napari_vipp/napari.yaml\npython -m ruff check .\npython -m pytest\n```\n\nLaunch napari manually and open the widget from:\n\n```text\nPlugins > VIPP Workflow (napari-vipp)\n```\n\nOr launch the local sample app:\n\n```bash\npython scripts\\launch_vipp_sample.py\n```\n\nTo start directly from the multichannel Otsu-to-label workflow:\n\n```bash\npython scripts\\launch_vipp_label_workflow.py\n```\n\nThe same graph can be loaded manually from\n`examples/otsu-red-channel-labels.json`. A second review workflow,\n`examples/red-channel-object-intensity-measurements.json`, demonstrates the\nnamed `Labels` plus `Intensity image` input slots on `Measure Objects +\nIntensity`.\n\n## Roadmap\n\nNear-term development priorities:\n\n- axis-aware channel selectors that show probe names instead of only numbers;\n- grouped table summaries by condition/time/source;\n- skeleton QC feature masks, branch labels, and short-branch pruning;\n- distance transforms, marker generation, and marker-controlled watershed;\n- richer 3D mesh morphology and calibrated physical variants for extended\n  length/shape measurements;\n- fluorescence background correction;\n- OME-Zarr pyramids, label colors/properties, and preview-resolution selection;\n- plate/well/field browsing, remote reads, batch execution, and memory-aware\n  lazy execution;\n- richer non-image outputs, including points and scalar summaries;\n- batch execution over files, positions, channels, z-slices, and timepoints.\n\nSee `docs/user-guide.md` for end-user operation guidance,\n`docs/operator-tips.md` for operator-focused tuning,\n`docs/developer-notes.md` and `docs/architecture.md` for technical internals,\n`docs/planning.md` for broader planning, `docs/io-user-guide.md` for current\nI/O behavior, `docs/ome-io-plan.md` for the accepted OME architecture, and\n`docs/research-and-publication.md` for the evidence and publication record.\n","description_content_type":"text/markdown","keywords":"bioimage analysis,fluorescence microscopy,image processing,napari,node graph,visual programming","home_page":null,"download_url":null,"author":"Rensu P. Theart","author_email":null,"maintainer":null,"maintainer_email":null,"license":null,"classifier":["Development Status :: 3 - Alpha","Framework :: napari","Intended Audience :: Science/Research","Programming Language :: Python :: 3","Programming Language :: Python :: 3 :: Only","Topic :: Scientific/Engineering :: Bio-Informatics","Topic :: Scientific/Engineering :: Image Processing","Topic :: Scientific/Engineering :: Visualization"],"requires_dist":["dask[array]>=2025.2","fsspec>=2024.2","imageio>=2.31","numpy>=1.24","ome-types>=0.6","ome-zarr>=0.17","pillow>=10","qtpy>=2.4","scikit-image>=0.21","scipy>=1.10","tifffile>=2023.8","zarr>=3.0","build>=1.2; extra == \"dev\"","napari[pyqt6]>=0.6; extra == \"dev\"","npe2>=0.8; extra == \"dev\"","pytest>=8; extra == \"dev\"","pytest-qt>=4.4; extra == \"dev\"","ruff>=0.12; extra == \"dev\""],"requires_python":">=3.10","requires_external":null,"project_url":["Homepage, https://github.com/rensutheart/napari-vipp","Repository, https://github.com/rensutheart/napari-vipp","Issues, https://github.com/rensutheart/napari-vipp/issues"],"provides_extra":["dev"],"provides_dist":null,"obsoletes_dist":null},"npe1_shim":false}