Beispiel #1
0
    def mesh_to_mask(mesh: trimesh.Trimesh, R, grid_size):
        mesh.vertices = mesh.vertices @ R.T
        bottom_left = np.min(mesh.vertices[:,:2], axis = 0)
        top_right = np.max(mesh.vertices[:,:2], axis = 0)

        x = np.arange(bottom_left[0], top_right[0], grid_size)
        y = np.arange(bottom_left[1], top_right[1], grid_size)
        X, Y = np.meshgrid(x, y)
        z = np.full_like(X, -5.0)
        xyz = np.stack((X, Y, z), axis = 2).reshape((-1, 3))
        d = np.zeros_like(xyz)
        d[:,2] = 1
        mask = mesh.ray.intersects_any(xyz, d)
        mesh.vertices = mesh.vertices @ R

        intersection_points, *_ = mesh.ray.intersects_location(xyz, d)
        offset = np.mean(intersection_points, axis = 0)

        u, s, vt = np.linalg.svd(xyz[mask,:2] - np.mean(xyz[mask,:2], axis = 0))
        if vt[0,0] * vt[1,1] - vt[0,1] * vt[1,0] < 0:
            vt[1,:] *= -1

        if np.sum((xyz[mask,:2] - np.mean(xyz[mask,:2])) @ vt[0,:] < 0) > np.sum(mask) // 2:
            vt = -vt
        return mask.reshape(X.shape).T, offset, vt
Beispiel #2
0
def mesh_and_extract_largest_connected_surface(volume, level_set):
    vertices, faces = marching_cubes(volume, level_set)
    mesh = Trimesh()
    mesh.vertices = vertices
    mesh.faces = faces
    meshes = mesh.split(only_watertight=False)
    sorted_meshes = sorted(meshes, key=lambda x: len(x.vertices))
    return sorted_meshes[-1]
