Mercurial > repos > imgteam > 2d_feature_extraction
changeset 7:048545339ced draft default tip
planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tree/master/tools/2d_feature_extraction/ commit b8e0b656d417db6e2ad0f187fc3c5afff0c3acd7
| author | imgteam |
|---|---|
| date | Tue, 06 Jan 2026 09:25:17 +0000 |
| parents | 8e3a52b74876 |
| children | |
| files | 2d_feature_extraction.py 2d_feature_extraction.xml test-data/output/input13-bbox.tsv test-data/output/input13-centroid.tsv test-data/output/input9.tsv validators.xml |
| diffstat | 6 files changed, 29 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/2d_feature_extraction.py Mon Jan 05 14:35:43 2026 +0000 +++ b/2d_feature_extraction.py Tue Jan 06 09:25:17 2026 +0000 @@ -45,11 +45,11 @@ # Validate the input image try: label_image = tool.args.input_images['labels'] - if any(label_image.shape[label_image.axes.index(axis)] > 1 for axis in label_image.axes if axis not in 'ZYX'): + if any(label_image.shape[label_image.axes.index(axis)] > 1 for axis in label_image.axes if axis not in 'XYZ'): raise ValueError(f'This tool is not applicable to images with {label_image.original_axes} axes.') # Extract the image features - for section in tool.run('ZYX'): # the validation code above guarantees that we will have only a single iteration + for section in tool.run('XYZ'): # the validation code above guarantees that we will have only a single iteration df = pd.DataFrame() # Get the labels array and cast to `uint8` if it is `bool` (`skimage.measure.regionprops` refuses `bool` typed arrays) @@ -89,6 +89,14 @@ lambda ait: surface(labels_section_data, regions[ait].label), # `skimage.measure.regionprops` cannot compute perimeters for 3-D data ) + # Add the object centroid using separate columns for the different coordinates + elif feature_name == 'centroid': + for axis_idx, axis in enumerate(section['labels'].axes): # XYZ + if section['labels'].shape[axis_idx] > 1: + df[f'{feature_name}_{axis.lower()}'] = df['it'].map( + lambda ait: getattr(regions[ait], feature_name)[axis_idx], + ) + # Skip features that are not available when processing 3-D images elif feature_name in ('eccentricity', 'moments_hu', 'orientation') and labels_section_data.ndim == 3: print(f'Skip feature that is not available for 3-D images: "{feature_name}"')
--- a/2d_feature_extraction.xml Mon Jan 05 14:35:43 2026 +0000 +++ b/2d_feature_extraction.xml Tue Jan 06 09:25:17 2026 +0000 @@ -4,7 +4,7 @@ <import>creators.xml</import> <import>validators.xml</import> <token name="@TOOL_VERSION@">0.25.2</token> - <token name="@VERSION_SUFFIX@">0</token> + <token name="@VERSION_SUFFIX@">1</token> <xml name="features"> <param name="features" type="select" label="Available features" multiple="true" display="checkboxes" help="*) Features marked with an asterisk are only available for 2-D images (not for 3-D images)."> @@ -231,7 +231,7 @@ **Bounding box:** Bounding box `(min_row, min_col, max_row, max_col)`. Pixels belonging to the bounding box are in the half-open interval `[min_row; max_row)` and `[min_col; max_col)`. -**Centroid:** Centroid coordinate tuple `(row, col)`. +**Centroid:** Centroid coordinates in separate columns ``centroid_x``, ``centroid_y``, and ``centroid_z`` when processing 3-D data. **Eccentricity:** Eccentricity of the ellipse that has the same second-moments as the region. The eccentricity is the ratio of the focal distance (distance between focal points) over the major axis length. The value is in the interval [0, 1). When it is 0, the ellipse becomes a circle.
--- a/test-data/output/input13-bbox.tsv Mon Jan 05 14:35:43 2026 +0000 +++ b/test-data/output/input13-bbox.tsv Tue Jan 06 09:25:17 2026 +0000 @@ -1,3 +1,3 @@ bbox -\[50, 60, 100, 110\] -\[150, 160, 200, 210\] +\[60, 50, 110, 100\] +\[160, 150, 210, 200\]
--- a/test-data/output/input13-centroid.tsv Mon Jan 05 14:35:43 2026 +0000 +++ b/test-data/output/input13-centroid.tsv Tue Jan 06 09:25:17 2026 +0000 @@ -1,3 +1,3 @@ -centroid -\[74.5, 84.5\] -\[174.5, 184.5\] +centroid_x centroid_y +84.5 74.5 +184.5 174.5
--- a/test-data/output/input9.tsv Mon Jan 05 14:35:43 2026 +0000 +++ b/test-data/output/input9.tsv Tue Jan 06 09:25:17 2026 +0000 @@ -1,2 +1,2 @@ -area area_convex area_filled axis_major_length axis_minor_length bbox centroid equivalent_diameter_area euler_number extent inertia_tensor_eigvals moments perimeter solidity max_intensity mean_intensity min_intensity -10076.0 19452.0 10076.0 141.5372[0-9]+ 2.2275[0-9]+ \[0, 0, 0, 2, 100, 100\] \[0.4791[0-9]+, 51.0215[0-9]+, 55.5112[0-9]+\] 26.7976[0-9]+ -1 0.5038 \[1633.5242[0-9]+, 1001.8878[0-9]+, 632.1326[0-9]+\] \[\[\[10076.0, 559331.0, 39680985.0, 3075710795.0\], \[514093.0, 26719026.0, 1828782204.0, 137703070104.0\], \[34057349.0, 1680671976.0, 112117199682.0, 8307987945522.0\], \[2545051621.0, 120295106826.0, 7853098605480.0, 574813269790152.0\]\], \[\[4828.0, 278845.0, 20126387.0, 1574048161.0\], \[246982.0, 13386366.0, 940613844.0, 72136219614.0\], \[16531236.0, 855530424.0, 59225271630.0, 4513705336536.0\], \[1248767206.0, 62249971170.0, 4259056106556.0, 323493844156146.0\]\], \[\[4828.0, 278845.0, 20126387.0, 1574048161.0\], \[246982.0, 13386366.0, 940613844.0, 72136219614.0\], \[16531236.0, 855530424.0, 59225271630.0, 4513705336536.0\], \[1248767206.0, 62249971170.0, 4259056106556.0, 323493844156146.0\]\], \[\[4828.0, 278845.0, 20126387.0, 1574048161.0\], \[246982.0, 13386366.0, 940613844.0, 72136219614.0\], \[16531236.0, 855530424.0, 59225271630.0, 4513705336536.0\], \[1248767206.0, 62249971170.0, 4259056106556.0, 323493844156146.0\]\]\] 10076 0.5179[0-9]+ 999.8037[0-9]+ 523.4422[0-9]+ 0.1145[0-9]+ +area area_convex area_filled axis_major_length axis_minor_length bbox centroid_x centroid_y centroid_z equivalent_diameter_area euler_number extent inertia_tensor_eigvals moments perimeter solidity max_intensity mean_intensity min_intensity +10076.0 19452.0 10076.0 141.5372[0-9]+ 2.2275[0-9]+ \[0, 0, 0, 100, 100, 2\] 55.5112[0-9]+ 51.0215[0-9]+ 0.4791[0-9]+ 26.7976[0-9]+ -1 0.5038 \[1633.5242[0-9]+, 1001.8878[0-9]+, 632.1326[0-9]+\] \[\[\[10076.0, 4828.0, 4828.0, 4828.0\], \[514093.0, 246982.0, 246982.0, 246982.0\], \[34057349.0, 16531236.0, 16531236.0, 16531236.0\], \[2545051621.0, 1248767206.0, 1248767206.0, 1248767206.0\]\], \[\[559331.0, 278845.0, 278845.0, 278845.0\], \[26719026.0, 13386366.0, 13386366.0, 13386366.0\], \[1680671976.0, 855530424.0, 855530424.0, 855530424.0\], \[120295106826.0, 62249971170.0, 62249971170.0, 62249971170.0\]\], \[\[39680985.0, 20126387.0, 20126387.0, 20126387.0\], \[1828782204.0, 940613844.0, 940613844.0, 940613844.0\], \[112117199682.0, 59225271630.0, 59225271630.0, 59225271630.0\], \[7853098605480.0, 4259056106556.0, 4259056106556.0, 4259056106556.0\]\], \[\[3075710795.0, 1574048161.0, 1574048161.0, 1574048161.0\], \[137703070104.0, 72136219614.0, 72136219614.0, 72136219614.0\], \[8307987945522.0, 4513705336536.0, 4513705336536.0, 4513705336536.0\], \[574813269790152.0, 323493844156146.0, 323493844156146.0, 323493844156146.0\]\]\] 10076 0.5179[0-9]+ 999.8037[0-9]+ 523.4422[0-9]+ 0.1145[0-9]+
--- a/validators.xml Mon Jan 05 14:35:43 2026 +0000 +++ b/validators.xml Tue Jan 06 09:25:17 2026 +0000 @@ -32,6 +32,16 @@ ><![CDATA[getattr(value.metadata, "depth", None) in (None, '') or int(value.metadata.depth) < 2]]></validator> </xml> + <xml name="validators/is_3d"> + <!-- + The OME-Zarr datatype in Galaxy is currently not derived from the Image datatype, and it does + hence not inherit the metadata fields like `depth`. To cope with that, we allow all datasets + except those where we *know* that they are *not* 3-D. + --> + <validator type="expression" message="Dataset is a 2-D image" + ><![CDATA[getattr(value.metadata, "depth", None) in (None, '') or int(value.metadata.depth) >= 2]]></validator> + </xml> + <xml name="validators/is_binary"> <!-- The OME-Zarr datatype in Galaxy is currently not derived from the Image datatype, and it does
