用区域内最接近的值填充图像
Fill image with nearest value within region
我想用圆圈内最接近的值填充圆形区域外的图像。效果类似于 skimage 的 mode='edge' 但应用于图像的圆形区域而不是矩形区域。
做正确事情的简单代码 - 非常慢:
def circle_pad(img, xc, yc, r):
img_out = img.copy()
for i in range(img.shape[0]):
for j in range(img.shape[1]):
d = math.sqrt( (i-yc)**2 + (j-xc)**2 )
if d > r:
i1, j1 = int( yc + (i-yc)*(r/d) ), int( xc + (j-xc)*(r/d) )
img_out[i,j] = img[i1,j1]
return img_out
如何使用 numpy 加快速度? (可能避免在 python 代码中遍历每个像素;典型图像是数千万像素)
我想过使用类似 meshgrid 的东西作为起点来计算每个点要填充的值的坐标,但具体方法不清楚。
已使用 mgrid 解决 - 不漂亮但非常快。以防万一它可以作为其他有类似图像处理问题的人的例子:
def circle_pad(img, xc, yc, r):
mg = np.mgrid[:img.shape[0],0:img.shape[1]]
yi, xi = mg[0,:,:], mg[1,:,:]
mask = ((yi-yc)**2 + (xi-xc)**2) < r**2
d = np.sqrt( (yi-yc)**2 + (xi-xc)**2 )
d = np.clip(d, r, None)
ye = yc + (yi-yc)*(r/d)
xe = xc + (xi-xc)*(r/d)
ye = np.clip(ye.astype(int), 0, img.shape[0])
xe = np.clip(xe.astype(int), 0, img.shape[1])
img_out = img * mask + img[ye,xe] * (~mask)
return img_out
关键部分是:
- 创建一个类似网格的索引数组
xi, yi
和 np.mgrid
- 每个都与图像具有相同的大小
- 通过对 xi, yi
进行数学计算,计算最近边缘像素的坐标数组 xe, ye
- 通过下标替换值,如下所示:
img[ye,xe]
我想用圆圈内最接近的值填充圆形区域外的图像。效果类似于 skimage 的 mode='edge' 但应用于图像的圆形区域而不是矩形区域。
做正确事情的简单代码 - 非常慢:
def circle_pad(img, xc, yc, r):
img_out = img.copy()
for i in range(img.shape[0]):
for j in range(img.shape[1]):
d = math.sqrt( (i-yc)**2 + (j-xc)**2 )
if d > r:
i1, j1 = int( yc + (i-yc)*(r/d) ), int( xc + (j-xc)*(r/d) )
img_out[i,j] = img[i1,j1]
return img_out
如何使用 numpy 加快速度? (可能避免在 python 代码中遍历每个像素;典型图像是数千万像素)
我想过使用类似 meshgrid 的东西作为起点来计算每个点要填充的值的坐标,但具体方法不清楚。
已使用 mgrid 解决 - 不漂亮但非常快。以防万一它可以作为其他有类似图像处理问题的人的例子:
def circle_pad(img, xc, yc, r):
mg = np.mgrid[:img.shape[0],0:img.shape[1]]
yi, xi = mg[0,:,:], mg[1,:,:]
mask = ((yi-yc)**2 + (xi-xc)**2) < r**2
d = np.sqrt( (yi-yc)**2 + (xi-xc)**2 )
d = np.clip(d, r, None)
ye = yc + (yi-yc)*(r/d)
xe = xc + (xi-xc)*(r/d)
ye = np.clip(ye.astype(int), 0, img.shape[0])
xe = np.clip(xe.astype(int), 0, img.shape[1])
img_out = img * mask + img[ye,xe] * (~mask)
return img_out
关键部分是:
- 创建一个类似网格的索引数组
xi, yi
和np.mgrid
- 每个都与图像具有相同的大小 - 通过对 xi, yi 进行数学计算,计算最近边缘像素的坐标数组
- 通过下标替换值,如下所示:
img[ye,xe]
xe, ye