Beispiel #3
0
def plot_hull_section_colours(
    hull: trimesh.Trimesh,  # type: ignore[name-defined]  # noqa
    model: Union[Literal["CAM02LCD", "CAM02SCD", "CAM02UCS", "CAM16LCD",
                         "CAM16SCD", "CAM16UCS", "CIE XYZ", "CIE xyY",
                         "CIE Lab", "CIE Luv", "CIE UCS", "CIE UVW", "DIN99",
                         "Hunter Lab", "Hunter Rdab", "ICaCb", "ICtCp", "IPT",
                         "IgPgTg", "Jzazbz", "OSA UCS", "Oklab", "hdr-CIELAB",
                         "hdr-IPT", ], str, ] = "CIE xyY",
    axis: Union[Literal["+z", "+x", "+y"], str] = "+z",
    origin: Floating = 0.5,
    normalise: Boolean = True,
    section_colours: Optional[Union[ArrayLike, str]] = None,
    section_opacity: Floating = 1,
    convert_kwargs: Optional[Dict] = None,
    samples: Integer = 256,
    **kwargs: Any,
) -> Tuple[plt.Figure, plt.Axes]:
    """
    Plot the section colours of given *trimesh* hull along given axis and
    origin.

    Parameters
    ----------
    hull
        *Trimesh* hull.
    model
        Colourspace model, see :attr:`colour.COLOURSPACE_MODELS` attribute for
        the list of supported colourspace models.
    axis
        Axis the hull section will be normal to.
    origin
        Coordinate along ``axis`` at which to plot the hull section.
    normalise
        Whether to normalise ``axis`` to the extent of the hull along it.
    section_colours
        Colours of the hull section, if ``section_colours`` is set to *RGB*,
        the colours will be computed according to the corresponding
        coordinates.
    section_opacity
        Opacity of the hull section colours.
    convert_kwargs
        Keyword arguments for the :func:`colour.convert` definition.
    samples
        Samples count on one axis when computing the hull section colours.

    Other Parameters
    ----------------
    kwargs
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.render`},
        See the documentation of the previously listed definitions.

    Returns
    -------
    :class:`tuple`
        Current figure and axes.

    Examples
    --------
    >>> from colour.models import RGB_COLOURSPACE_sRGB
    >>> from colour.utilities import is_trimesh_installed
    >>> vertices, faces, _outline = primitive_cube(1, 1, 1, 64, 64, 64)
    >>> XYZ_vertices = RGB_to_XYZ(
    ...     vertices['position'] + 0.5,
    ...     RGB_COLOURSPACE_sRGB.whitepoint,
    ...     RGB_COLOURSPACE_sRGB.whitepoint,
    ...     RGB_COLOURSPACE_sRGB.matrix_RGB_to_XYZ,
    ... )
    >>> if is_trimesh_installed:
    ...     import trimesh
    ...     hull = trimesh.Trimesh(XYZ_vertices, faces, process=False)
    ...     plot_hull_section_colours(hull, section_colours='RGB')
    ...     # doctest: +ELLIPSIS
    (<Figure size ... with 1 Axes>, <...AxesSubplot...>)

    .. image:: ../_static/Plotting_Plot_Hull_Section_Colours.png
        :align: center
        :alt: plot_hull_section_colours
    """

    axis = validate_method(
        axis,
        ["+z", "+x", "+y"],
        '"{0}" axis is invalid, it must be one of {1}!',
    )

    hull = hull.copy()

    settings: Dict[str, Any] = {"uniform": True}
    settings.update(kwargs)

    _figure, axes = artist(**settings)

    section_colours = cast(
        ArrayLike,
        optional(section_colours,
                 HEX_to_RGB(CONSTANTS_COLOUR_STYLE.colour.average)),
    )

    convert_kwargs = optional(convert_kwargs, {})

    # Luminance / Lightness reordered along "z" axis.
    with suppress_warnings(python_warnings=True):
        ijk_vertices = colourspace_model_axis_reorder(
            convert(hull.vertices, "CIE XYZ", model, **convert_kwargs), model)
        ijk_vertices = np.nan_to_num(ijk_vertices)
        ijk_vertices *= COLOURSPACE_MODELS_DOMAIN_RANGE_SCALE_1_TO_REFERENCE[
            model]

    hull.vertices = ijk_vertices

    if axis == "+x":
        index_origin = 0
    elif axis == "+y":
        index_origin = 1
    elif axis == "+z":
        index_origin = 2
    plane = MAPPING_AXIS_TO_PLANE[axis]

    section = hull_section(hull, axis, origin, normalise)

    padding = 0.1 * np.mean(
        COLOURSPACE_MODELS_DOMAIN_RANGE_SCALE_1_TO_REFERENCE[model])
    min_x = np.min(ijk_vertices[..., plane[0]]) - padding
    max_x = np.max(ijk_vertices[..., plane[0]]) + padding
    min_y = np.min(ijk_vertices[..., plane[1]]) - padding
    max_y = np.max(ijk_vertices[..., plane[1]]) + padding
    extent = (min_x, max_x, min_y, max_y)

    use_RGB_section_colours = str(section_colours).upper() == "RGB"
    if use_RGB_section_colours:
        ii, jj = np.meshgrid(
            np.linspace(min_x, max_x, samples),
            np.linspace(max_y, min_y, samples),
        )
        ij = tstack([ii, jj])
        ijk_section = full((samples, samples, 3),
                           np.median(section[..., index_origin]))
        ijk_section[..., plane] = ij
        ijk_section /= COLOURSPACE_MODELS_DOMAIN_RANGE_SCALE_1_TO_REFERENCE[
            model]
        XYZ_section = convert(
            colourspace_model_axis_reorder(ijk_section, model, "Inverse"),
            model,
            "CIE XYZ",
            **convert_kwargs,
        )
        RGB_section = XYZ_to_plotting_colourspace(XYZ_section)
    else:
        section_colours = np.hstack([section_colours, section_opacity])

    facecolor = "none" if use_RGB_section_colours else section_colours
    polygon = Polygon(
        section[..., plane],
        facecolor=facecolor,
        edgecolor="none",
        zorder=CONSTANTS_COLOUR_STYLE.zorder.background_polygon,
    )
    axes.add_patch(polygon)
    if use_RGB_section_colours:
        image = axes.imshow(
            np.clip(RGB_section, 0, 1),
            interpolation="bilinear",
            extent=extent,
            clip_path=None,
            alpha=section_opacity,
            zorder=CONSTANTS_COLOUR_STYLE.zorder.background_polygon,
        )
        image.set_clip_path(polygon)

    settings = {
        "axes": axes,
        "bounding_box": extent,
    }
    settings.update(kwargs)

    return render(**settings)
