distance_transform_bf#
- scipy.ndimage.distance_transform_bf(input, metric='euclidean', sampling=None, return_distances=True, return_indices=False, distances=None, indices=None)[原始碼]#
透過暴力演算法計算距離轉換函式。
此函式計算 input 的距離轉換,方法是將每個前景(非零)元素替換為其到背景(任何零值元素)的最短距離。
除了距離轉換之外,還可以計算特徵轉換。在這種情況下,會傳回一個獨立陣列,其中包含每個前景元素最接近的背景元素的索引。
- 參數:
- inputarray_like
輸入
- metric{‘euclidean’, ‘taxicab’, ‘chessboard’}, optional
‘cityblock’ 和 ‘manhattan’ 也有效,並對應到 ‘taxicab’。預設值為 ‘euclidean’。
- samplingfloat, 或 float 序列, optional
僅當 metric 為 ‘euclidean’ 時才使用此參數。沿每個維度的元素間距。如果是序列,則長度必須等於輸入的 rank;如果是單個數字,則用於所有軸。如果未指定,則表示單位網格間距。
- return_distancesbool, optional
是否計算距離轉換。預設值為 True。
- return_indicesbool, optional
是否計算特徵轉換。預設值為 False。
- distancesndarray, optional
用於儲存計算出的距離轉換的輸出陣列,而不是傳回它。return_distances 必須為 True。它必須與 input 具有相同的形狀,如果 metric 為 ‘euclidean’,則類型必須為 float64,否則為 uint32。
- indicesint32 ndarray, optional
用於儲存計算出的特徵轉換的輸出陣列,而不是傳回它。return_indicies 必須為 True。其形狀必須為
(input.ndim,) + input.shape
。
- 傳回值:
- distancesndarray, optional
計算出的距離轉換。僅當 return_distances 為 True 且未提供 distances 時傳回。它將具有與輸入陣列相同的形狀。
- indicesint32 ndarray, optional
計算出的特徵轉換。它為輸入的每個維度都有一個輸入形狀的陣列。有關範例,請參閱 distance_transform_edt 文件。僅當 return_indices 為 True 且未提供 indices 時傳回。
另請參閱
distance_transform_cdt
用於計程車和棋盤度量的更快速距離轉換
distance_transform_edt
用於歐幾里得度量的更快速距離轉換
註解
此函式採用緩慢的暴力演算法。另請參閱函式
distance_transform_cdt
以獲得更有效率的計程車 [1] 和棋盤演算法 [2]。參考文獻
[1]計程車距離。維基百科,2023 年。https://en.wikipedia.org/wiki/Taxicab_geometry
[2]棋盤距離。維基百科,2023 年。https://en.wikipedia.org/wiki/Chebyshev_distance
範例
匯入必要的模組。
>>> import numpy as np >>> from scipy.ndimage import distance_transform_bf >>> import matplotlib.pyplot as plt >>> from mpl_toolkits.axes_grid1 import ImageGrid
首先,我們建立一個玩具二元影像。
>>> def add_circle(center_x, center_y, radius, image, fillvalue=1): ... # fill circular area with 1 ... xx, yy = np.mgrid[:image.shape[0], :image.shape[1]] ... circle = (xx - center_x) ** 2 + (yy - center_y) ** 2 ... circle_shape = np.sqrt(circle) < radius ... image[circle_shape] = fillvalue ... return image >>> image = np.zeros((100, 100), dtype=np.uint8) >>> image[35:65, 20:80] = 1 >>> image = add_circle(28, 65, 10, image) >>> image = add_circle(37, 30, 10, image) >>> image = add_circle(70, 45, 20, image) >>> image = add_circle(45, 80, 10, image)
接下來,我們設定圖形。
>>> fig = plt.figure(figsize=(8, 8)) # set up the figure structure >>> grid = ImageGrid(fig, 111, nrows_ncols=(2, 2), axes_pad=(0.4, 0.3), ... label_mode="1", share_all=True, ... cbar_location="right", cbar_mode="each", ... cbar_size="7%", cbar_pad="2%") >>> for ax in grid: ... ax.axis('off') # remove axes from images
左上角的影像為原始二元影像。
>>> binary_image = grid[0].imshow(image, cmap='gray') >>> cbar_binary_image = grid.cbar_axes[0].colorbar(binary_image) >>> cbar_binary_image.set_ticks([0, 1]) >>> grid[0].set_title("Binary image: foreground in white")
距離轉換根據距離度量計算前景像素與影像背景之間的距離。
distance_transform_bf
中可用的度量為:euclidean
(預設值)、taxicab
和chessboard
。右上角的影像包含基於euclidean
度量的距離轉換。>>> distance_transform_euclidean = distance_transform_bf(image) >>> euclidean_transform = grid[1].imshow(distance_transform_euclidean, ... cmap='gray') >>> cbar_euclidean = grid.cbar_axes[1].colorbar(euclidean_transform) >>> colorbar_ticks = [0, 10, 20] >>> cbar_euclidean.set_ticks(colorbar_ticks) >>> grid[1].set_title("Euclidean distance")
左下角的影像包含使用
taxicab
度量的距離轉換。>>> distance_transform_taxicab = distance_transform_bf(image, ... metric='taxicab') >>> taxicab_transformation = grid[2].imshow(distance_transform_taxicab, ... cmap='gray') >>> cbar_taxicab = grid.cbar_axes[2].colorbar(taxicab_transformation) >>> cbar_taxicab.set_ticks(colorbar_ticks) >>> grid[2].set_title("Taxicab distance")
最後,右下角的影像包含使用
chessboard
度量的距離轉換。>>> distance_transform_cb = distance_transform_bf(image, ... metric='chessboard') >>> chessboard_transformation = grid[3].imshow(distance_transform_cb, ... cmap='gray') >>> cbar_taxicab = grid.cbar_axes[3].colorbar(chessboard_transformation) >>> cbar_taxicab.set_ticks(colorbar_ticks) >>> grid[3].set_title("Chessboard distance") >>> plt.show()