Skip to content

Commit

Permalink
Merge pull request BMCV#125 from rmassei/master
Browse files Browse the repository at this point in the history
Add background_removal tool (skimage)
  • Loading branch information
kostrykin authored Jul 15, 2024
2 parents 1688098 + c6b1140 commit 004112a
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 0 deletions.
5 changes: 5 additions & 0 deletions macros/creators.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
<yield />
</xml>

<xml name="creators/rmassei">
<person givenName="Riccardo" familyName="Massei"/>
<yield/>
</xml>

<xml name="creators/alliecreason">
<person givenName="Allison" familyName="Creason"/>
<yield/>
Expand Down
8 changes: 8 additions & 0 deletions tools/background_removal/.shed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
categories:
- Imaging
description: Background removal filters using scikit-image
long_description: Tool to perform a background removal using 1) Rolling-Ball Algorithm, 2) Difference of Gaussians and 3) Top-Hat Filter
name: background_removal
owner: ufz
homepage_url: https://github.com/bmcv
remote_repository_url: https://github.com/BMCV/galaxy-image-analysis/tools/background_removal
59 changes: 59 additions & 0 deletions tools/background_removal/background_removal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import argparse
import warnings

import numpy as np
import skimage.io
from skimage.filters import difference_of_gaussians
from skimage.io import imread
from skimage.morphology import disk, white_tophat
from skimage.restoration import rolling_ball


def process_image(args):
image = imread(args.input_image)

if args.filter == "rolling_ball":
background_rolling = rolling_ball(image, radius=args.radius)
output_image = image - background_rolling

elif args.filter == "dog":
output_image = difference_of_gaussians(image, low_sigma=0, high_sigma=args.radius)

elif args.filter == "top_hat":
output_image = white_tophat(image, disk(args.radius))

with warnings.catch_warnings():
output_image = convert_image_to_format_of(output_image, image)
skimage.io.imsave(args.output, output_image, plugin="tifffile")


def convert_image_to_format_of(image, format_image):
"""
Convert the first image to the format of the second image.
"""
if format_image.dtype == image.dtype:
return image
elif format_image.dtype == np.uint8:
return skimage.util.img_as_ubyte(image)
elif format_image.dtype == np.uint16:
return skimage.util.img_as_uint(image)
elif format_image.dtype == np.int16:
return skimage.util.img_as_int(image)
else:
raise ValueError(f'Unsupported image data type: {format_image.dtype}')


def main():
parser = argparse.ArgumentParser(description="Background removal script using skiimage")
parser.add_argument('input_image', help="Input image path")
parser.add_argument('filter', choices=['rolling_ball', 'dog', 'top_hat'],
help="Background removal algorithm")
parser.add_argument('radius', type=float, help="Radius")
parser.add_argument('output', help="Output image path")

args = parser.parse_args()
process_image(args)


if __name__ == '__main__':
main()
72 changes: 72 additions & 0 deletions tools/background_removal/background_removal.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<tool id="background_removal" name="Remove image background" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="20.05">
<description>with scikit-image</description>
<macros>
<import>creators.xml</import>
<import>tests.xml</import>
<token name="@TOOL_VERSION@">0.24.0</token>
<token name="@VERSION_SUFFIX@">0</token>
</macros>
<creator>
<expand macro="creators/rmassei"/>
</creator>
<requirements>
<requirement type="package" version="0.24.0">scikit-image</requirement>
</requirements>
<command detect_errors="aggressive">
<![CDATA[
python "$__tool_directory__/background_removal.py" $input_image $filter $radius $output
]]>
</command>
<inputs>
<param name="input_image" type="data" format="tiff, jpg, jpeg, png, tif" label="Input Image"/>
<param name="filter" type="select" label="Select Filter">
<option value="rolling_ball">Rolling-ball algorithm</option>
<option value="dog">Difference of Gaussians</option>
<option value="top_hat">Top-hat filter</option>
</param>
<param name="radius" type="float" label="Radius" value="20"/>
</inputs>
<outputs>
<data name="output" format="tiff" label="Background substraction output"/>
</outputs>
<tests>
<!-- uint8 tests -->
<test>
<param name="input_image" value="input1_uint8.tif"/>
<param name="filter" value="dog"/>
<param name="radius" value="20"/>
<expand macro="tests/intensity_image_diff" name="output" value="input1_output_dog.tif" ftype="tiff"/>
</test>
<test>
<param name="input_image" value="input3_uint8.tif"/>
<param name="filter" value="top_hat"/>
<param name="radius" value="15"/>
<expand macro="tests/intensity_image_diff" name="output" value="input3_output_tophat.tif" ftype="tiff"/>
</test>
<!-- uint16 tests -->
<test>
<param name="input_image" value="input2_uint16.tif"/>
<param name="filter" value="rolling_ball"/>
<param name="radius" value="20"/>
<expand macro="tests/intensity_image_diff" name="output" value="input2_output_rb.tif" ftype="tiff"/>
</test>
<test>
<param name="input_image" value="input2_uint16.tif"/>
<param name="filter" value="dog"/>
<param name="radius" value="20"/>
<expand macro="tests/intensity_image_diff" name="output" value="input2_output_dog.tif" ftype="tiff"/>
</test>
</tests>
<help>
This tool applies different background removal algorithms to an image:

- Rolling-ball algorithm

- Difference of Gaussians

- Top-hat filter
</help>
<citations>
<citation type="doi">10.1109/MC.1983.1654163</citation>
</citations>
</tool>
1 change: 1 addition & 0 deletions tools/background_removal/creators.xml
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions tools/background_removal/tests.xml

0 comments on commit 004112a

Please sign in to comment.