写一段从悬臂梁振动冲击视频中利用圆心标靶检测算法提取悬臂梁上6个测点,并利用对于每个测点,并使用Lucas-Kanade光流法进行跟踪并计算位移,将每个测点的位移数据存储下来,并绘制位移时程曲线的完整代码
时间: 2024-02-13 11:00:38 浏览: 109
好的,以下是利用圆心标靶检测算法和Lucas-Kanade光流法提取悬臂梁上6个测点的位移并绘制位移时程曲线的完整代码:
```python
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 设置参数
winSize = (21, 21)
maxLevel = 3
criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)
# 读取视频
cap = cv2.VideoCapture("beam_video.mp4")
# 提取每一帧
ret, frame = cap.read()
gray_prev = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 检测圆心标靶
circles = cv2.HoughCircles(gray_prev, cv2.HOUGH_GRADIENT, 1, 50, param1=50, param2=30, minRadius=5, maxRadius=20)
circles = np.uint16(np.around(circles))
# 初始化跟踪点
p0 = np.array([[[x, y]] for x, y, r in circles[0]])
color = np.random.randint(0, 255, (len(p0), 3))
# 创建空列表存储每个测点的位移数据
displacement_data = [[] for i in range(len(p0))]
while True:
# 读取下一帧
ret, frame = cap.read()
if not ret:
break
# 转换为灰度图像
gray_next = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 计算光流
p1, status, err = cv2.calcOpticalFlowPyrLK(gray_prev, gray_next, p0, None, winSize, maxLevel, criteria)
# 选择好的跟踪点
good_new = p1[status == 1]
good_old = p0[status == 1]
# 计算位移并存储
for i, (new, old) in enumerate(zip(good_new, good_old)):
displacement = np.sqrt((new[0] - old[0]) ** 2 + (new[1] - old[1]) ** 2)
displacement_data[i].append(displacement)
# 更新跟踪点
p0 = good_new.reshape(-1, 1, 2)
# 绘制跟踪点和位移路径
for i, (new, old) in enumerate(zip(good_new, good_old)):
a, b = new.ravel()
c, d = old.ravel()
frame = cv2.line(frame, (a, b), (c, d), color[i].tolist(), 2)
frame = cv2.circle(frame, (a, b), 5, color[i].tolist(), -1)
# 显示当前帧
cv2.imshow("frame", frame)
# 按下q键退出
if cv2.waitKey(25) & 0xFF == ord("q"):
break
# 更新上一帧
gray_prev = gray_next.copy()
# 绘制位移时程曲线
for i, data in enumerate(displacement_data):
plt.plot(data, label=f"Point{i+1}")
plt.legend()
plt.xlabel("Frame")
plt.ylabel("Displacement")
plt.show()
# 释放资源
cap.release()
cv2.destroyAllWindows()
```
需要注意的是,这段代码中的 `beam_video.mp4` 是指悬臂梁振动冲击视频的文件名,需要根据实际情况进行修改。此外,代码中使用了Matplotlib库,需要先安装才能运行。
阅读全文