我有(一堆 3D)層析資料堆疊,在這些資料中我推匯出了一個特定的(3D)坐標,我需要圍繞該坐標切出一個球形區域。
我的代碼為我生成了以下影像,該影像概述了我的作業。我根據白色虛線和綠色虛線區域計算橙色和綠色點。在這些的中點周圍,我想切出一個球形區域,它的表示現在在影像中用一個圓圈標記(也是由我的代碼繪制的)。

用原始影像構造一個球體skimage.morphology.ball并將其與原始影像相乘很容易,但是如何將球體的中心設定在影像中所需的 3D 位置?大約 30 個 3D 影像堆疊的大小不同,區域也不同,但我已經準備好所有必要的坐標以供進一步使用。
uj5u.com熱心網友回復:
你有一些半徑
r和資料索引(i,j,k)。kernel = skimage.morphology.ball(r)a = 2*r 1回傳沿每一側的掩碼/內核。它是立方體形狀的。從樹干斷層掃描儀中取出一個與內核大小一樣的立方體切片。起始索引取決于您需要中心的位置以及內核的半徑。
piece = data[i-r:i-r a, j-r:j-r a, k-r:k-r a]將二進制“球”掩碼/內核應用于切片。
piece *= kernel
uj5u.com熱心網友回復:
以下是我使用的兩種方法,它們展示了對陣列中的子區域進行“操作”(以某種方式計算值)的兩種方法。兩種不同的方法是:
因此,假設您只想計算球形區域中的值的平均值:
1 -將區域的坐標直接指定為“切片”:
data[region_coordinates].mean()
2 -使用您的陣列的掩碼版本,其中掩碼用于指定區域:data_masked.mean()
哪個可能更好取決于您可能想對該地區的價值觀做什么。兩者都可以互換使用,您可以選擇哪個使您的代碼更清晰/更容易/更快。
在我的作業中,我使用了這兩種方法,但更常見的是第一種方法(將區域指定為坐標的“切片”)。
對我來說,坐標切片方法有以下優點:
1 - 發生的事情更加明顯
2 - 如果需要,您可以更輕松地將幾何運算應用于您的“區域”。(例如旋轉、平移、縮放……)
以下是示例代碼,以及可用于任一方法的方法:
mport numpy as np
import skimage.morphology as mo
from typing import Tuple
def get_ball_coords(radius: int, center: Tuple[int]) -> Tuple[np.ndarray]:
"""
Use radius and center to return the coordinates within that 3d region
as a 'slice'.
"""
coords = np.nonzero(mo.ball(radius))
# 'coords' is a tuple of 1d arrays - to move center using pure numpy,
# first convert to a 2d array
coords_array = np.array(coords)
center_array = np.array([center]).T
# transform coordinates to be centered at 'center'
coords_array = coords_array - radius center_array
# convert coordinates back to tuple of 1d arrays, which can be used
# directly as a slice specification
coords_tuple = (
coords_array[0,:],
coords_array[1,:],
coords_array[2,:]
)
return coords_tuple
def get_masked_array(data: np.ndarray, radius: int, center: Tuple[int]) -> np.ndarray:
"""
Return a masked version of the data array, where all values are masked
except for the values within the sphere specified by radius and center.
"""
# get 'ball' as 2d array of booleans
ball = np.array(mo.ball(radius), dtype=bool)
# create full mask over entire data array
mask = np.full_like(data, True, dtype=bool)
# un-mask the 'ball' region, translated to the 'center'
mask[
center[0]-radius: center[0] radius 1,
center[1]-radius: center[1] radius 1,
center[2]-radius: center[2] radius 1
] = ~ball
# mask is now True everywhere, except inside the 'ball'
# at 'center' - create masked array version of data using this.
masked_data = np.ma.array(data=data, mask=mask)
return masked_data
# make some 3D data
data_size = (100,100,100)
data = np.random.rand(*data_size)
# define some spherical region by radius and center
region_radius = 2
region_center = (23, 41, 53)
# get coordinates of this region
region_coords = get_ball_coords(region_radius, region_center)
# get masked version of the data, based on this region
data_masked = get_masked_array(data, region_radius, region_center)
# now you can use 'region_coords' as a single 'index' (slice)
# to specify only the points with those coordinates
print('\nUSING COORDINATES:')
print('here is mean value in the region:')
print(data[region_coords].mean())
print('here is the total data mean:')
print(data.mean())
# of you can use the masked array as-is:
print('\nUSING MASKED DATA:')
print('here is mean value in the region:')
print(data_masked.mean())
print('here is the total data mean:')
print(data.mean())
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/420101.html
標籤:
