changeset 5:7db4fc31dbee draft

planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tree/master/tools/2d_auto_threshold/ commit 8b9f24cbfaf54f140705f0bf4b6732269bd401da
author imgteam
date Mon, 11 Mar 2024 17:12:33 +0000
parents 3df9f0a4bf34
children 8bccb36e055a
files auto_threshold.py auto_threshold.xml test-data/out3.tif
diffstat 3 files changed, 94 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/auto_threshold.py	Fri Nov 10 14:23:07 2023 +0000
+++ b/auto_threshold.py	Mon Mar 11 17:12:33 2024 +0000
@@ -1,37 +1,38 @@
 """
-Copyright 2017-2022 Biomedical Computer Vision Group, Heidelberg University.
+Copyright 2017-2024 Biomedical Computer Vision Group, Heidelberg University.
 
 Distributed under the MIT license.
 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
-
 """
 
 import argparse
 
+import numpy as np
 import skimage.filters
 import skimage.io
 import skimage.util
 import tifffile
 
-thOptions = {
-    'otsu': lambda img_raw, bz: skimage.filters.threshold_otsu(img_raw),
-    'li': lambda img_raw, bz: skimage.filters.threshold_li(img_raw),
-    'yen': lambda img_raw, bz: skimage.filters.threshold_yen(img_raw),
-    'isodata': lambda img_raw, bz: skimage.filters.threshold_isodata(img_raw),
+th_methods = {
+    'manual': lambda thres, **kwargs: thres,
 
-    'loc_gaussian': lambda img_raw, bz: skimage.filters.threshold_local(img_raw, bz, method='gaussian'),
-    'loc_median': lambda img_raw, bz: skimage.filters.threshold_local(img_raw, bz, method='median'),
-    'loc_mean': lambda img_raw, bz: skimage.filters.threshold_local(img_raw, bz, method='mean')
+    'otsu': lambda img_raw, **kwargs: skimage.filters.threshold_otsu(img_raw),
+    'li': lambda img_raw, **kwargs: skimage.filters.threshold_li(img_raw),
+    'yen': lambda img_raw, **kwargs: skimage.filters.threshold_yen(img_raw),
+    'isodata': lambda img_raw, **kwargs: skimage.filters.threshold_isodata(img_raw),
+
+    'loc_gaussian': lambda img_raw, bz, **kwargs: skimage.filters.threshold_local(img_raw, bz, method='gaussian'),
+    'loc_median': lambda img_raw, bz, **kwargs: skimage.filters.threshold_local(img_raw, bz, method='median'),
+    'loc_mean': lambda img_raw, bz, **kwargs: skimage.filters.threshold_local(img_raw, bz, method='mean')
 }
 
 
-def auto_thresholding(in_fn, out_fn, th_method, block_size=5, dark_bg=True):
+def do_thresholding(in_fn, out_fn, th_method, block_size=5, threshold=0, invert_output=False):
     img = skimage.io.imread(in_fn)
-    th = thOptions[th_method](img, block_size)
-    if dark_bg:
-        res = img > th
-    else:
-        res = img <= th
+    th = th_methods[th_method](img_raw=img, bz=block_size, thres=threshold)
+    res = img > th
+    if invert_output:
+        res = np.logical_not(res)
     tifffile.imwrite(out_fn, skimage.util.img_as_ubyte(res))
 
 
@@ -39,9 +40,10 @@
     parser = argparse.ArgumentParser(description='Automatic Image Thresholding')
     parser.add_argument('im_in', help='Path to the input image')
     parser.add_argument('im_out', help='Path to the output image (TIFF)')
-    parser.add_argument('th_method', choices=thOptions.keys(), help='Thresholding method')
+    parser.add_argument('th_method', choices=th_methods.keys(), help='Thresholding method')
     parser.add_argument('block_size', type=int, default=5, help='Odd size of pixel neighborhood for calculating the threshold')
-    parser.add_argument('dark_bg', default=True, type=bool, help='True if background is dark')
+    parser.add_argument('threshold', type=float, default=0, help='Manual thresholding value')
+    parser.add_argument('invert_output', default=False, type=bool, help='Values below/above the threshold are labeled with 0/255 if False, and with 255/0 otherwise')
     args = parser.parse_args()
 
-    auto_thresholding(args.im_in, args.im_out, args.th_method, args.block_size, args.dark_bg)
+    do_thresholding(args.im_in, args.im_out, args.th_method, args.block_size, args.threshold, args.invert_output)
--- a/auto_threshold.xml	Fri Nov 10 14:23:07 2023 +0000
+++ b/auto_threshold.xml	Mon Mar 11 17:12:33 2024 +0000
@@ -1,5 +1,9 @@
-<tool id="ip_threshold" name="Threshold image" version="0.0.5-2" profile="20.05">
+<tool id="ip_threshold" name="Threshold image" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="20.05">
     <description>with scikit-image</description>
+    <macros>
+        <token name="@TOOL_VERSION@">0.18.1</token>
+        <token name="@VERSION_SUFFIX@">0</token>
+    </macros>
     <edam_operations>
         <edam_operation>operation_3443</edam_operation>
     </edam_operations>
@@ -16,24 +20,59 @@
     python '$__tool_directory__/auto_threshold.py'
     '$input'
     ./out.tif
-    '$th_method'
-    '$block_size'
-    '$dark_bg'
+    '$th_method.method_id'
+    '$th_method.block_size'
+    '$th_method.threshold'
+    '$invert_output'
     ]]>
     </command>
     <inputs>
         <param name="input" type="data" format="tiff,png" label="Input image" />
