Mercurial > repos > thomaswollmann > 2d_feature_extraction
changeset 0:4d6e6901df43 draft default tip
planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tools/2d_feature_extraction/ commit d93e1dd276027cfc3fb518236110395a23d96f66
author | thomaswollmann |
---|---|
date | Wed, 16 Jan 2019 15:32:39 -0500 |
parents | |
children | |
files | 2d_feature_extraction.py 2d_feature_extraction.xml test-data/input.tiff test-data/out.csv |
diffstat | 4 files changed, 224 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/2d_feature_extraction.py Wed Jan 16 15:32:39 2019 -0500 @@ -0,0 +1,124 @@ +import argparse +import numpy as np +import pandas as pd +import tifffile +import skimage.io +import skimage.measure +import skimage.feature +import skimage.segmentation +import skimage.morphology + +#TODO make importable by python script + +parser = argparse.ArgumentParser(description='Extract Features 2D') + +#TODO create factory for boilerplate code +features = parser.add_argument_group('compute features') +features.add_argument('--all', dest='all_features', action='store_true') +features.add_argument('--label', dest='add_label', action='store_true') +features.add_argument('--patches', dest='add_roi_patches', action='store_true') +features.add_argument('--max_intensity', dest='max_intensity', action='store_true') +features.add_argument('--mean_intensity', dest='mean_intensity', action='store_true') +features.add_argument('--min_intensity', dest='min_intensity', action='store_true') +features.add_argument('--moments_hu', dest='moments_hu', action='store_true') +features.add_argument('--centroid', dest='centroid', action='store_true') +features.add_argument('--bbox', dest='bbox', action='store_true') +features.add_argument('--area', dest='area', action='store_true') +features.add_argument('--filled_area', dest='filled_area', action='store_true') +features.add_argument('--convex_area', dest='convex_area', action='store_true') +features.add_argument('--perimeter', dest='perimeter', action='store_true') +features.add_argument('--extent', dest='extent', action='store_true') +features.add_argument('--eccentricity', dest='eccentricity', action='store_true') +features.add_argument('--equivalent_diameter', dest='equivalent_diameter', action='store_true') +features.add_argument('--euler_number', dest='euler_number', action='store_true') +features.add_argument('--inertia_tensor_eigvals', dest='inertia_tensor_eigvals', action='store_true') +features.add_argument('--major_axis_length', dest='major_axis_length', action='store_true') +features.add_argument('--minor_axis_length', dest='minor_axis_length', action='store_true') +features.add_argument('--orientation', dest='orientation', action='store_true') +features.add_argument('--solidity', dest='solidity', action='store_true') +features.add_argument('--moments', dest='moments', action='store_true') +features.add_argument('--convexity', dest='convexity', action='store_true') + +parser.add_argument('--label_file_binary', dest='label_file_binary', action='store_true') + +parser.add_argument('--raw', dest='raw_file', type=argparse.FileType('r'), + help='Original input file', required=False) +parser.add_argument('label_file', type=argparse.FileType('r'), + help='Label input file') +parser.add_argument('output_file', type=argparse.FileType('w'), + help='Tabular output file') +args = parser.parse_args() + +label_file_binary = args.label_file_binary +label_file = args.label_file.name +out_file = args.output_file.name +add_patch = args.add_roi_patches + +raw_image = None +if args.raw_file is not None: + raw_image = skimage.io.imread(args.raw_file.name) + +raw_label_image = skimage.io.imread(label_file) + +df = pd.DataFrame() +if label_file_binary: + raw_label_image = skimage.measure.label(raw_label_image) +regions = skimage.measure.regionprops(raw_label_image, intensity_image=raw_image) + +df['it'] = np.arange(len(regions)) + +if add_patch: + df['image'] = df['it'].map(lambda ait: regions[ait].image.astype(np.float).tolist()) + df['intensity_image'] = df['it'].map(lambda ait: regions[ait].intensity_image.astype(np.float).tolist()) + +#TODO no matrix features, but split in own rows? +if args.add_label or args.all_features: + df['label'] = df['it'].map(lambda ait: regions[ait].label) + +if raw_image is not None: + if args.max_intensity or args.all_features: + df['max_intensity'] = df['it'].map(lambda ait: regions[ait].max_intensity) + if args.mean_intensity or args.all_features: + df['mean_intensity'] = df['it'].map(lambda ait: regions[ait].mean_intensity) + if args.min_intensity or args.all_features: + df['min_intensity'] = df['it'].map(lambda ait: regions[ait].min_intensity) + if args.moments_hu or args.all_features: + df['moments_hu'] = df['it'].map(lambda ait: regions[ait].moments_hu) + +if args.centroid or args.all_features: + df['centroid'] = df['it'].map(lambda ait: regions[ait].centroid) +if args.bbox or args.all_features: + df['bbox'] = df['it'].map(lambda ait: regions[ait].bbox) +if args.area or args.all_features: + df['area'] = df['it'].map(lambda ait: regions[ait].area) +if args.filled_area or args.all_features: + df['filled_area'] = df['it'].map(lambda ait: regions[ait].filled_area) +if args.convex_area or args.all_features: + df['convex_area'] = df['it'].map(lambda ait: regions[ait].convex_area) +if args.perimeter or args.all_features: + df['perimeter'] = df['it'].map(lambda ait: regions[ait].perimeter) +if args.extent or args.all_features: + df['extent'] = df['it'].map(lambda ait: regions[ait].extent) +if args.eccentricity or args.all_features: + df['eccentricity'] = df['it'].map(lambda ait: regions[ait].eccentricity) +if args.equivalent_diameter or args.all_features: + df['equivalent_diameter'] = df['it'].map(lambda ait: regions[ait].equivalent_diameter) +if args.euler_number or args.all_features: + df['euler_number'] = df['it'].map(lambda ait: regions[ait].euler_number) +if args.inertia_tensor_eigvals or args.all_features: + df['inertia_tensor_eigvals'] = df['it'].map(lambda ait: regions[ait].inertia_tensor_eigvals) +if args.major_axis_length or args.all_features: + df['major_axis_length'] = df['it'].map(lambda ait: regions[ait].major_axis_length) +if args.minor_axis_length or args.all_features: + df['minor_axis_length'] = df['it'].map(lambda ait: regions[ait].minor_axis_length) +if args.orientation or args.all_features: + df['orientation'] = df['it'].map(lambda ait: regions[ait].orientation) +if args.solidity or args.all_features: + df['solidity'] = df['it'].map(lambda ait: regions[ait].solidity) +if args.moments or args.all_features: + df['moments'] = df['it'].map(lambda ait: regions[ait].moments) +if args.convexity or args.all_features: + df['convexity'] = df.area/(df.perimeter*df.perimeter) + +del df['it'] +df.to_csv(out_file, sep='\t', line_terminator='\n', index=False)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/2d_feature_extraction.xml Wed Jan 16 15:32:39 2019 -0500 @@ -0,0 +1,88 @@ +<?xml version="1.0"?> +<tool name="2D Feature Extraction" id="ip_2d_feature_extraction" version="0.0.8"> + <description>Feature Extraction</description> + <requirements> + <requirement type="package" version="0.23.4">pandas</requirement> + <requirement type="package" version="0.14.0">scikit-image</requirement> + <requirement type="package" version="1.15.4">numpy</requirement> + <requirement type="package" version="0.15.1">tifffile</requirement> + </requirements> + <command> + <![CDATA[ + python '$__tool_directory__/2d_feature_extraction.py' + #if $feature_options['features'] == 'all' + --all + #else if $feature_options['features'] == 'select' + ${' '.join(str( $feature_options['selected_features'] ).split(','))} + #end if + #if $use_raw_option['use_raw'] == 'raw_image' + --raw '$input_raw' + #end if + '$input_label' '$output' + ]]> + </command> + <inputs> + <param name="input_label" type="data" format="tiff" label="Label file" /> + <conditional name="use_raw_option"> + <param label="Use original image to compute additional features" name="use_raw" type="select"> + <option selected="True" value="no_original">No original image</option> + <option value="raw_image">Use original image</option> + </param> + <when value="no_original"> </when> + <when value="raw_image"> + <param name="input_raw" type="data" format="tiff" label="Original image file" /> + </when> + </conditional> + <conditional name="feature_options"> + <param label="Select features to compute" name="features" type="select"> + <option selected="True" value="all">All features</option> + <option value="select">Select features</option> + </param> + <when value="all"> </when> + <when value="select"> + <param name="selected_features" type="select" label="Available features" multiple="true" display="checkboxes"> + <option value="--label">Add label id of label image</option> + <option value="--patches">Patches (requires original image)</option> + <option value="--max_intensity">Max Intensity (requires original image)</option> + <option value="--mean_intensity">Mean Intensity (requires original image)</option> + <option value="--min_intensity">Minimum Intensity (requires original image)</option> + <option value="--moments_hu">Moments Hu</option> + <option value="--centroid">Centroid</option> + <option value="--bbox">Bounding Box</option> + <option value="--area">Area</option> + <option value="--filled_area">Filled Area</option> + <option value="--convex_area">Convex Area</option> + <option value="--perimeter">Perimeter</option> + <option value="--extent">Extent</option> + <option value="--eccentricity">Eccentricity</option> + <option value="--equivalent_diameter">Equivalent Diameter</option> + <option value="--euler_number">Euler Number</option> + <option value="--inertia_tensor_eigvals">Inertia Tensor Eigenvalues</option> + <option value="--major_axis_length">Major Axis Length</option> + <option value="--minor_axis_length">Minor Axis Length</option> + <option value="--orientation">Orientation</option> + <option value="--solidity">Solidity</option> + <option value="--moments">Moments</option> + <option value="--convexity">Convexity</option> + </param> + </when> + </conditional> + </inputs> + <outputs> + <data format="tabular" name="output" /> + </outputs> + <tests> + <test> + <param name="input_label" value="input.tiff"/> + <param name="features" value="select"/> + <param name="selected_features" value="--area"/> + <output name="output" ftype="tabular" value="out.csv"/> + </test> + </tests> + <help> + This tool computes several features of a 2D label image and optionally more features using the original image. + </help> + <citations> + <citation type="doi">10.1016/j.jbiotec.2017.07.019</citation> + </citations> +</tool>