{"id":43137473,"url":"https://github.com/multiview-stitcher/multiview-stitcher","last_synced_at":"2026-01-31T22:07:52.752Z","repository":{"id":199947663,"uuid":"697999800","full_name":"multiview-stitcher/multiview-stitcher","owner":"multiview-stitcher","description":"A toolbox for registering / fusing / stitching large multi-view / multi-positioning image datasets in 2-3D.","archived":false,"fork":false,"pushed_at":"2026-01-24T21:47:55.000Z","size":12408,"stargazers_count":101,"open_issues_count":16,"forks_count":14,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-25T08:39:43.522Z","etag":null,"topics":["image-fusion","image-processing","image-registration","stitching"],"latest_commit_sha":null,"homepage":"https://multiview-stitcher.github.io/multiview-stitcher/","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/multiview-stitcher.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-09-28T23:24:53.000Z","updated_at":"2026-01-24T19:58:35.000Z","dependencies_parsed_at":"2026-01-16T15:12:46.527Z","dependency_job_id":null,"html_url":"https://github.com/multiview-stitcher/multiview-stitcher","commit_stats":null,"previous_names":["multiview-stitcher/multiview-stitcher"],"tags_count":45,"template":false,"template_full_name":null,"purl":"pkg:github/multiview-stitcher/multiview-stitcher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiview-stitcher%2Fmultiview-stitcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiview-stitcher%2Fmultiview-stitcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiview-stitcher%2Fmultiview-stitcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiview-stitcher%2Fmultiview-stitcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/multiview-stitcher","download_url":"https://codeload.github.com/multiview-stitcher/multiview-stitcher/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiview-stitcher%2Fmultiview-stitcher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28957006,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T18:30:42.805Z","status":"ssl_error","status_checked_at":"2026-01-31T18:30:19.593Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["image-fusion","image-processing","image-registration","stitching"],"created_at":"2026-01-31T22:07:49.803Z","updated_at":"2026-01-31T22:07:52.744Z","avatar_url":"https://github.com/multiview-stitcher.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![License BSD-3](https://img.shields.io/pypi/l/multiview-stitcher.svg?color=green)](https://github.com/multiview-stitcher/multiview-stitcher/raw/main/LICENSE)\n[![PyPI](https://img.shields.io/pypi/v/multiview-stitcher.svg?color=green)](https://pypi.org/project/multiview-stitcher)\n[![Python Version](https://img.shields.io/pypi/pyversions/multiview-stitcher.svg?color=green)](https://python.org)\n[![tests](https://github.com/multiview-stitcher/multiview-stitcher/actions/workflows/test_and_deploy.yml/badge.svg)](https://github.com/multiview-stitcher/multiview-stitcher/actions)\n[![DOI](https://zenodo.org/badge/697999800.svg)](https://zenodo.org/doi/10.5281/zenodo.13151252)\n\n\u003c!--\n[![License BSD-3](https://img.shields.io/pypi/l/multiview-stitcher.svg?color=green)](https://github.com/multiview-stitcher/multiview-stitcher/raw/main/LICENSE)\n[![PyPI](https://img.shields.io/pypi/v/multiview-stitcher.svg?color=green)](https://pypi.org/project/multiview-stitcher)\n[![Python Version](https://img.shields.io/pypi/pyversions/multiview-stitcher.svg?color=green)](https://python.org)\n[![tests](https://github.com/multiview-stitcher/multiview-stitcher/workflows/tests/badge.svg)](https://github.com/multiview-stitcher/multiview-stitcher/actions)\n[![codecov](https://codecov.io/gh/multiview-stitcher/multiview-stitcher/branch/main/graph/badge.svg)](https://codecov.io/gh/multiview-stitcher/multiview-stitcher)\n--\u003e\n\nDocumentation available [here](https://multiview-stitcher.github.io/multiview-stitcher). 📚\n\n**Contents:** [Intro](#multiview-stitcher) • [Quickstart](#quickstart) • [Napari plugin](#napari-plugin) • [Installation](#installation) • [Recent news](#recent-news) • [Browser usage](#stitching-in-the-browser) • [Limitations](#known-limitations) • [Roadmap](#roadmap--future-plans) • [Related tools](#related-stitching-tools) • [Contributing](#contributing) • [Citing](#citing-multiview-stitcher) • [License](#license)\n\n# multiview-stitcher\n\n![A mosaic of example applications](docs/images/applications_mosaic.png)\n\n`multiview-stitcher` is an open-source modular toolbox for distributed and tiled stitching of 2-3D image data in Python. It is a collection of algorithms to **register** and **fuse** small and large datasets from **multi-positioning** and **multi-view** light sheet microscopy, as well as **other modalities** such as correlative cryo-EM datasets. As such, it shares considerable functionality with the Fiji plugin [BigStitcher](https://imagej.net/plugins/bigstitcher/), with the difference that it is designed for interoperability with the Python scientific ecosystem. This allows it to:\n\n  - easily integrate into existing Python-based workflows (within Jupyter notebooks, scripts, etc.) 🐍\n  - scale to very large datasets using mature Python tooling (using `dask`, `zarr-python`, `ray`) 🚀\n  - make use of community-developed data representations (`xarray`, `spatial-image`, `multiscale-spatial-image`, `spatialdata`) 🤓\n  - ensure compatibility with and optimal usage of modern file formats and standards, e.g. [OME-Zarr](https://ome-ngff.readthedocs.io/en/latest/)\n  - swap in custom methods for registration and fusion that are readily available in the Python ecosystem (e.g. from `scikit-image`, `ANTs`, `elastix`, `SimpleITK`) 🔧\n  \n![alt text](docs/images/workflow_schematic.png)\n\n\n**👀 Visualization**: The associated [`napari-stitcher`](https://github.com/multiview-stitcher/napari-stitcher) provides visualization functionality using the Napari viewer, including a standalone widget for stitching vanilla napari image layers. Alternatively, web-based visualization of huge datasets  together with their associated transformations is supported using [neuroglancer](https://neuroglancer-docs.web.app/) (no additional installation required! See e.g. the exaSPIM example [notebook](https://github.com/multiview-stitcher/multiview-stitcher/blob/main/notebooks/stitching_exaspim.ipynb)).\n\n**🛠️ Extensibility**: Next to the built-in functions for pairwise registration, fusion and view weighing, custom functions with a simple API can be provided by the user. Multiview-stitcher provides these functions with chunk-sized and pre-transformed image arrays, taking care of the overall stitching workflow and large data handling.\n\n**🚀 Scalability**: The package is designed to handle very large datasets that do not fit into memory. It leverages `zarr`, `dask` and `ray` for efficient data handling and processing. For example, `multiview-stitcher` can fuse cloud-hosted exaSPIM datasets of \u003e100TB each (see [example notebook](https://github.com/multiview-stitcher/multiview-stitcher/blob/main/notebooks/stitching_exaspim.ipynb)).\n\n**🔄 Transformations**: multiview-stitcher supports both input and output tile transformations, as well as registration results to be full affine transformations. This includes simple shifts / translations, as well as rotation and scaling for advanced stitching or multi-view fusion. Non-rigid transformations are not supported at the moment.\n\n## Quickstart\n\n- [Documentation](https://multiview-stitcher.github.io/multiview-stitcher) and [code example](https://multiview-stitcher.github.io/multiview-stitcher/main/code_example/)\n- Check out the [example notebooks](https://github.com/multiview-stitcher/multiview-stitcher/tree/main/notebooks).\n\n### Code example\n\nThese code snippets walk you through a small stitching workflow consisting of\n1) Preparing the input image data and metadata (tile positions, spacing, channels)\n2) Registering the tiles\n3) Stitching / fusing the tiles\n\n#### 1) Prepare data for stitching\n\n```python\nimport numpy as np\nfrom multiview_stitcher import msi_utils\nfrom multiview_stitcher import spatial_image_utils as si_utils\n\n# input data (can be any numpy compatible array: numpy, dask, cupy, etc.)\ntile_arrays = [np.random.randint(0, 100, (2, 10, 100, 100)) for _ in range(3)]\n\n# indicate the tile offsets and spacing\ntile_translations = [\n    {\"z\": 2.5, \"y\": -10, \"x\": 30},\n    {\"z\": 2.5, \"y\": 30, \"x\": 10},\n    {\"z\": 2.5, \"y\": 30, \"x\": 50},\n]\nspacing = {\"z\": 2, \"y\": 0.5, \"x\": 0.5}\n\nchannels = [\"DAPI\", \"GFP\"]\n\n# build input for stitching\nmsims = []\nfor tile_array, tile_translation in zip(tile_arrays, tile_translations):\n    sim = si_utils.get_sim_from_array(\n        tile_array,\n        dims=[\"c\", \"z\", \"y\", \"x\"],\n        scale=spacing,\n        translation=tile_translation,\n        transform_key=\"stage_metadata\",\n        c_coords=channels,\n    )\n    msims.append(msi_utils.get_msim_from_sim(sim, scale_factors=[]))\n\n# plot the tile configuration\n# from multiview_stitcher import vis_utils\n# fig, ax = vis_utils.plot_positions(msims, transform_key='stage_metadata', use_positional_colors=False)\n```\n\n![Visualization of input tile configuration](docs/images/tile_configuration.png)\n\n#### 2) Register the tiles\n\n```python\nfrom dask.diagnostics import ProgressBar\nfrom multiview_stitcher import registration\n\nwith ProgressBar():\n    params = registration.register(\n        msims,\n        reg_channel=\"DAPI\",  # channel to use for registration\n        transform_key=\"stage_metadata\",\n        new_transform_key=\"translation_registered\",\n        pre_registration_pruning_method=None,\n        plot_summary=True,\n    )\n```\n\n![Pairwise registration summary](docs/images/pairwise_registration_summary_example.png)\n\n![Global parameter resolution summary](docs/images/global_registration_summary_example.png)\n\n\n#### 3) Stitch / fuse the tiles\n\n```python\nfrom multiview_stitcher import fusion\n\nfused_sim = fusion.fuse(\n    [msi_utils.get_sim_from_msim(msim) for msim in msims],\n    transform_key=\"translation_registered\",\n)\n\n# get fused array as a dask array\nfused_sim.data\n\n# get fused array as a numpy array\nfused_sim.data.compute()\n```\n\nFor large datasets (\u003e50GB, potentially with benefits already at \u003e5GB) consider streaming the fused result directly to a zarr file using the following way to call `fusion.fuse`:\n\n\u003cdetails\u003e\n  \u003csummary\u003eCode snippet\u003c/summary\u003e\n\n\n```python\nfrom multiview_stitcher import fusion, misc_utils\n\nfused = fusion.fuse(\n    sims=[msi_utils.get_sim_from_msim(msim) for msim in msims],\n    transform_key=\"translation_registered\",\n    # ... further optional args for fusion.fuse\n    output_zarr_url=\"fused_output.ome.zarr\",\n    zarr_options={\n        \"ome_zarr\": True,\n        # \"ngff_version\": \"0.4\",  # optional\n    },\n    # optionally, we can use ray for parallelization (`pip install \"ray[default]\"`)\n    # batch_options={\n    #     \"batch_func\": misc_utils.process_batch_using_ray,\n    #     \"n_batch\": 4,  # number of chunk fusions to schedule / submit at a time\n    #     \"batch_func_kwargs\": {\n    #         'num_cpus': 4  # number of processes for parallel processing to use with ray\n    #     },\n    # },\n)\n```\n\n\u003c/details\u003e\n\n## Napari plugin\n\nThere's an associated napari plugin: [napari-stitcher](https://github.com/multiview-stitcher/napari-stitcher).\n\n![](https://github.com/multiview-stitcher/napari-stitcher/blob/dc6b571049c971709eb41064930be9b880d806f4/misc-data/20230929_screenshot.png)\n\nImage data by [Arthur Michaut](https://research.pasteur.fr/fr/member/arthur-michaut/) @ [Jérôme Gros Lab](https://research.pasteur.fr/fr/team/dynamic-regulation-of-morphogenesis/) @ Institut Pasteur.\n\n----------------------------------\n## Installation\n\nYou can install `multiview-stitcher` via `pip` from PyPI:\n\n    pip install multiview-stitcher\n\nor from the source code in this github repository:\n\n    pip install git+https://github.com/multiview-stitcher/multiview-stitcher.git\n\n## Recent news\n\n- Oct/25 (**v0.1.37**): Support for fusing huge datasets using `fusion.fuse(..., output_zarr_url=...)`, in which the fused result is streamed to disk in batches of independently processed chunks, circumventing any dask graph induced overhead. [Tested](https://github.com/multiview-stitcher/multiview-stitcher/blob/main/notebooks/stitching_exaspim.ipynb) on \u003e100TB datasets!\n- Oct/25 (**v0.1.34**): `register(..., reg_res_level=1)` for registering directly on downsampled data\n- Aug/25 (**v0.1.30**): Multi-view fusion example [notebook](https://github.com/multiview-stitcher/multiview-stitcher/blob/main/notebooks/stitching_bigstitcher_multiview.ipynb) available.\n- May/25 (**v0.1.26**): Introduced option to specify the number of parallel pairwise registrations for improved performance / memory tradeoff.\n- Mar/25 (**v0.1.23**): Support for neuroglancer visualization of\n  - input tiles together with their input transformations\n  - registered tiles together with their registration transformations\n  - fused output together with the transformations of all input tiles\n- Mar/25 (**v0.1.21**): Obtained completely stable numerics for n-dimensional stack intersection calculation using `scipy.spatial.HalfspaceIntersection`.\n\n## Citing multiview-stitcher\n\nIf you find multiview-stitcher useful please cite this repository using the following DOI (all versions): https://doi.org/10.5281/zenodo.13151252.\n\n## Stitching in the browser\n\n`multiview-stitcher` can run without installation in your browser. Data is processed locally in the browser and not uploaded to any server.\n\n### Try it out\n\n- open [JupyterLite](https://jupyter.org/try-jupyter/lab/) in a private browser window\n- upload this notebook into the jupyter lab window: [notebooks/stitching_in_the_browser.ipynb](https://github.com/multiview-stitcher/multiview-stitcher/tree/main/notebooks/stitching_in_the_browser.ipynb)\n- upload files to stitch into a 'data' folder in the jupyter lab window\n- follow the notebook\n\nLimitations: stitching will run with a single thread and while the code runs locally, your local file system is not directly accessible from within the browser environment\n\n## Known limitations\n\n1. The current implementation focuses on rigid transformations (translation, rotation). Non-rigid transformations are not supported at the moment.\n1. In terms of data volumes, processing huge tiles is handled well. A large amount of tiles (e.g. more than hundreds) works but can be slow during registration, as the currently built-in global optimization method converges slowly for large numbers of tiles.\n1. Open an issue if you encounter any problems or have suggestions for improvements 🙋\n\n## Roadmap / Future plans\n\nSome planned improvements for future releases:\n\n1. Implement a hierarchical and parallelised global registration optimization for faster registration of datasets with large numbers of tiles (\u003e100s).\n1. Implement more built-in registration and fusion methods:\n    1. Feature-based registration\n    1. Multiview deconvolution-based fusion\n1. The built-in option to subdivide tiles / views for working with piecewise affine transformations that account for local distortions observed in e.g. large FOV light sheet data.\n1. Make multiview-stitcher available via conda-forge.\n1. Open an issue if you have suggestions for improvements 🙋\n\n\n## Related stitching tools\n\n`multiview-stitcher` sits in a broader ecosystem of excellent open-source stitching software.  \nRather than aiming to replace existing tools, it focuses on providing a **Python-native, modular API**\nthat integrates well with the scientific Python ecosystem (dask/zarr/xarray, napari, etc.).\n\nThe table below is a **high-level orientation** (features and workflows often overlap, and most tools can be combined in practice):\n\n| Tool | Ecosystem | Typical use case / focus | 2D | 3D | Transform model (typical) | Out-of-core / huge data* | Automation |\n| --- | --- | --- | :--: | :--: | --- | :--: | --- |\n| BigStitcher | Fiji | GUI-driven multi-view + tiled microscopy workflows | ✅ | ✅ | rigid + affine | ✅ | ImageJ macros / batch |\n| Ashlar | Python | multiplexed whole-slide 2D mosaics | ✅ | — | translation/rigid mosaics | limited* | CLI + Python |\n| TeraStitcher | C++ | very large tiled 3D volumes | ✅ | ✅ | translation/rigid | ✅ | CLI |\n| multiview-stitcher | Python | modular registration + fusion integrated into Python workflows | ✅ | ✅ | rigid + affine | ✅ | Jupyter notebooks / Python API + napari / neuroglancer |\n\n\\* “Out-of-core / huge data” depends heavily on workflow, file formats, and output options. Several tools here can handle very large datasets; in practice, Python can make it particularly convenient to compose and distribute stitching workflows across compute resources.\n\n### Rule of thumb\n\n- If you want a mature **GUI-first** workflow with broad microscopy stitching functionality: **BigStitcher**\n- If you stitch **whole-slide multiplexed** 2D mosaics and want a **simple CLI**: **Ashlar**\n- If you stitch **very large 3D tiled volumes** with a dedicated toolchain: **TeraStitcher**\n- If you want stitching and fusion as a **Python building block** that plugs into existing analysis pipelines: **multiview-stitcher**\n\nIf you spot inaccuracies or want to extend the comparison, please open an issue or PR 🙂\n\n## Work in progress\n\n`multiview-stitcher` is being actively developed in the open and the API is subject to change.\n\n## Previous work\n\n`multiview-stitcher` improves and replaces [MVRegFUS](https://github.com/m-albert/MVRegFus).\n\n## Issues\n\nIf you encounter any problems, please [file an issue](https://github.com/multiview-stitcher/multiview-stitcher/issues) along with a description of the problem. Interacting with the community and developers via issues is highly appreciated and encouraged 🙌\n\n## Contributing\n\nContributions are very welcome 🙌\n\nIf you're looking for ideas, feel free to have a look at the open issues (e.g. those labeled with \"help wanted\" or \"good first issue\").\n\n## License\n\nDistributed under the terms of the BSD-3 license,\n\"multiview-stitcher\" is free and open source software.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmultiview-stitcher%2Fmultiview-stitcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmultiview-stitcher%2Fmultiview-stitcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmultiview-stitcher%2Fmultiview-stitcher/lists"}