Python中多曲线信号起止点的精准识别方案咨询:现有方法在失真信号下失效
Hey there! I’ve run into this exact problem before—segmenting curves with distorted signals and non-flat baselines can be tricky when relying on simple percentage change checks. Let’s go through some more robust approaches that should handle these edge cases better.
1. Leverage Gradients (First Derivatives) for Edge Detection
Curves start when the signal transitions from a flat baseline to a rising slope, and end when it transitions back to the baseline. Calculating the first derivative of your signal makes these transitions easy to spot, even with baseline drift.
Here’s a modified function using gradients:
import numpy as np def find_start_gradient(peak, left_limit, signal, grad_threshold=0.05): # Compute the first derivative of the signal signal_grad = np.gradient(signal) # Move left from the peak until we hit the baseline (low gradient) for i in range(peak, left_limit, -1): if abs(signal_grad[i]) < grad_threshold: # Now move right to find the first point where the slope picks up (start of the curve) for j in range(i, peak): if abs(signal_grad[j]) > grad_threshold: return j return -1 # Similar logic for finding endpoints: def find_end_gradient(peak, right_limit, signal, grad_threshold=0.05): signal_grad = np.gradient(signal) for i in range(peak, right_limit): if abs(signal_grad[i]) < grad_threshold: for j in range(peak, i): if abs(signal_grad[j]) < grad_threshold: return j return -1
You can adjust grad_threshold based on your signal’s noise level—lower values work for cleaner signals, higher values for noisier ones.
2. Correct Baseline Drift First
If your baseline isn’t a flat line, fixing it before detecting start/end points will simplify everything. A common method is using a rolling mean to estimate the baseline, then subtracting it from your original signal.
Example code for baseline correction:
import pandas as pd def correct_baseline(signal, window_size=50): # Use a rolling window mean to approximate the baseline baseline = pd.Series(signal).rolling(window=window_size, center=True).mean() # Fill in missing values at the start/end baseline = baseline.fillna(method="bfill").fillna(method="ffill") # Return the corrected signal and baseline return signal - baseline.values, baseline.values # Apply correction to your signal corrected_signal, _ = correct_baseline(your_original_signal)
Once you have the corrected signal, you can detect start/end points by looking for where the corrected signal crosses a small threshold (e.g., 2% of the peak’s value):
def find_start_corrected(peak, left_limit, corrected_signal, peak_value): threshold = 0.02 * peak_value # Adjust percentage as needed for i in range(peak, left_limit, -1): if corrected_signal[i] < threshold: for j in range(i, peak): if corrected_signal[j] >= threshold: return j return -1
3. Use Scipy’s Peak Prominence & Width Tools
You’re already using scipy.signal.find_peaks—did you know it has companion functions that can directly give you the "foot" of each peak (which is exactly your start/end points)?
Try peak_prominences and peak_widths:
from scipy.signal import find_peaks, peak_prominences, peak_widths # First find your peaks as before peaks, _ = find_peaks(your_original_signal) # Calculate prominence and left/right baseline points for each peak prominences, left_bases, right_bases = peak_prominences(your_original_signal, peaks) # left_bases = starting points of each curve (where it rises from baseline) # right_bases = ending points of each curve (where it falls back to baseline)
This method is great because it’s designed to handle non-flat baselines and automatically finds the points where the curve deviates from the baseline. You can tweak the prominence parameter in find_peaks to make this more or less sensitive.
4. Adaptive Thresholding (For Noisy/Distorted Signals)
If your signal has extreme distortion, try using local statistics (like local standard deviation) to set adaptive thresholds. For example, you can calculate the standard deviation of a small window around each point to determine if it’s part of the baseline or the curve.
Final Recommendation
Start with baseline correction + peak prominence—this combo handles most non-flat baseline and distortion cases out of the box. If you still have issues, add gradient checks to refine the start/end points further.
内容的提问来源于stack exchange,提问作者Aditya

