-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature suggestion: Function that places a structuring element in an array around a given index. #6122
Comments
Hi @kolibril13, and thanks for your interest! I see the utility of such a function, but I'm not sure about the API. I think this sort of belongs with |
Prior conversations moved back to issues from Discussions
draw.structuring_element(footprint, *, position=None, shape=None, out=None):
"""Draw a structuring element.
Parameters
----------
footprint: ndarray
A structuring element.
position: array_like, optional
The position of the structuring element in the output image. The center
of the output image by default.
shape: array_like, optional
The shape of the output image. Same as footprint by default.
out: ndarray, optional
An array where footprint must be drawn.
"""
import numpy as np
import matplotlib.pyplot as plt
from skimage.morphology import ball
def structuring_element(array, structure, position=None, alignment_to_index="center"):
"""Draw a structuring element.
Parameters
----------
array: ndarray
An array where the structuring element will be placed.
structure: ndarray
A structuring element.
position: array_like, optional
The position of the structuring element in the output image.
When no position is given, the stucuting element will be drawn in the center of the array.
If one or more array axis haven an even count of total elements and therefore no integer as center index,
the center index is rounded up to the next integer.
alignment_to_index: string, optional
Can be either "center" or "corner".
"""
if position == None:
i, j, k = array.shape
position = np.array([int(np.ceil(i / 2)), int(np.ceil(j / 2)), int(np.ceil(k / 2))])
x = position[0]
y = position[1]
z = position[2]
strulen_x = structure.shape[0]
strulen_y = structure.shape[1]
strulen_z = structure.shape[2]
if alignment_to_index == "center":
halfxA = int(np.ceil(strulen_x / 2))
halfxB = int(np.floor(strulen_x / 2))
halfyA = int(np.ceil(strulen_y / 2))
halfyB = int(np.floor(strulen_y / 2))
halfzA = int(np.ceil(strulen_z / 2))
halfzB = int(np.floor(strulen_z / 2))
array[
x - halfxA : x + halfxB, y - halfyA : y + halfyB, z - halfzA : z + halfzB
] = structure
if alignment_to_index == "corner":
array[x : x + strulen_x, y : y + strulen_y, z : z + strulen_z] = structure
return array
voxelarray = np.full((25, 25, 25), 0)
voxelarray = structuring_element(voxelarray, ball(7))
voxelarray = structuring_element(voxelarray, ball(2), position=[3, 20, 20], alignment_to_index="center")
voxelarray = structuring_element(voxelarray, ball(1), position=[0, 0, 0], alignment_to_index="corner")
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(1, 1, 1, projection="3d")
ax.view_init(10, 200)
ax.voxels(voxelarray, edgecolor="k")
plt.show()
voxelarray = np.zeros((25, 25, 25))
voxelarray = structuring_element(footprint= ball(3), out= voxelarray) would be the same as voxelarray = structuring_element(footprint= ball(3), shape = (25, 25, 25))
|
The variety of structuring elements in scikit-image is quite amazing:
https://scikit-image.org/docs/dev/auto_examples/numpy_operations/plot_structuring_elements.html#generate-structuring-elements
However, when one wants to place them into a numpy array at a certain position, one has to do something like this, which is really cumbersome code:
and one (at least me 😉 ) gets lots of error messages like
ValueError: could not broadcast input array from shape (5,5,5) into shape (4,4,4)
This could be solved by a function like
place_structuring_element
.Here is a proof of concept:
The proof of concept is really only a quick draft, and one could add things like if the alignment to this anchor index should be at the CENTER, TOP, RIGHT, UPLEFT etc.
I just wanted to share this idea and ask if scikit-image might be interested in a function like this.
The text was updated successfully, but these errors were encountered: