我正在嘗試在 python 中實作影像點畫演算法,并希望矢量化計算標記影像區域(Voronoi 細胞)的密度(平均亮度)。目前我可以使用回圈來做到這一點,但這對于大量區域來說計算量太大。如何矢量化此操作?
import numpy as np
from skimage import io
from scipy.interpolate import griddata
number_of_points = 1000
img = io.imread('https://www.kindpng.com/picc/m/111-1114964_house-icon-png-old-house-easy-drawing-transparent.png', as_gray=True)
height, width = img.shape
# generate random points
rng = np.random.default_rng()
points = rng.random((number_of_points,2)) * [width, height]
# calculate labelled regions
grid_x, grid_y = np.mgrid[0:width, 0:height]
labels = griddata(points, np.arange(number_of_points), (grid_x, grid_y), method='nearest')
# calculate density per region (mean of grayscale values of pixels in each region)
point_idxs = np.arange(len(points))
density = [np.mean(img[labels.T==i]) for i in point_idxs] # <-- this is the bottleneck
uj5u.com熱心網友回復:
問題不在于回圈,而在于該演算法效率不高。使用矢量化將使用大量記憶體(這很慢)并且幾乎不會加速回圈。確實,img是全讀len(point_idxs)。可以使用np.add.atand讀取一次np.bincount:
sumByLabel = np.zeros(np.max(labels) 1)
np.add.at(sumByLabel, labels.T, img)
countByLabel = np.bincount(labels.reshape(-1))
density = sumByLabel / countByLabel
這在我的機器上需要 32 毫秒,而初始代碼需要 539 毫秒(快 17 倍)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/506608.html
上一篇:RTDB查詢會減少帶寬嗎?