Beispiel #4
0
def plot_hull_section_contour(
    hull: trimesh.Trimesh,  # type: ignore[name-defined]  # noqa
    model: Union[Literal["CAM02LCD", "CAM02SCD", "CAM02UCS", "CAM16LCD",
                         "CAM16SCD", "CAM16UCS", "CIE XYZ", "CIE xyY",
                         "CIE Lab", "CIE Luv", "CIE UCS", "CIE UVW", "DIN99",
                         "Hunter Lab", "Hunter Rdab", "ICaCb", "ICtCp", "IPT",
                         "IgPgTg", "Jzazbz", "OSA UCS", "Oklab", "hdr-CIELAB",
                         "hdr-IPT", ], str, ] = "CIE xyY",
    axis: Union[Literal["+z", "+x", "+y"], str] = "+z",
    origin: Floating = 0.5,
    normalise: Boolean = True,
    contour_colours: Optional[Union[ArrayLike, str]] = None,
    contour_opacity: Floating = 1,
    convert_kwargs: Optional[Dict] = None,
    **kwargs: Any,
) -> Tuple[plt.Figure, plt.Axes]:
    """
    Plot the section contour of given *trimesh* hull along given axis and
    origin.

    Parameters
    ----------
    hull
        *Trimesh* hull.
    model
        Colourspace model, see :attr:`colour.COLOURSPACE_MODELS` attribute for
        the list of supported colourspace models.
    axis
        Axis the hull section will be normal to.
    origin
        Coordinate along ``axis`` at which to plot the hull section.
    normalise
        Whether to normalise ``axis`` to the extent of the hull along it.
    contour_colours
        Colours of the hull section contour, if ``contour_colours`` is set to
        *RGB*, the colours will be computed according to the corresponding
        coordinates.
    contour_opacity
        Opacity of the hull section contour.
    convert_kwargs
        Keyword arguments for the :func:`colour.convert` definition.

    Other Parameters
    ----------------
    kwargs
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.render`},
        See the documentation of the previously listed definitions.

    Returns
    -------
    :class:`tuple`
        Current figure and axes.

    Examples
    --------
    >>> from colour.models import RGB_COLOURSPACE_sRGB
    >>> from colour.utilities import is_trimesh_installed
    >>> vertices, faces, _outline = primitive_cube(1, 1, 1, 64, 64, 64)
    >>> XYZ_vertices = RGB_to_XYZ(
    ...     vertices['position'] + 0.5,
    ...     RGB_COLOURSPACE_sRGB.whitepoint,
    ...     RGB_COLOURSPACE_sRGB.whitepoint,
    ...     RGB_COLOURSPACE_sRGB.matrix_RGB_to_XYZ,
    ... )
    >>> if is_trimesh_installed:
    ...     import trimesh
    ...     hull = trimesh.Trimesh(XYZ_vertices, faces, process=False)
    ...     plot_hull_section_contour(hull, contour_colours='RGB')
    ...     # doctest: +ELLIPSIS
    (<Figure size ... with 1 Axes>, <...AxesSubplot...>)

    .. image:: ../_static/Plotting_Plot_Hull_Section_Contour.png
        :align: center
        :alt: plot_hull_section_contour
    """

    hull = hull.copy()

    contour_colours = cast(
        Union[ArrayLike, str],
        optional(contour_colours, CONSTANTS_COLOUR_STYLE.colour.dark),
    )

    settings: Dict[str, Any] = {"uniform": True}
    settings.update(kwargs)

    _figure, axes = artist(**settings)

    convert_kwargs = optional(convert_kwargs, {})

    # Luminance / Lightness is re-ordered along "z-up" axis.
    with suppress_warnings(python_warnings=True):
        ijk_vertices = colourspace_model_axis_reorder(
            convert(hull.vertices, "CIE XYZ", model, **convert_kwargs), model)
        ijk_vertices = np.nan_to_num(ijk_vertices)
        ijk_vertices *= COLOURSPACE_MODELS_DOMAIN_RANGE_SCALE_1_TO_REFERENCE[
            model]

    hull.vertices = ijk_vertices

    plane = MAPPING_AXIS_TO_PLANE[axis]

    padding = 0.1 * np.mean(
        COLOURSPACE_MODELS_DOMAIN_RANGE_SCALE_1_TO_REFERENCE[model])
    min_x = np.min(ijk_vertices[..., plane[0]]) - padding
    max_x = np.max(ijk_vertices[..., plane[0]]) + padding
    min_y = np.min(ijk_vertices[..., plane[1]]) - padding
    max_y = np.max(ijk_vertices[..., plane[1]]) + padding
    extent = (min_x, max_x, min_y, max_y)

    use_RGB_contour_colours = str(contour_colours).upper() == "RGB"
    section = hull_section(hull, axis, origin, normalise)
    if use_RGB_contour_colours:
        ijk_section = section / (
            COLOURSPACE_MODELS_DOMAIN_RANGE_SCALE_1_TO_REFERENCE[model])
        XYZ_section = convert(
            colourspace_model_axis_reorder(ijk_section, model, "Inverse"),
            model,
            "CIE XYZ",
            **convert_kwargs,
        )
        contour_colours = np.clip(XYZ_to_plotting_colourspace(XYZ_section), 0,
                                  1)

    section = np.reshape(section[..., plane], (-1, 1, 2))
    line_collection = LineCollection(
        np.concatenate([section[:-1], section[1:]], axis=1),
        colors=contour_colours,
        alpha=contour_opacity,
        zorder=CONSTANTS_COLOUR_STYLE.zorder.background_line,
    )
    axes.add_collection(line_collection)

    settings = {
        "axes": axes,
        "bounding_box": extent,
    }
    settings.update(kwargs)

    return render(**settings)
angiogram_crop = np.zeros(angiogram.shape)
angiogram_crop[15:-60, :, 150:angiogram.shape[2] - 150] = angio_top
# angiogram_crop = angiogram_crop*angiogram_HU

# # TEST (Trimesh)

for im in angiogram_crop:
    im[0, :] = 1
    im[:, 0] = 1

v, f = make_mesh(angiogram_crop[2])
v, f = remesh.subdivide(v, f)

CTmesh = Trimesh()
CTmesh.vertices = v
CTmesh.faces = f

cta_mesh = smoothing.filter_humphrey(CTmesh)

cta_voxel = cta_mesh.voxelized(1)
cta_voxel = cta_voxel.fill()

cta_voxel = cta_voxel.revoxelized(
    (angiogram_crop.shape[2], angiogram_crop.shape[1], 20 * 10))
cta_bone = cta_voxel.matrix

angiogram_test = np.zeros(
    (cta_bone.shape[2], cta_bone.shape[1], cta_bone.shape[0]))
for i in range(cta_bone.shape[2]):
    a = cta_bone[:, :, i]