You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过高速相机视频测量物体振动?基于帧位移的实现方案

视频振动测量技术方案(Python实现)

一、从帧间位移数据计算振动频率

你已经通过2D FFT得到了帧间的x/y轴位移序列,接下来通过以下步骤将位移数据转化为振动频率:

1. 构建位移-时间序列

首先明确视频的实际帧率fps,每帧的时间间隔为1/fps秒。假设你有N个位移数据(对应N+1帧视频),则时间戳数组可通过以下代码生成:

import numpy as np
fps = 30  # 替换为你的视频实际帧率
displacement_y = [y1, y2, ..., yN]  # 你的y轴位移数组
timestamps = np.arange(len(displacement_y)) / fps

2. 位移信号预处理

  • 去趋势:移除位移序列中的线性漂移(比如相机缓慢移动导致的整体偏移),避免干扰频率分析:
    from scipy.signal import detrend
    detrended_y = detrend(displacement_y)
    
  • 低通滤波:过滤高频噪声,保留振动信号:
    from scipy.signal import butter, filtfilt
    def butter_lowpass(cutoff, fs, order=5):
        nyq = 0.5 * fs
        normal_cutoff = cutoff / nyq
        b, a = butter(order, normal_cutoff, btype='low', analog=False)
        return b, a
    
    cutoff_freq = 10  # 替换为你预期的振动最高频率
    b, a = butter_lowpass(cutoff_freq, fps)
    filtered_y = filtfilt(b, a, detrended_y)
    

3. 频率提取(两种核心方法)

方法1:FFT功率谱分析

对预处理后的位移序列做FFT,找到功率谱峰值对应的频率:

from scipy.fft import fft, fftfreq

n = len(filtered_y)
# 计算FFT和频率轴
yf = fft(filtered_y)
xf = fftfreq(n, 1/fps)[:n//2]  # 只取正频率部分
power_spectrum = 2.0/n * np.abs(yf[:n//2])

# 找到峰值对应的频率(排除0Hz直流分量)
peak_idx = np.argmax(power_spectrum[1:]) + 1
vibration_freq = xf[peak_idx]
print(f"振动频率:{vibration_freq:.2f} Hz")

方法2:自相关法(噪声鲁棒性更强)

通过计算位移序列的自相关,找到信号周期,再转换为频率:

corr = np.correlate(filtered_y, filtered_y, mode='full')
corr = corr[len(corr)//2:]  # 取自相关的正延迟部分
# 找到第一个峰值位置(对应周期)
peak_pos = np.argmax(corr[1:]) + 1
period = peak_pos / fps
vibration_freq = 1 / period

二、替代的视频振动测量方法

除了2D FFT帧间位移检测,还有以下更实用的方法:

1. 光流法(适合局部区域振动)

通过计算像素的光流场,获取感兴趣区域(ROI)的平均位移,鲁棒性优于直接帧差FFT:

import cv2

cap = cv2.VideoCapture("your_video.mp4")
ret, prev_frame = cap.read()
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
fps = cap.get(cv2.CAP_PROP_FPS)

displacements = []
# 定义振动物体的ROI(x1,y1,x2,y2)
roi = (100, 100, 300, 300)

while ret:
    ret, curr_frame = cap.read()
    if not ret:
        break
    curr_gray = cv2.cvtColor(curr_frame, cv2.COLOR_BGR2GRAY)
    # 计算稠密光流
    flow = cv2.calcOpticalFlowFarneback(prev_gray, curr_gray, None, 0.5, 3, 15, 3, 5, 1.2, 0)
    # 提取ROI内的光流并计算平均位移
    x1, y1, x2, y2 = roi
    roi_flow = flow[y1:y2, x1:x2]
    avg_x = np.mean(roi_flow[..., 0])
    avg_y = np.mean(roi_flow[..., 1])
    displacements.append((avg_x, avg_y))
    prev_gray = curr_gray

cap.release()

2. 特征点跟踪法(适合有明显特征的物体)

检测物体上的特征点,跟踪其帧间运动,过滤无效跟踪点后取平均位移:

cap = cv2.VideoCapture("your_video.mp4")
ret, prev_frame = cap.read()
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
# 检测ORB特征点
orb = cv2.ORB_create(500)
kp_prev, des_prev = orb.detectAndCompute(prev_gray, None)

displacements = []
fps = cap.get(cv2.CAP_PROP_FPS)

while ret:
    ret, curr_frame = cap.read()
    if not ret:
        break
    curr_gray = cv2.cvtColor(curr_frame, cv2.COLOR_BGR2GRAY)
    kp_curr, des_curr = orb.detectAndCompute(curr_gray, None)
    # 匹配特征点
    bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
    matches = bf.match(des_prev, des_curr)
    # 计算平均位移
    dx_list, dy_list = [], []
    for match in matches:
        prev_pt = kp_prev[match.queryIdx].pt
        curr_pt = kp_curr[match.trainIdx].pt
        dx_list.append(curr_pt[0] - prev_pt[0])
        dy_list.append(curr_pt[1] - prev_pt[1])
    if dx_list:
        avg_dx = np.mean(dx_list)
        avg_dy = np.mean(dy_list)
        displacements.append((avg_dx, avg_dy))
    kp_prev, des_prev = kp_curr, des_curr

cap.release()

3. 像素强度时域分析法(适合亚像素级微小振动)

对于振动幅度极小的场景,直接分析ROI内像素平均强度的时域变化,通过FFT提取频率:

cap = cv2.VideoCapture("your_video.mp4")
fps = cap.get(cv2.CAP_PROP_FPS)
roi = (100, 100, 300, 300)
intensity_list = []

while ret:
    ret, frame = cap.read()
    if not ret:
        break
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    x1, y1, x2, y2 = roi
    roi_intensity = np.mean(gray[y1:y2, x1:x2])
    intensity_list.append(roi_intensity)

cap.release()

# 对强度序列做FFT提取频率(步骤同位移序列的FFT分析)

三、关键注意事项

  • 帧率校准:必须使用视频的实际帧率(通过cap.get(cv2.CAP_PROP_FPS)获取),否则频率计算会出现偏差;高速相机需确认硬件帧率参数准确。
  • 物理单位转换:若需要实际长度的位移,需用已知尺寸的标定物,建立像素与实际长度的映射关系。
  • 噪声抑制:环境光变化、相机抖动会干扰结果,可通过缩小ROI、增加滤波强度、多帧平均等方式降低噪声影响。

内容的提问来源于stack exchange,提问作者tryingmybest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 18:54:50