示例#1
0
def assert_sitk_img_equivalence(img: SimpleITK.Image,
                                img_ref: SimpleITK.Image):
    assert img.GetDimension() == img_ref.GetDimension()
    assert img.GetSize() == img_ref.GetSize()
    assert img.GetOrigin() == img_ref.GetOrigin()
    assert img.GetSpacing() == img_ref.GetSpacing()
    assert (img.GetNumberOfComponentsPerPixel() ==
            img_ref.GetNumberOfComponentsPerPixel())
    assert img.GetPixelIDValue() == img_ref.GetPixelIDValue()
    assert img.GetPixelIDTypeAsString() == img_ref.GetPixelIDTypeAsString()
示例#2
0
def fitting_index(image: sitk.Image,
                  norm: Union[int, str] = 2.0,
                  centre: Tuple[float, float, float] = None,
                  radius: float = None,
                  padding: bool = True) -> float:
    r""" Compute the fitting index of an input object.

    The fitting index of order `p` is defined as the Jaccard coefficient
    computed between the input object and a p-ball centred in the object's
    centre of mass.

    Parameters
    ----------
    image : sitk.Image
        Input binary image of the object.
    norm : Union[int,str]
        Order of the Minkowski norm ('inf' or 'max' to use the Chebyshev norm).
    centre : Tuple[float, float, float]
        Forces the p-ball to be centred in a specific point.
    radius : float
        Force the radius of the p-ball.
    padding : bool
        If `True`, add enough padding to be sure that the ball will entirely
        fit within the volume.

    Returns
    -------
    float
        Value of the fitting index.
    """

    if image.GetPixelID() != sitk.sitkUInt8:
        raise Exception('Unsupported %s pixel type' %
                        image.GetPixelIDTypeAsString())

    if centre is None:
        # Use the centroid as centre
        lssif = sitk.LabelShapeStatisticsImageFilter()
        lssif.Execute(image)
        centre = lssif.GetCentroid(1)

    if padding:
        # Add some padding to be sure that an isovolumetric 1-ball can fit
        # within the same volume of a sphere touching the boundary
        pad = tuple([x // 4 for x in image.GetSize()])
        image = sitk.ConstantPad(image, pad, pad, 0)
        image.SetOrigin((0, 0, 0))
        centre = tuple([x + y for x, y in zip(centre, pad)])

    if radius is None:
        radius = isovolumteric_radius(image, norm)

    size = image.GetSize()

    sphere = drawing.create_sphere(radius, size=size, centre=centre,
                                   norm=norm) > 0

    return jaccard(image, sphere)
示例#3
0
def check_if_image_is_rgb(image: sitk.Image):
    """Check if an image is RGB by looking for a 3-component 8 bit pixel image"""
    components = image.GetNumberOfComponentsPerPixel()
    pixel_type = image.GetPixelIDTypeAsString()

    if components == 3 and pixel_type == 'vector of 8-bit unsigned integer':
        image_is_rgb = True
    else:
        image_is_rgb = False

    return image_is_rgb
示例#4
0
def minkowski_compactness(image: sitk.Image,
                          norm: Union[int, str] = 1.0) -> float:
    r""" Compute the Minkovski compactness of a binary image.

    Minkowski compactness of an object is defined as the ratio between the volume
    of the object and the volume of a p-ball centred on the object's centre of
    mass, maximised agaist spatial rotations of the ball.

    Parameters
    ----------
    image : sitk.Image
        Input binary image.
    norm : Union[int,str]
        Order of the Minkowski norm ('inf' or 'max' to use the Chebyshev norm).

    Returns
    -------
    float
        Value of the Minkowski norm.
    """

    if image.GetPixelID() != sitk.sitkUInt8:
        raise Exception('Unsupported %s pixel type' %
                        image.GetPixelIDTypeAsString())

    if norm == 'inf' or norm == 'max':
        descriptor = 'cubeness'
    elif norm == 1.0:
        descriptor = 'octahedroness'
    else:
        raise Exception('Unsupported value %s for the norm parameter' %
                        str(norm))

    lssif = sitk.LabelShapeStatisticsImageFilter()
    lssif.Execute(image)

    a = sitk.GetArrayViewFromImage(image) > 0

    return _disptools.shape_descriptor(a, lssif.GetCentroid(1),
                                       image.GetSpacing(), descriptor)
示例#5
0
def sphericity(image: sitk.Image) -> float:
    r""" Measure the sphericity of a object.

    The sphericity is defined [5]_ [6]_ as the ratio between the surface of a sphere
    with the same volume of the object and the surface of the object itself.

    .. math::
        \frac{\pi^{\frac{1}{3}}(6V)^{\frac{2}{3}}}{A}

    A sphere has sphericity equal to 1, non-spherical objects have sphericity
    strictly lesser than 1.

    References
    ----------
    .. [5] Wadell, Hakon. "Volume, shape, and roundness of quartz particles."
           The Journal of Geology 43.3 (1935): 250-280.
    .. [6] Lehmann, Gaëthan. "Label object representation and manipulation with ITK"
           Insight Journal, July-December 2007

    Parameters
    ----------
    image : sitk.Image
        Input binary (sitkUInt8) image.

    Returns
    -------
    float
        A floating point value of sphericity in the interval [0, 1].
    """

    if image.GetPixelID() != sitk.sitkUInt8:
        raise Exception('Unsupported %s pixel type' %
                        image.GetPixelIDTypeAsString())

    lssif = sitk.LabelShapeStatisticsImageFilter()
    lssif.Execute(image)
    return lssif.GetRoundness(1)
示例#6
0
def cubicity(image: sitk.Image) -> float:
    r""" Measure the cubicity of an object.

    The cubicity is defined [4]_ as the ratio between the volume of the
    object and the volume of its bounding cube.
    A cube has cubicity equal to 1, a sphere has cubicity pi/6, and in
    general non-cubic objects have cubicity strictly lesser than 1.

    Here the bounding cube is estimated as the cube whose side is
    equal to the longest side of the oriented bounding box of the
    object.

    References
    ----------
    .. [4] O'Flannery, LJ and O'Mahony, MM, "Precise shape grading of
           coarse aggregate". Magazine of Concrete Research 51.5 (1999),
           pp. 319-324.

    Parameters
    ----------
    image : sitk.Image
        Input binary (sitkUInt8) image.

    Returns
    -------
    float
        A floating point value of cubicity in the interval [0, 1].
    """

    if image.GetPixelID() != sitk.sitkUInt8:
        raise Exception('Unsupported %s pixel type' %
                        image.GetPixelIDTypeAsString())

    # NOTE: the size of the bounding box is already in image space
    # units, while the volume (number of voxels) needs to be multiplied
    # by the voxel size
    dv = functools.reduce(lambda x, y: x * y, image.GetSpacing(), 1.0)

    try:
        lssif = sitk.LabelShapeStatisticsImageFilter()
        lssif.ComputeOrientedBoundingBoxOn()
        lssif.Execute(image)

        (s1, s2, s3) = lssif.GetOrientedBoundingBoxSize(1)
        volume = lssif.GetNumberOfPixels(1) * dv

    except AttributeError:
        # Use ITK as a fallback if the method is not available in
        # SimpleITK

        if 'itk' not in sys.modules:
            raise Exception(
                'sitk_to_itk: itk module is required to use this feature.')

        itk_image = drawing.sitk_to_itk(image)
        li2slmf = itk.LabelImageToShapeLabelMapFilter.IUC3LM3.New(itk_image)
        li2slmf.ComputeOrientedBoundingBoxOn()

        statistics = li2slmf()[0][1]

        #  FIXME GetOrientedBoundingBoxSize() seems to be broken
        #  (s1, s2, s3) = statistics.GetOrientedBoundingBoxSize() #
        (s1, s2, s3) = statistics.GetBoundingBox().GetSize()

        # FIXME GetBoundingBox is in voxels, GetOrientedBoundingBox is
        # in image size instead, so multiply by the spacing when using
        # GetBoundingBox
        (s1, s2,
         s3) = [x * s for x, s in zip([s1, s2, s3], image.GetSpacing())]

        volume = statistics.GetNumberOfPixels() * dv

    return volume / (max(s1, s2, s3)**3)