如何在距离场二维数组中提取谷线及交点线段?
问题描述
我有一个代表高度的二维数组,数组包含峰值,峰值间为线性梯度——数组是根据峰值位置生成的,梯度值等于到最近峰值的距离,实际数组分辨率高于附图。我需要找到谷线及其交点,并将它们以线段集合的形式呈现,同时获取交点的实际深度值。我尝试过多种极小值查找方法,但无法准确定位精确的交点和连续的谷线段。
已尝试的方法
方法1:使用scipy.ndimage.minimum_filter
最初尝试用形态学滤波识别极小值,但得到的谷线零散,无法形成连续线段:
import scipy.ndimage import numpy as np minima = (arr != scipy.ndimage.minimum_filter(arr, size=10, mode='constant', cval=0.0)) modified_arr = np.where(minima, arr, 1500)
方法2:基于峰值距离差的遍历识别
从数学定义出发(交点是与三个峰值等距的点,谷线是与两个峰值等距的点),遍历每个点计算到各峰值的距离差,筛选符合条件的点:
from math import hypot max_int_diff = 0.85 # 交点距离差阈值 max_valley_diff = 0.45 # 谷线距离差阈值 max_edge_dist = 2 # 图边缘判定距离 intersections = [] valleys = [] array_size = arr.shape[0] # 假设数组为正方形 for i in range(arr.shape[1]): for j in range(arr.shape[0]): dists = [(hypot((i - node.x), (j - node.y)), node) for node in peaks.values()] closest = sorted(dists, key=lambda _x: _x[0]) # 判断是否为交点 diff_1_2 = abs(closest[0][0] - closest[1][0]) diff_1_3 = abs(closest[0][0] - closest[2][0]) diff_2_3 = abs(closest[1][0] - closest[2][0]) if diff_1_3 <= max_int_diff and diff_2_3 <= max_int_diff and diff_1_2 <= max_int_diff: intersections.append((i, j)) # 图边缘的谷线视为交点 elif diff_1_2 <= max_valley_diff \ and (i <= max_edge_dist or i >= array_size - max_edge_dist or j <= max_edge_dist or j >= array_size - max_edge_dist): intersections.append((i, j)) # 判断是否为谷线点 elif diff_1_2 <= max_valley_diff: valleys.append((i, j))
该方法能定位所有目标点,但存在冗余点,需要调整阈值参数;计划用K-means聚类获取交点质心,基于交点角度筛选谷线点。
方法3:单轴结合minimum_filter
针对单轴方向做极小值滤波,合并结果以补全谷线,但仍有部分缺失,考虑添加45度轴的过滤:
import scipy.ndimage import numpy as np # 分别对x、y轴方向做极小值滤波 minima_0 = (arr != scipy.ndimage.minimum_filter(arr, axes=0, size=10, mode='constant', cval=20.0)) minima_1 = (arr != scipy.ndimage.minimum_filter(arr, axes=1, size=10, mode='constant', cval=20.0)) # 生成标记后的数组 arr_0 = np.where(minima_0, arr, 50) arr_1 = np.where(minima_1, arr, 50) mg = arr_0 + arr_1
思路转变
后续意识到将问题视为图像处理问题过于复杂,核心是数学问题,现已发布解决方案。
内容的提问来源于stack exchange,提问作者LangerNZ
相关产品推荐
相关产品推荐

