-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Doc: added tutorial on macro/plugins/...
- Loading branch information
1 parent
0a9c928
commit 4f88309
Showing
20 changed files
with
980 additions
and
7 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
.. _tutorial_blobs: | ||
|
||
Detecting blobs on an image | ||
=========================== | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
""" | ||
Custom denoising filter plugin | ||
============================== | ||
This is a simple example of a DataLab image processing plugin. | ||
It is part of the DataLab custom function tutorial. | ||
.. note:: | ||
This plugin is not installed by default. To install it, copy this file to | ||
your DataLab plugins directory (see `DataLab documentation | ||
<https://codra-ingenierie-informatique.github.io/DataLab/en/features/general/plugins.html>`_). | ||
""" | ||
|
||
import numpy as np | ||
import scipy.ndimage as spi | ||
|
||
import cdl.core.computation.image as cpi | ||
import cdl.obj | ||
import cdl.param | ||
import cdl.plugins | ||
|
||
|
||
def weighted_average_denoise(values: np.ndarray) -> float: | ||
"""Apply a custom denoising filter to an image. | ||
This filter averages the pixels in a 5x5 neighborhood, but gives less weight | ||
to pixels that significantly differ from the central pixel. | ||
""" | ||
central_pixel = values[len(values) // 2] | ||
differences = np.abs(values - central_pixel) | ||
weights = np.exp(-differences / np.mean(differences)) | ||
return np.average(values, weights=weights) | ||
|
||
|
||
def compute_weighted_average_denoise(src: cdl.obj.ImageObj) -> cdl.obj.ImageObj: | ||
"""Compute Weighted average denoise | ||
This function is a wrapper around the ``weighted_average_denoise`` function, | ||
allowing to process an image object (instead of a NumPy array). | ||
It is required to use the function in DataLab. | ||
Args: | ||
src (ImageObj): input image object | ||
Returns: | ||
ImageObj: output image object | ||
""" | ||
dst = cpi.dst_11(src, weighted_average_denoise.__name__) | ||
dst.data = spi.generic_filter(src.data, weighted_average_denoise, size=5) | ||
return dst | ||
|
||
|
||
class CustomFilters(cdl.plugins.PluginBase): | ||
"""DataLab Custom Filters Plugin""" | ||
|
||
PLUGIN_INFO = cdl.plugins.PluginInfo( | ||
name="My custom filters", | ||
version="1.0.0", | ||
description="This is an example plugin", | ||
) | ||
|
||
def apply_func(self, func, title) -> None: | ||
"""Apply custom function""" | ||
self.imagepanel.processor.compute_11(func, title=title) | ||
|
||
def create_actions(self) -> None: | ||
"""Create actions""" | ||
acth = self.imagepanel.acthandler | ||
with acth.new_menu(self.PLUGIN_INFO.name): | ||
for name, func in ( | ||
("Weighted average denoise", compute_weighted_average_denoise), | ||
): | ||
acth.new_action(name, triggered=lambda: self.apply_func(func, name)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "76b9af91-1233-485b-a616-826a8ccfcbc8", | ||
"metadata": {}, | ||
"source": [ | ||
"DataLab custom function example\n", | ||
"===============================\n", | ||
"\n", | ||
"This is part of the DataLab's custom function tutorial which aims at illustrating the extensibility of DataLab (macros, plugins, and control from an external IDE or a Jupyter notebook). \n", | ||
"\n", | ||
"The only requirement is to install the *DataLab Simple Client* package (using `pip install cdlclient`, for example)." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"id": "47c889ba-ca07-46dd-bec0-b08d67bd1eb2", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import numpy as np\n", | ||
"import scipy.ndimage as spi\n", | ||
"from cdlclient import SimpleRemoteProxy\n", | ||
"\n", | ||
"# Define our custom processing function\n", | ||
"def weighted_average_denoise(values: np.ndarray) -> float:\n", | ||
" \"\"\"Apply a custom denoising filter to an image.\n", | ||
"\n", | ||
" This filter averages the pixels in a 5x5 neighborhood, but gives less weight\n", | ||
" to pixels that significantly differ from the central pixel.\n", | ||
" \"\"\"\n", | ||
" central_pixel = values[len(values) // 2]\n", | ||
" differences = np.abs(values - central_pixel)\n", | ||
" weights = np.exp(-differences / np.mean(differences))\n", | ||
" return np.average(values, weights=weights)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "721d52f6-2df8-4559-89d2-f7088a5e2ee2", | ||
"metadata": {}, | ||
"source": [ | ||
"Connecting to DataLab current session:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 3, | ||
"id": "1de8616a-619c-4d5b-869f-fb41cf72b7cf", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Connecting to DataLab XML-RPC server...OK (port: 61330)\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"proxy = SimpleRemoteProxy()\n", | ||
"proxy.connect()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "9246a105-d73d-4ba3-81e1-4fadd042a4c6", | ||
"metadata": {}, | ||
"source": [ | ||
"Switch to the \"Image panel\" and get the current image" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 5, | ||
"id": "ccdddb07-cc54-42dd-b744-751516ae73d9", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"proxy.set_current_panel(\"image\")\n", | ||
"image = proxy.get_object()\n", | ||
"if image is None:\n", | ||
" # We raise an explicit error if there is no image to process\n", | ||
" raise RuntimeError(\"No image to process!\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "0b717a9d-f92f-4269-8c47-150beeed1075", | ||
"metadata": {}, | ||
"source": [ | ||
"Get a copy of the image data, apply the function to it, and add new image to the panel" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 6, | ||
"id": "7216fc12-2675-48ff-a62a-64b5516c2e09", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"True" | ||
] | ||
}, | ||
"execution_count": 6, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"data = np.array(image.data, copy=True)\n", | ||
"data = spi.generic_filter(data, weighted_average_denoise, size=5)\n", | ||
"proxy.add_image(\"Filtered using a Jupyter notebook\", data)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "0ca0385b-bb43-4c14-b4ab-2768d44f04cc", | ||
"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.11.6" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
Example of remote control of DataLab current session, | ||
from a Python script running outside DataLab (e.g. in Spyder) | ||
Created on Fri May 12 12:28:56 2023 | ||
@author: p.raybaut | ||
""" | ||
|
||
# %% Importing necessary modules | ||
|
||
import numpy as np | ||
import scipy.ndimage as spi | ||
from cdlclient import SimpleRemoteProxy | ||
|
||
# %% Connecting to DataLab current session | ||
|
||
proxy = SimpleRemoteProxy() | ||
proxy.connect() | ||
|
||
# %% Executing commands in DataLab (...) | ||
|
||
# Define our custom processing function | ||
def weighted_average_denoise(values: np.ndarray) -> float: | ||
"""Apply a custom denoising filter to an image. | ||
This filter averages the pixels in a 5x5 neighborhood, but gives less weight | ||
to pixels that significantly differ from the central pixel. | ||
""" | ||
central_pixel = values[len(values) // 2] | ||
differences = np.abs(values - central_pixel) | ||
weights = np.exp(-differences / np.mean(differences)) | ||
return np.average(values, weights=weights) | ||
|
||
# Switch to the "Image panel" and get the current image | ||
proxy.set_current_panel("image") | ||
image = proxy.get_object() | ||
if image is None: | ||
# We raise an explicit error if there is no image to process | ||
raise RuntimeError("No image to process!") | ||
|
||
# Get a copy of the image data, and apply the function to it | ||
data = np.array(image.data, copy=True) | ||
data = spi.generic_filter(data, weighted_average_denoise, size=5) | ||
|
||
# Add new image to the panel | ||
proxy.add_image("Filtered using Spyder", data) |
Oops, something went wrong.