Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image segmenter of overlayed images and functions for segmenting interactively #266

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,7 @@ _version.py

# mpl testing
result_images/


# Pycharm paths
.idea/
16 changes: 8 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@ ci:
autoupdate_schedule: "quarterly"
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
rev: v4.4.0
hooks:
- id: check-docstring-first
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/psf/black
rev: 22.8.0
rev: 23.1.0
hooks:
- id: black

- repo: https://github.com/pycqa/isort
rev: 5.10.1
rev: 5.12.0
hooks:
- id: isort

- repo: https://github.com/nbQA-dev/nbQA
rev: 1.5.2
rev: 1.6.3
hooks:
- id: nbqa-black
- id: nbqa-isort
Expand All @@ -30,18 +30,18 @@ repos:
- id: nbstripout

- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.0.0-alpha.0
rev: v3.0.0-alpha.6
hooks:
- id: prettier

- repo: https://github.com/PyCQA/flake8
rev: 5.0.4
rev: 6.0.0
hooks:
- id: flake8
additional_dependencies: [flake8-typing-imports==1.7.0]
additional_dependencies: [flake8-typing-imports==1.12.0]

- repo: https://github.com/PyCQA/autoflake
rev: v1.6.1
rev: v2.0.1
hooks:
- id: autoflake
args:
Expand Down
2 changes: 1 addition & 1 deletion docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pre-commit install
The `conda env create` command installs all Python packages that are useful when working on the source code of `mpl_interactions` and its documentation. You can also install these packages separately:

```bash
pip install -e .[dev]
pip install -e ".[dev]"
```

The {command}`-e .` flag installs the `mpl_interactions` folder in ["editable" mode](https://pip.pypa.io/en/stable/cli/pip_install/#editable-installs) and {command}`[dev]` installs the [optional dependencies](https://setuptools.readthedocs.io/en/latest/userguide/dependency_management.html#optional-dependencies) you need for developing `mpl_interacions`.
Expand Down
1 change: 1 addition & 0 deletions docs/examples/custom-callbacks.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
"\n",
"# attach a custom callback\n",
"\n",
"\n",
"# if running from a script you can just delete the widgets.Output and associated code\n",
"def my_callback(tau, beta):\n",
" if tau < 7.5:\n",
Expand Down
2 changes: 0 additions & 2 deletions docs/examples/devlop/devlop-controller.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,6 @@
" )\n",
"\n",
" def update(params, indices):\n",
"\n",
" # update plot\n",
" for i, f in enumerate(funcs):\n",
" if x is not None and not indexed_x:\n",
Expand Down Expand Up @@ -379,7 +378,6 @@
"\n",
" lines = []\n",
" for i, f in enumerate(funcs):\n",
"\n",
" if x is not None and not indexed_x:\n",
" lines.append(ax.plot(x, f(x, **params), **plot_kwargs[i])[0])\n",
" elif indexed_x:\n",
Expand Down
201 changes: 201 additions & 0 deletions docs/examples/image-segmentation-multiple-images.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Image Segmentation of overlayed images and multi-dimensional images"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%matplotlib widget\n",
"\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"%load_ext autoreload\n",
"%autoreload 2\n",
"import mpl_interactions as mpl"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# load a primary sample image\n",
"import urllib\n",
"\n",
"import PIL\n",
"\n",
"url = \"https://github.com/matplotlib/matplotlib/raw/v3.3.0/lib/matplotlib/mpl-data/sample_data/ada.png\"\n",
"\n",
"\n",
"image = np.sum(np.array(PIL.Image.open(urllib.request.urlopen(url))), axis=2) / 255\n",
"# simulating multiple slices along the 2 dimension\n",
"image_stack = np.array([image] * 3).transpose((1, 2, 0))\n",
"\n",
"# secondary image\n",
"url_2 = \"https://github.com/matplotlib/matplotlib/raw/v3.3.0/lib/matplotlib/mpl-data/sample_data/Minduka_Present_Blue_Pack.png\"\n",
"secondary_image = np.sum(np.array(PIL.Image.open(urllib.request.urlopen(url_2))), axis=2) / 255\n",
"# padding secondard to be same size as primary for illustration\n",
"secondary_image_padded = np.pad(\n",
" secondary_image,\n",
" [\n",
" (170, 505),\n",
" (150, 234),\n",
" ],\n",
" mode=\"constant\",\n",
" constant_values=(0, 0),\n",
")\n",
"# simulating multiple slices along the 2 dimension\n",
"secondary_image_stack = np.array([secondary_image_padded] * 3).transpose(1, 2, 0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fig, ax = plt.subplots(1, 3, tight_layout=True)\n",
"ax[0].imshow(image, cmap=\"gray\")\n",
"ax[1].imshow(secondary_image, cmap=\"magma\")\n",
"ax[2].imshow(image, cmap=\"gray\")\n",
"ax[2].imshow(secondary_image_padded, cmap=\"magma\", alpha=0.6)\n",
"ax[0].set_title(\"Primary image\")\n",
"ax[1].set_title(\"Secondary image\")\n",
"ax[2].set_title(\"Overlayed\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Now segment the secondary image over the primary\n",
"1. First create a stack of image_segmenter_overlayed objects"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"segmenter_stack = mpl.get_segmenter_list(image_stack, secondary_image_stack, n_classes=2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2. Call draw_masks function to open an interactive window where one can draw the masks on the seperate slices"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"mpl.draw_masks(segmenter_list=segmenter_stack)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"3. Retrieve mask values from segmenter_list"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"masks_dict = mpl.get_masks(segmenter_stack, plot_res=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"4. Retrieve contours of the masks"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"contours = mpl.get_mask_contours(segmenter_stack)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"5. Plot contours on segmented images"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fig,ax=plt.subplots(1,image_stack.shape[2])\n",
"\n",
"for n in range(len(image_stack.shape[2])):\n",
" ax[n].imshow(image_stack[:,:,n]) for n in range(len(image_stack.shape[2])\n",
" if len(contours[slice])>0:\n",
" for roi_num in range(len(contours[n])):\n",
" ax.plot(contours[n][roi_num][:,1], contours[n][roi_num][:,0], linewidth=2, color='C'+str(roi_num),label='ROI Nr.'+str(roi_num))\n",
"\n",
"ax.legend()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.9"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
2 changes: 2 additions & 0 deletions docs/examples/usage.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@
")\n",
"\n",
"iplt.title(\"the value of tau is: {tau:.2f}\", controls=controls[\"tau\"])\n",
"\n",
"\n",
"# you can still use plt commands if this is the active figure\n",
"def ylabel(tau):\n",
" return f\"tau/2 is {np.round(tau/2,3)}\"\n",
Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ examples/imshow.ipynb
examples/hist.ipynb
examples/scatter-selector.ipynb
examples/image-segmentation.ipynb
examples/image-segmentation-multiple-image.ipynb
examples/zoom-factory.ipynb
examples/heatmap-slicer.ipynb
```
Expand Down
Loading