-        <param name="th_method" type="select" label="Thresholding method">
-          <option value="otsu" selected="True">Otsu</option>
-          <option value="li">Li's Minimum Cross Entropy</option>
-          <option value="isodata">Isodata</option>
-          <option value="yen">Yen</option>
-          <option value="loc_gaussian">Adaptive (Gaussian)</option>
-          <option value="loc_median">Adaptive (Median)</option>
-          <option value="loc_mean">Adaptive (Mean)</option>
-        </param>
-        <param name="block_size" type="integer" value="5" label="Odd size of pixel neighborhood for determining the threshold (only valid for adaptive thresholding methods)" />
-        <param name="dark_bg" type="boolean" checked="true" truevalue="True" falsevalue="False" label="Dark Background" />
+        <conditional name="th_method">
+            <param name="method_id" type="select" label="Thresholding method">
+                <option value="manual">Manual</option>
+                <option value="otsu" selected="True">Globally adaptive / Otsu</option>
+                <option value="li">Globally adaptive / Li's Minimum Cross Entropy</option>
+                <option value="isodata">Globally adaptive / Isodata</option>
+                <option value="yen">Globally adaptive / Yen</option>
+                <option value="loc_gaussian">Locally adaptive / Gaussian</option>
+                <option value="loc_median">Locally adaptive / Median</option>
+                <option value="loc_mean">Locally adaptive / Mean</option>
+            </param>
+            <when value="manual">
+                <param name="threshold" type="float" value="0" label="Threshold value" />
+                <param name="block_size" type="hidden" value="0" />
+            </when>
+            <when value="otsu">
+                <param name="threshold" type="hidden" value="0" />
+                <param name="block_size" type="hidden" value="0" />
+            </when>
+            <when value="li">
+                <param name="threshold" type="hidden" value="0" />
+                <param name="block_size" type="hidden" value="0" />
+            </when>
+            <when value="isodata">
+                <param name="threshold" type="hidden" value="0" />
+                <param name="block_size" type="hidden" value="0" />
+            </when>
+            <when value="yen">
+                <param name="threshold" type="hidden" value="0" />
+                <param name="block_size" type="hidden" value="0" />
+            </when>
+            <when value="loc_gaussian">
+                <param name="threshold" type="hidden" value="0" />
+                <param name="block_size" type="integer" value="5" label="Odd size of pixel neighborhood for determining the threshold" />
+            </when>
+            <when value="loc_median">
+                <param name="threshold" type="hidden" value="0" />
+                <param name="block_size" type="integer" value="5" label="Odd size of pixel neighborhood for determining the threshold" />
+            </when>
+            <when value="loc_mean">
+                <param name="threshold" type="hidden" value="0" />
+                <param name="block_size" type="integer" value="5" label="Odd size of pixel neighborhood for determining the threshold" />
+            </when>
+        </conditional>
+        <param name="invert_output" type="boolean" checked="false" truevalue="True" falsevalue="False" label="Invert output labels" help="Pixels are usually assigned the label 0 if the pixel value is below (or equal to) the threshold, and 255 if it is above the threshold. If this option is activated, pixels are assigned the label 255 if the pixel value is below (or equal to) the threshold, and 0 if it is above the threshold." />
     </inputs>
     <outputs>
        <data format="tiff" name="output" from_work_dir="out.tif" />
@@ -41,21 +80,34 @@
     <tests>
         <test>
             <param name="input" value="sample.tif"/>
-            <output name="output" value="out.tif" ftype="tiff" compare="sim_size"/>
-            <param name="th_method" value="loc_gaussian"/>
+            <output name="output" value="out.tif" ftype="tiff" compare="sim_size" delta="10"/>
+            <param name="method_id" value="loc_gaussian"/>
             <param name="block_size" value="3"/>
-            <param name="dark_bg" value="True"/>
+            <param name="invert_output" value="False"/>
         </test>
         <test>
             <param name="input" value="sample.tif"/>
-            <output name="output" value="out2.tif" ftype="tiff" compare="sim_size"/>
-            <param name="th_method" value="otsu"/>
+            <output name="output" value="out2.tif" ftype="tiff" compare="sim_size" delta="10"/>
+            <param name="method_id" value="otsu"/>
             <param name="block_size" value="5"/>
-            <param name="dark_bg" value="True"/>
+            <param name="invert_output" value="False"/>
+        </test>
+        <test>
+            <param name="input" value="sample.tif"/>
+            <output name="output" value="out3.tif" ftype="tiff" compare="sim_size" delta="10"/>
+            <param name="method_id" value="manual"/>
+            <param name="threshold" value="64"/>
+            <param name="invert_output" value="True"/>
         </test>
     </tests>
     <help>
         Applies a standard thresholding algorithm to an image.
+
+        The thresholding algorithm automatically determines a threshold value (unless manual thresholding is used).
+        The input image is then thresholded, by assigning white (pixel value 255) to image regions above the determined threshold,
+        and black (pixel value 0) to image regions below or equal to the determined threshold.
+
+        The assignment of black and white to image regions below and above the threshold is inverted, if the corresponding option is set.
     </help>
     <citations>
         <citation type="doi">10.1016/j.jbiotec.2017.07.019</citation>
Binary file test-data/out3.tif has changed