52shishi

本文介绍了使用Python和OpenCV实现视频中特征点的追踪,通过计算光流来获取特征点在每一帧之间的位置变化,并使用Matplotlib进行可视化,展示了特征点在时间上的x和y方向位移情况。
摘要由CSDN通过智能技术生成
import cv2
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
# 输出每个特征点位移
# 创建文件用于写入坐标数据
output_file = open("coordinates.xlsx", "w")


def write_coordinates(x, y):
    #output_file.write(f"x={x}, y={y}\n")
    output_file.write(f"{y}\n")


def detect_coordinates(video_path):
    cap = cv2.VideoCapture(video_path)

    # 参数设置
    lk_params = dict(winSize=(15, 15), maxLevel=3, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.007))
    feature_params = dict(maxCorners=3, qualityLevel=0.7, minDistance=1, blockSize=7)

    # 读取第一帧作为初始帧
    ret, old_frame = cap.read()
    if old_frame is None:
        print("Error: Input frame is empty")
    else:
        old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
    # old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)

     # 使用 goodFeaturesToTrack 检测特征点
    p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params)
    # # ORB 特征点检测器
    # orb = cv2.ORB_create()

    # 检测特征点
    #p0, _ = orb.detectAndCompute(old_gray, None)


    # 存储每个特征点的坐标变化
    point_history = [[] for _ in range(p0.shape[0])]

    while True:
        # 读取当前帧
        ret, frame = cap.read()
        if not ret:  # 视频读取完毕
            break

        frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # 使用 calcOpticalFlowPyrLK 计算光流
        p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)

        # 保留好的特征点和匹配的特征点
        good_new = p1[st == 1]
        good_old = p0[st == 1]

        # 绘制追踪线和特征点
        for i, (new, old) in enumerate(zip(good_new, good_old)):
            a, b = new.ravel()
            c, d = old.ravel()
            cv2.line(frame, (int(a), int(b)), (int(c), int(d)), (0, 255, 0), 2)
            cv2.circle(frame, (int(a), int(b)), 5, (0, 0, 255), -1)

            # 将坐标写入文件
            write_coordinates(a, b)

            # 存储坐标变化
            point_history[i].append((a, b))

        # 显示当前帧
        cv2.imshow("Frame", frame)

        # 退出循环的条件
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

        # 更新上一帧的图像和特征点
        old_gray = frame_gray.copy()
        p0 = good_new.reshape(-1, 1, 2)

    # 关闭视频和文件
    cap.release()
    output_file.close()
    cv2.destroyAllWindows()

    # 提取特征点的位移沿x方向的数据
    x_data = [[] for _ in range(len(point_history))]
    for i, points in enumerate(point_history):
        for j in range(1, len(points)):
            #x_data[i].append(points[j][0] - points[i][0])  # 计算横x位移
            x_data[i].append(points[j][1] - points[i][1])  # 计算竖y位移

    # 可视化特征点的位移与时间的关系
    plt.figure()
    for i, x_values in enumerate(x_data):
        t = np.arange(len(x_values))
        #plt.xticks(np.linspace(t.min(), t.max(), num=20)) #x轴范围限制
        # plt.grid(True,linestyle=':', linewidth=1) #网格
        plt.plot(t, x_values, label=f"Point {i + 1}", linestyle="-")
    # 去掉网格线
    # plt.grid(False)

    plt.title("X Displacement of Feature Points over Time")
    plt.xlabel("Frame Number")
    plt.ylabel("Displacement (pixels)")
    plt.legend()
    plt.show()

# 调用函数执行坐标检测并将结果写入文件
detect_coordinates("saocj1.avi")



import cv2
import numpy as np
import matplotlib.pyplot as plt
video_path="saocj.avi"
cap = cv2.VideoCapture(video_path)

# 参数设置
lk_params = dict(winSize=(15, 15), maxLevel=3, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.007))
feature_params = dict(maxCorners=3, qualityLevel=0.7, minDistance=1, blockSize=7)

# 读取第一帧作为初始帧
ret, old_frame = cap.read()
if old_frame is None:
    print("Error: Input frame is empty")
else:
    old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
# old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)

 # 使用 goodFeaturesToTrack 检测特征点
p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params)
# # ORB 特征点检测器
# orb = cv2.ORB_create()

# 检测特征点
#p0, _ = orb.detectAndCompute(old_gray, None)


# 存储每个特征点的坐标变化
point_history = [[] for _ in range(p0.shape[0])]
while True:
    # 读取当前帧
    ret, frame = cap.read()
    if not ret:  # 视频读取完毕
        break

    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 使用 calcOpticalFlowPyrLK 计算光流
    p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)

    # 保留好的特征点和匹配的特征点
    good_new = p1[st == 1]
    good_old = p0[st == 1]

    # 绘制追踪线和特征点
    for i, (new, old) in enumerate(zip(good_new, good_old)):
        a, b = new.ravel()
        c, d = old.ravel()
        cv2.line(frame, (int(a), int(b)), (int(c), int(d)), (0, 255, 0), 2)
        cv2.circle(frame, (int(a), int(b)), 5, (0, 0, 255), -1)

        # 存储坐标变化
        point_history[i].append((a, b))

    # 显示当前帧
    cv2.imshow("Frame", frame)

    # 获取当前帧号
    current_frame = cap.get(cv2.CAP_PROP_POS_FRAMES)
    # 提取特征点的位移沿x,y方向的数据
    x_data = [[] for _ in range(len(point_history))]
    y_data = [[] for _ in range(len(point_history))]
    for i, points in enumerate(point_history):
        for j in range(1, len(points)):
            x_data[i].append(points[j][0] - points[i][0])  # 计算横x位移
            y_data[i].append(points[j][1] - points[i][1])  # 计算竖y位移

    # 可视化特征点的位移与时间的关系
    plt.clf()  # 清空之前的图像
    for i, (x_values, y_values) in enumerate(zip(x_data, y_data)):
        t = np.arange(len(x_values))

        # 绘制x位移图像
        plt.subplot(2, 1, 1)
        plt.plot(t, x_values, label=f"Point {i + 1}", linestyle="-")
        plt.ylabel("X Displacement (pixels)")

        # 绘制y位移图像
        plt.subplot(2, 1, 2)
        plt.plot(t, y_values, label=f"Point {i + 1}", linestyle="-")
        plt.xlabel("Frame Number")
        plt.ylabel("Y Displacement (pixels)")

    plt.title("X Displacement of Feature Points over Time")
    #plt.legend()
    plt.text(0.05, 0.95, f"Frame: {int(current_frame)}", transform=plt.gca().transAxes, color='white')  # 在图上标记当前帧号
    plt.pause(0.001)  # 暂停一小段时间,以更新图像

    # 退出循环的条件
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    # 更新上一帧的图像和特征点
    old_gray = frame_gray.copy()
    p0 = good_new.reshape(-1, 1, 2)
# 关闭视频和文件
cap.release()
cv2.destroyAllWindows()

for i, (x_values, y_values) in enumerate(zip(x_data, y_data)):
    t = np.arange(len(x_values))

    # 绘制x位移图像
    plt.subplot(2, 1, 1)
    plt.plot(t, x_values, label=f"Point {i + 1}", linestyle="-")
    plt.ylabel("X Displacement (pixels)")

    # 绘制y位移图像
    plt.subplot(2, 1, 2)
    plt.plot(t, y_values, label=f"Point {i + 1}", linestyle="-")
    plt.xlabel("Frame Number")
    plt.ylabel("Y Displacement (pixels)")

plt.title("X Displacement of Feature Points over Time")
plt.legend()
plt.show()

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值