python – 如何从任意方向的2D数组中提取1d轮廓(具有集成宽度)

python – 如何从任意方向的2D数组中提取1d轮廓(具有集成宽度),第1张

概述我有以下问题:我想从2D数组中提取一维配置文件,这是相对简单的.并且在任意方向上也很容易做到这一点(见 here). 但我想给轮廓一定的宽度,以便垂直于轮廓的值被平均.我设法做到了这一点,但速度非常慢. 有人有一个很好的解决方案吗? 谢谢! import numpy as npimport osimport mathimport itertoolsimport matplotlib.pyp 我有以下问题:我想从2D数组中提取一维配置文件,这是相对简单的.并且在任意方向上也很容易做到这一点(见 here).

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

谢谢!

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轮廓(具有集成宽度)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1197592.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存