如何分离scipy find_peaks检测到的条纹并存储至文本文件
如何分离scipy find_peaks检测到的条纹并存储至文本文件
看起来你现在的核心问题是:用find_peaks检测到所有峰值点后,没法区分出那些独立的条纹曲线,而是把所有点混在了一起。我来帮你一步步解决这个问题,先修正原代码的bug,再实现条纹分组逻辑,最后把每个条纹的数据保存到文件里。
先修正原代码的致命错误
你写的代码里有个严重的缩进问题:if peaks.size > 0这部分是在for循环外面的,这会导致程序只处理最后一行的峰值,前面所有行的检测结果都被忽略了!首先得把这个if块缩进,放到for循环内部,和peaks检测的代码对齐。
核心思路:按行匹配峰值,分组条纹
条纹是连续的曲线,上下相邻行中属于同一条纹的峰值坐标肯定会很接近。基于这个特点,我们可以:
- 按行收集每一行的所有峰值坐标,记录每行的峰值列表
- 从第一行开始,把每个峰值作为一个新条纹的起点
- 逐行往下,把当前行的每个峰值和上一行的峰值计算距离,把距离最近的峰值归为同一条纹(设置一个距离阈值来判断)
- 最后把每个独立条纹的坐标单独保存
完整可运行代码
import numpy as np from scipy.signal import find_peaks import matplotlib.pyplot as plt # 加载你的数据 X = np.load('X.npy') Y = np.load('Y.npy') P_new = np.load('P_new.npy') T = np.real(P_new) # 提取2D矩阵的实部作为处理对象 # 绘制原始图像确认数据 plt.figure() plt.imshow(T, cmap='jet', aspect='auto') plt.colorbar() plt.title('Original Image') plt.show() # 峰值检测参数(可根据你的数据微调) min_peak_dist = 3 # 同一行内峰值的最小间距 min_peak_h = 3e-5 # 峰值的最小高度阈值 # -------------------------- # 第一步:按行收集所有峰值坐标(修正缩进错误) # -------------------------- row_peak_coords = [] # 每个元素是该行的峰值坐标列表:[(x1,y1), (x2,y2), ...] for k in range(T.shape[0]): current_row = T[k, :] peaks, _ = find_peaks(current_row, distance=min_peak_dist, height=min_peak_h) if peaks.size > 0: # 把当前行的峰值转换成(X,Y)真实坐标 current_peaks = [(X[k, p], Y[k, p]) for p in peaks] row_peak_coords.append(current_peaks) else: # 该行没有检测到峰值,添加空列表占位 row_peak_coords.append([]) # -------------------------- # 第二步:将峰值分组到不同的条纹 # -------------------------- stripes = [] # 每个元素是一条条纹的坐标列表 # 初始化:第一行的每个峰值对应一个新条纹 if row_peak_coords[0]: for peak in row_peak_coords[0]: stripes.append([peak]) # 从第二行开始,匹配上一行的峰值,分配到对应条纹 distance_threshold = 5 # 同一条纹上下行峰值的最大距离阈值,可根据数据调整 for k in range(1, len(row_peak_coords)): current_peaks = row_peak_coords[k] prev_peaks = row_peak_coords[k-1] if not current_peaks: continue # 当前行无峰值,直接跳过 if not prev_peaks: # 上一行没有峰值,当前行的每个峰值作为新条纹的起点 for peak in current_peaks: stripes.append([peak]) continue # 计算当前行每个峰值与上一行所有峰值的欧氏距离,找到最近的匹配 current_to_stripe = [] for curr_p in current_peaks: distances = [np.linalg.norm(np.array(curr_p) - np.array(prev_p)) for prev_p in prev_peaks] closest_idx = np.argmin(distances) if distances[closest_idx] < distance_threshold: # 距离足够近,归为同一条纹 current_to_stripe.append(closest_idx) else: # 距离太远,作为新条纹 current_to_stripe.append(len(stripes)) stripes.append([curr_p]) # 把当前行的峰值添加到对应条纹中 for idx, stripe_idx in enumerate(current_to_stripe): stripes[stripe_idx].append(current_peaks[idx]) # -------------------------- # 第三步:可视化分离后的条纹 # -------------------------- plt.figure(figsize=(10,6)) colors = plt.cm.rainbow(np.linspace(0, 1, len(stripes))) for i, stripe in enumerate(stripes): stripe_x = [p[0] for p in stripe] stripe_y = [p[1] for p in stripe] plt.scatter(stripe_x, stripe_y, color=colors[i], s=2, label=f'Stripe {i+1}') plt.xlabel('X Coordinate') plt.ylabel('Y Coordinate') plt.title('Separated Individual Fringes') plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', fontsize='small') plt.tight_layout() plt.show() # -------------------------- # 第四步:保存条纹数据到文本文件 # -------------------------- # 方式1:每个条纹保存到单独的文本文件 for i, stripe in enumerate(stripes): stripe_array = np.array(stripe) # 保存为带表头的文本文件,格式为X Y np.savetxt(f'stripe_{i+1}.txt', stripe_array, header='X Y', fmt='%.6f', comments='') print(f"✅ 条纹 {i+1} 已保存到 stripe_{i+1}.txt") # 方式2:所有条纹保存到一个文件,用空行分隔不同条纹 with open('all_stripes.txt', 'w') as f: f.write('# All separated fringes (empty line separates different stripes)\n') f.write('# X Coordinate Y Coordinate\n') for stripe in stripes: for (x, y) in stripe: f.write(f'{x:.6f} {y:.6f}\n') f.write('\n') # 空行分隔不同条纹 print("✅ 所有条纹已保存到 all_stripes.txt")
关键细节说明
- 距离阈值调整:
distance_threshold是判断上下行峰值是否属于同一条纹的关键,如果你的条纹间距比较大,就把这个值调大一点,反之调小。 - 边界情况处理:代码会自动处理某行无峰值、条纹新增/结束的情况,比如某一行突然多了一个峰值,会自动作为新条纹的起点。
- 保存方式:提供了两种保存方案,你可以根据后续处理需求选择——单个文件对应单条纹,或者一个文件集中存储所有条纹。
备注:内容来源于stack exchange,提问作者wosker4yan
相关产品推荐
相关产品推荐

