python :alpha shapes 算法检测边界点
alpha shape 算法识别
def alpha_shape_2D(data, radius):"""alpha shapes 算法检测边缘:param x: 原始点坐标集 x轴:param y: 原始点坐标集 y轴:param radius: 圆半径:return: 边缘点集"""x = data.xy = data.ycount = len(x)i = 0temp_i = iedge_x = []edge_y = []edge_len = 0while (i < count): # 遍历点集里的所有的点# 根据农机作业轨迹的特性(有一定规律的,一列一列的排列)# 筛选 以当前点为质心,边长为 4*radius 的正方形区域 内的点 ,计算这些点与当前点的连线是否构成边界i_range = np.array([t for t, v in enumerate(x < x[i] + 2 * radius) if v == True])i_range = i_range[[t for t, v in enumerate(data.loc[i_range, 'x'] > x[i] - 2 * radius) if v == True]]i_range = i_range[[t for t, v in enumerate(data.loc[i_range, 'y'] < y[i] + 2 * radius) if v == True]]i_range = i_range[[t for t, v in enumerate(data.loc[i_range, 'y'] > y[i] - 2 * radius) if v == True]]""" i_range 是可能与当前点的连线组成边界线的备选点集"""for k in i_range:# 避免重复选点(一个点不能组成三个边界线,最多只能组成两条边界)if edge_x.count(x[k]) > 0 and edge_y.count(y[k]) > 0:continue# 计算 当前点 与 备选点 的距离dis = distance((x[i], y[i]), (x[k], y[k]))# 因为当前点 和 备选点 要在一个圆上,所有距离不能大于圆直径, 或者 当前点 与 备选点 重合if dis > 2 * radius or dis == 0:continue# 当前点与备选点的连线 L 线段中点center_x = (x[k] + x[i]) * 0.5center_y = (y[k] + y[i]) * 0.5# L 的 方向向量direct_x = x[k] - x[i]direct_y = y[k] - y[i]# L 的 法向量K 及其单位化nomal_x = -direct_y / ma.sqrt(pow(direct_x, 2) + pow(direct_y, 2))nomal_y = direct_x / ma.sqrt(pow(direct_x, 2) + pow(direct_y, 2))# 圆心到直线L 距离disOfcenter = ma.sqrt(pow(radius, 2) - 0.25 * pow(dis, 2))if nomal_x != 0:a = ma.sqrt(pow(disOfcenter, 2) / (1 + pow(nomal_y / nomal_x, 2)))b = a * (nomal_y / nomal_x)else:a = 0b = radius# 圆心 坐标cicle1_x = center_x + acicle1_y = center_y + bcicle2_x = center_x - acicle2_y = center_y - b# 检测圆内是否有其他点b1 = Falseb2 = False# 筛选以圆心R1为质点,边长为 2*radius 的方形区域内的点集inSquare = np.array([t for t, v in enumerate(x < cicle1_x + radius) if v == True])inSquare = inSquare[[t for t, v in enumerate(data.loc[inSquare, 'x'] > cicle1_x - radius) if v == True]]inSquare = inSquare[[t for t, v in enumerate(data.loc[inSquare, 'y'] < cicle1_y + radius) if v == True]]inSquare = inSquare[[t for t, v in enumerate(data.loc[inSquare, 'y'] > cicle1_y - radius) if v == True]]if len(inSquare) != 0:for j in inSquare:if j == i or j == k: # 点集内的点 除去当前点i 和 备选点kcontinueelse:d = distance((x[j], y[j]), (cicle1_x, cicle1_y)) # 计算备选点k与点集内的点的距离if d <= radius: # 圆内有点 ,跳过b1 = Truebreak# 筛选 圆R2inSquare = np.array([t for t, v in enumerate(x < cicle2_x + radius) if v == True])inSquare = inSquare[[t for t, v in enumerate(data.loc[inSquare, 'x'] > cicle2_x - radius) if v == True]]inSquare = inSquare[[t for t, v in enumerate(data.loc[inSquare, 'y'] < cicle2_y + radius) if v == True]]inSquare = inSquare[[t for t, v in enumerate(data.loc[inSquare, 'y'] > cicle2_y - radius) if v == True]]if len(inSquare) != 0:for j in inSquare: # 与原两个点的坐标点一样if j == i or j == k or distance((x[j], y[j]), (x[i], y[i])) == 0:continueelse:d = distance((x[j], y[j]), (cicle2_x, cicle2_y))if d <= radius: # 圆内有点 ,跳过b2 = Truebreak# 圆1 或 圆2 内没有其他的点,则备选点k是边界点if b1 == False or b2 == False:if edge_x.count(x[i]) < 1 or edge_y.count(y[i]) < 1: # 当前点未加入边界点集edge_x.append(x[i])edge_y.append(y[i])edge.append(i)if edge_x.count(x[k]) < 1 or edge_y.count(y[k]) < 1: # 备选点k已未加入边界点集edge_x.append(x[k])edge_y.append(y[k])edge.append(k)temp_k = kbreakif edge_len < len(edge_x): # 跳转到新的边界点temp_i = ii = temp_kedge_len = len(edge_x)else:temp_i = ii = i + 1edge_x.append(edge_x[0])edge_y.append(edge_y[0])return edge_x, edge_y
计算两点之间的距离函数
def distance(a, b):"""计算a,b两点的直线距离:param a: a点坐标(大地坐标 m):param b: b点坐标(大地坐标 m):return: dis 直线距离"""p1 = np.array(a)p2 = np.array(b)dis = ma.sqrt(sum(np.power(p2 - p1, 2)))return dis
程序入口
import numpy as np
import pandas as pda
import math as ma
import matplotlib.pyplot as pltpath='你的点集文件路径'
data = pda.read_excel(path)
edge_x, edge_y = alpha_shape_2D(data, 6.625)i = 0
while i < len(edge_x):plt.text(edge_x[i], edge_y[i], i, ha='center', va='bottom', fontsize=11, color='b')i += 1# 画出点集 及 边界线
plt.plot(data.x, data.y, 'bo-', color='k', linewidth=1, markersize=2)
plt.plot(edge_x, edge_y, '*-', color='r', markersize=6)plt.axis('off')
plt.show()
效果图:
想要我的测试点集的可以去百度网盘下载,这里放不了
链接:https://pan.baidu.com/s/19SzVnvBJgGVn_OQElesF5Q
提取码:nal3
如果我的代码对你有帮助,就给我点个赞吧
说明: 本文所用方法都来自于网络查找,本文借鉴了一下其他博主的文章,在他的基础上实现了Alpha Shapes算法.然后写了一个Alpha Shapes演示程序. Alpha Shapes演示程序下载 ... alpha shape算法又称为滚球法,是一种提取边界点的算法.跟凸壳提取相比,alpha shape算法能够了凹包情形,且对多个点云时 能勾勒出多个边界线,这是他的优势. 研究alpha shape ... 由Edelsbrunner H提出的alpha shapes算法是一种简单.有效的快速提取边界点算法.其克服了点云边界点形状影响的缺点,可快速准确提取边界点,其原理如下: 如下图所示,对于任意形状的平 ... Alpha Shapes算法介绍 计算几何中Alpha Shqpes描述欧氏平面有限点集形状的一组分段线性的简单曲线.Alpha Shqpes可以用来从一堆无序的点集中提取边缘,其本质是滚球法,通过控 ... Python+opencv 机器视觉 - 基于霍夫圈变换算法检测图像中的圆形实例演示 第一章:霍夫变换检测圆 ① 实例演示1 ② 实例演示2 ③ 霍夫变换函数解析 第二章:Python + openc ... python数据结构和算法 参考 本文github 计算机科学是解决问题的研究.计算机科学使用抽象作为表示过程和数据的工具.抽象的数据类型允许程序员通过隐藏数据的细节来管理问题领域的复杂性.Pytho ... Python:实现费马检测算法 def bin_exp_mod(a, n, b):# mod bassert not (b == 0), "This cannot accept modulo ... 用 Python 实现哈希算法检测重复图片 - 简书 Python实现哈希算法,并检测图片重复的教程_Steven_ycs的博客-CSDN博客_python实现哈希 python:实现哈里斯角检测|Harris Corner算法 import cv2 import numpy as npclass Harris_Corner:def __init__(self, ... Python:SMOTE算法 直接用python的库, imbalanced-learn imbalanced-learn is a python package offering a number ...python :alpha shapes 算法检测边界点相关推荐
最新文章
热门文章