From a43dbb946e8cce09e987d9f7d9f8956dcef5527e Mon Sep 17 00:00:00 2001 From: Kevin Mader Date: Thu, 28 Jun 2018 12:04:03 +0200 Subject: [PATCH 1/2] Create shape_analysis.py adding shape analysis code --- pyqae/shape_analysis.py | 84 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 pyqae/shape_analysis.py diff --git a/pyqae/shape_analysis.py b/pyqae/shape_analysis.py new file mode 100644 index 0000000..7c814da --- /dev/null +++ b/pyqae/shape_analysis.py @@ -0,0 +1,84 @@ +""" +Tools for analyzing the labels and data made in lungstage +""" +import warnings +from warnings import warn + +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +from pyqae.nd import autocrop +from pyqae.viz import draw_3d_labels +from skimage.measure import regionprops + +try: + # sklearn team renamed the core marching cubes and replaced it with something funkier + from skimage.measure import marching_cubes_classic as marching_cubes +except ImportError: + from skimage.measure import marching_cubes + +from skimage.filters import gaussian +from scipy.ndimage import zoom +from mpl_toolkits.mplot3d.art3d import Poly3DCollection + +fake_HTML = lambda x: x # dummy function + + +def scalar_attributes_list(im_props): + """ + Makes list of all scalar, non-dunder, non-hidden + attributes of skimage.measure.regionprops object + """ + + attributes_list = [] + + for i, test_attribute in enumerate(dir(im_props[0])): + + # Attribute should not start with _ and cannot return an array + # does not yet return tuples + try: + if test_attribute[:1] != '_' and not \ + isinstance(getattr(im_props[0], test_attribute), np.ndarray): + attributes_list += [test_attribute] + except Exception as e: + warn("Not implemented: {} - {}".format(test_attribute, e), RuntimeWarning) + + return attributes_list + + +def regionprops_to_df(im_props): + """ + Read content of all attributes for every item in a list + output by skimage.measure.regionprops + """ + + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + attributes_list = scalar_attributes_list(im_props) + + # Initialise list of lists for parsed data + parsed_data = [] + + # Put data from im_props into list of lists + for i, _ in enumerate(im_props): + parsed_data += [[]] + + for j in range(len(attributes_list)): + parsed_data[i] += [getattr(im_props[i], attributes_list[j])] + + # Return as a Pandas DataFrame + return pd.DataFrame(parsed_data, columns=attributes_list) + + +def region_analysis(cur_mask, cur_image): + assert cur_mask.shape == cur_image.shape, "Mask and image must have same shape\n {} != {}".format(cur_mask.shape, + cur_image.shape) + return regionprops_to_df(regionprops(cur_mask, intensity_image=cur_image)) + + +if __name__ == '__main__': + import doctest + # noinspection PyUnresolvedReferences + import lungstage.shape_analysis + + doctest.testmod(lungstage.shape_analysis, verbose=True, optionflags=doctest.ELLIPSIS) From 59f43786520c3a216a8e6b79ce6e73f8f5933448 Mon Sep 17 00:00:00 2001 From: Kevin Mader Date: Thu, 28 Jun 2018 12:06:19 +0200 Subject: [PATCH 2/2] Update shape_analysis.py changing lungstage to pyqae --- pyqae/shape_analysis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyqae/shape_analysis.py b/pyqae/shape_analysis.py index 7c814da..bfaf4ae 100644 --- a/pyqae/shape_analysis.py +++ b/pyqae/shape_analysis.py @@ -79,6 +79,6 @@ def region_analysis(cur_mask, cur_image): if __name__ == '__main__': import doctest # noinspection PyUnresolvedReferences - import lungstage.shape_analysis + import pyqae.shape_analysis - doctest.testmod(lungstage.shape_analysis, verbose=True, optionflags=doctest.ELLIPSIS) + doctest.testmod(pyqae.shape_analysis, verbose=True, optionflags=doctest.ELLIPSIS)