但我想给轮廓一定的宽度,以便垂直于轮廓的值被平均.我设法做到了这一点,但速度非常慢.
有人有一个很好的解决方案吗?
谢谢!
import numpy as npimport osimport mathimport itertoolsimport matplotlib.pyplot as pltfrom matplotlib.patches import polygondef 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_distancesdef 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,x11))) return poly,poly_pointsdef averaged_profile(image,x0,wIDth): num = np.sqrt((x1-x0)**2 + (y1-y0)**2) x,y = np.linspace(x0,num),np.linspace(y0,num) coords = List(zip(x,y)) # Get all points that are in Rectangle poly,poly_points = rect_profile(x0,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 datafrom scipy.misc import faceimg = face(gray=True)profile = averaged_profile(img,10,500,10)解决方法 主要的性能值是函数nearest_point.使用矩形中的所有点计算线上所有点之间的距离非常慢.
通过将所有矩形点投影到线上,可以大大加快功能.投影点是线上最近的点,因此无需计算所有距离.此外,通过正确地标准化和舍入投影(距线开始的距离),它可以直接用作索引.
def closest_point(points,y1): line_direction = np.array([x1 - x0,y1 - y0],dtype=float) line_length = np.sqrt(line_direction[0]**2 + line_direction[1]**2) line_direction /= line_length n_bins = int(np.ceil(line_length)) # project points on line projections = np.array([(p[0] * line_direction[0] + p[1] * line_direction[1]) for p in points]) # normalize projections so that they can be directly used as indices projections -= np.min(projections) projections *= (n_bins - 1) / np.max(projections) return np.floor(projections).astype(int),n_bins
如果你想知道括号内的奇怪 – 这些是list comprehensions.
在averaged_profile中使用这样的函数:
#...# Finds closest point on line for each point in polyneighbours,n_bins = closest_point(points_in_poly,y1)# Add all phase values corresponding to closest point on linedata = [[] for _ in range(n_bins)]for IDx in enumerate(points_in_poly): index = neighbours[IDx[0]] data[index].append(image[IDx[1][1],IDx[1][0]])#...
这种优化将使计算速度明显加快.如果它对您来说仍然太慢,您还可以优化在多边形内找到点的方式.不是测试图像中的每个点是否在矩形内,您可以使用多边形光栅化算法直接生成坐标.有关详情,请参阅here.
最后,虽然它不是性能问题,但使用复数计算角度非常有创意:)
除了三角函数,您可以使用线的法线向量是[yd,-xd]除以线长度的事实:
def rect_profile(x0,wIDth): xd = x1 - x0 yd = y1 - y0 length = np.sqrt(xd**2 + yd**2) y00 = y0 + xd * wIDth / length x00 = x0 - xd * wIDth / length y01 = y0 - xd * wIDth / length x01 = x0 + xd * wIDth / length y10 = y1 - xd * wIDth / length x10 = x1 + xd * wIDth / length y11 = y1 + xd * wIDth / length x11 = x1 - xd * wIDth / length poly_points = [x00,poly_points总结
以上是内存溢出为你收集整理的python – 如何从任意方向的2D数组中提取1d轮廓(具有集成宽度)全部内容,希望文章能够帮你解决python – 如何从任意方向的2D数组中提取1d轮廓(具有集成宽度)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)