gpt4 book ai didi

python - 如何从任意方向的二维数组中提取一维轮廓(具有集成宽度)

转载 作者:太空宇宙 更新时间:2023-11-03 11:24:34 24 4
gpt4 key购买 nike

我有以下问题:我想从二维数组中提取一维轮廓,这比较简单。而且在任意方向上也很容易做到这一点(参见 here )。

但我想给轮廓一定的宽度,以便垂直于轮廓的值被平均。我设法做到了这一点,但速度非常慢。有人对此有好的解决方案吗?

谢谢!

import numpy as np
import os
import math
import itertools
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon

def closest_point(points, coords):
min_distances = []
coords = coords
for point in points:
distances = []
for coord in coords:
distances.append(np.sqrt((point[0]-coord[0])**2 + (point[1]-coord[1])**2))

val, idx = min((val, idx) for (idx, val) in enumerate(distances))
min_distances.append(coords[idx])
return min_distances

def rect_profile(x0, y0, x1, y1, width):

xd=x1-x0
yd=y1-y0
alpha = (np.angle(xd+1j*yd))

y00 = y0 - np.cos(math.pi - alpha)*width
x00 = x0 - np.sin(math.pi - alpha)*width

y01 = y0 + np.cos(math.pi - alpha)*width
x01 = x0 + np.sin(math.pi - alpha)*width

y10 = y1 + np.cos(math.pi - alpha)*width
x10 = x1 + np.sin(math.pi - alpha)*width

y11 = y1 - np.cos(math.pi - alpha)*width
x11 = x1 - np.sin(math.pi - alpha)*width

vertices = ((y00, x00), (y01, x01), (y10, x10), (y11, x11))
poly_points = [x00, x01, x10, x11], [y00, y01, y10, y11]
poly = Polygon(((y00, x00), (y01, x01), (y10, x10), (y11, x11)))

return poly, poly_points

def averaged_profile(image, x0, y0, x1, y1, width):
num = np.sqrt((x1-x0)**2 + (y1-y0)**2)
x, y = np.linspace(x0, x1, num), np.linspace(y0, y1, num)
coords = list(zip(x, y))

# Get all points that are in Rectangle
poly, poly_points = rect_profile(x0, y0, x1, y1, width)
points_in_poly = []
for point in itertools.product(range(image.shape[0]), range(image.shape[1])):
if poly.get_path().contains_point(point, radius=1) == True:
points_in_poly.append((point[1], point[0]))

# Finds closest point on line for each point in poly
neighbour = closest_point(points_in_poly, coords)

# Add all phase values corresponding to closest point on line
data = []
for i in range(len(coords)):
data.append([])

for idx in enumerate(points_in_poly):
index = coords.index(neighbour[idx[0]])
data[index].append(image[idx[1][1], idx[1][0]])

# Average data perpendicular to profile
for i in enumerate(data):
data[i[0]] = np.nanmean(data[i[0]])

# Plot
fig, axes = plt.subplots(figsize=(10, 5), nrows=1, ncols=2)

axes[0].imshow(image)
axes[0].plot([poly_points[0][0], poly_points[0][1]], [poly_points[1][0], poly_points[1][1]], 'yellow')
axes[0].plot([poly_points[0][1], poly_points[0][2]], [poly_points[1][1], poly_points[1][2]], 'yellow')
axes[0].plot([poly_points[0][2], poly_points[0][3]], [poly_points[1][2], poly_points[1][3]], 'yellow')
axes[0].plot([poly_points[0][3], poly_points[0][0]], [poly_points[1][3], poly_points[1][0]], 'yellow')
axes[0].axis('image')
axes[1].plot(data)
return data

from scipy.misc import face
img = face(gray=True)
profile = averaged_profile(img, 10, 10, 500, 500, 10)

最佳答案

作为另一种选择,现在有一个 scipy 测量函数可以做到这一点(获取二维数组中任意点之间的轮廓,指定可选宽度):skimage.measure.profile_line .

作为一大优点,它还允许您指定用于离网位置的插值。

虽然我不确定它与上面的代码相比如何 - 我知道对于正交情况,使用简单的数组切片/求和要很多更快(即数量级或更多)。

就像 heltonbiker 所说的那样,如果您真的需要速度(大阵列和/或多次),首先旋转矩阵会更快,然后使用切片。我过去使用的一种技术基本上是他的方法,但也首先实质上屏蔽了原始未旋转的数组,然后仅旋转数组中与您的配置文件区域大小相同的部分(加上一点)。

这种方法(对于速度)的缺点是,对于旋转,您需要使用某种形式的插值,这通常很慢,并且要获得准确的结果,您至少需要线性(1 阶)插值。然而,大多数用于数组旋转的 python 库模块(至少有 3 个)似乎都经过了相当优化。

...然而,为了纯粹的方便,profile_line 是要走的路

关于python - 如何从任意方向的二维数组中提取一维轮廓(具有集成宽度),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36712578/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com