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

如何将两帧相位相关结果映射至目标跟踪窗口及亚像素位移实现

问题描述
  • 基于论文《A Robust Image Tracker based on Phase Correlation and Fourier-Mallin Transform》实现相位相关目标跟踪,已完成目标选定和跟踪窗口生成,但对cv.phaseCorrelate输出含义不理解,不知道如何用它移动跟踪窗口。
  • 不清楚论文中提到的亚像素位移如何在该环节实现。
  • 尝试直接叠加函数输出到跟踪框,但代码运行存在问题,原代码如下:
import cv2 as cv
import numpy as np

capture = cv.VideoCapture('PHASE_CORRELATION/VIDEOS/flying_bird1.mp4')
cv.createHanningWindow((960,540),cv.CV_32F)
flag = 0
flag1 = 0

a,b = 0,0
def mouseHandler(event, x, y, flags, params):
    if event == cv.EVENT_LBUTTONDOWN:
        flag1 = 1
        global a
        global b
        a = round(x)
        b = round(y)
cv.namedWindow('Window',cv.WINDOW_NORMAL)
cv.setMouseCallback('Window',mouseHandler)


while True:

    istrue,frame = capture. read()

    frame = cv.resize(frame,(960,540),interpolation=cv.INTER_AREA)

    frame = cv.cvtColor(frame,cv.COLOR_BGR2GRAY)


    if (flag==0):
        curr = frame
        flag = 1
    else:
        prev = curr
        curr = frame

        
        shift = cv.phaseCorrelate(np.float32(prev),np.float32(curr))

        if (flag1==1):
            frame = cv.rectangle(frame,(x+30,y+30),(x-30,y-30),[255,0,0],2)
            a = round(a+shift[0][0])
            b = round(b+shift[0][1])
   
            flag1 = 2
        
        if (flag1==2):
            a = round(a+shift[0][0])
            b = round(b+shift[0][1])
            frame = cv.rectangle(frame,(x+shift[0][0]+30,y+shift[0][1]+30),(x+shift[0][0]-30,y+shift[0][1]-30),2)




        cv.imshow('Window',frame)

    if cv.waitKey(20) & 0xFF==ord('d'):
        break

capture. release()
cv.destroyAllwindows()

解决方案与说明

一、理解cv.phaseCorrelate的输出

该函数返回三个值:(shift, error, diff)

  • shift:二元组(dx, dy),表示当前帧相对前一帧的水平(x轴)、垂直(y轴)位移量,单位为像素,天然支持亚像素精度(例如dx=1.5、dy=-0.7)。逻辑上:若目标在当前帧相对于前一帧移动了(dx, dy),跟踪窗口的坐标需叠加该位移值。
  • error:相位匹配误差值,越小说明两帧匹配度越高,可用于判断跟踪是否失效。
  • diff:傅里叶域差异值,一般无需使用。

二、正确移动跟踪窗口的逻辑

原代码存在几个核心问题:

  1. 鼠标回调未正确绑定全局变量,后续直接使用x,y会导致未定义错误,应使用全局的a,b(或重命名为center_x,center_y更直观)。
  2. 跟踪窗口坐标计算错误:窗口中心为(center_x,center_y),左上角应为(center_x-30, center_y-30),右下角为(center_x+30, center_y+30)。
  3. 位移叠加逻辑错误:需基于前一帧的窗口中心,叠加当前帧计算的位移,而非重复累加同一位移值。

修正后的核心逻辑:

  • 用户点击选定目标后,记录窗口中心(center_x, center_y),固定窗口大小为60x60(±30)。
  • 每帧计算当前帧与前一帧的相位相关位移(dx, dy)。
  • 更新窗口中心:center_x += dx,center_y += dy。
  • 将浮点数中心坐标转为整数,绘制跟踪窗口。

三、亚像素位移的实现

cv.phaseCorrelate本身已通过互功率谱峰值二次插值实现亚像素精度计算,无需额外编码。使用时直接取返回的shift值即可,仅在绘制窗口时需将浮点数坐标转为整数(用int()或round())。


修正后的完整代码
import cv2 as cv
import numpy as np

capture = cv.VideoCapture('PHASE_CORRELATION/VIDEOS/flying_bird1.mp4')
# 应用汉宁窗减少边界噪声,提升相位相关准确性
hanning_window = cv.createHanningWindow((960, 540), cv.CV_32F)
flag = 0
track_started = 0

# 跟踪窗口中心坐标
center_x, center_y = 0, 0

def mouseHandler(event, x, y, flags, params):
    global track_started, center_x, center_y
    if event == cv.EVENT_LBUTTONDOWN:
        track_started = 1
        center_x = x
        center_y = y

cv.namedWindow('Window', cv.WINDOW_NORMAL)
cv.setMouseCallback('Window', mouseHandler)

prev_frame = None

while True:
    istrue, frame = capture.read()
    if not istrue:
        break  # 视频读取完毕退出

    frame = cv.resize(frame, (960, 540), interpolation=cv.INTER_AREA)
    gray_frame = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    gray_float = np.float32(gray_frame)

    if flag == 0:
        prev_frame = gray_float * hanning_window
        flag = 1
    else:
        curr_frame = gray_float * hanning_window
        # 计算相位相关位移
        shift, error, _ = cv.phaseCorrelate(prev_frame, curr_frame)
        dx, dy = shift

        # 更新并绘制跟踪窗口
        if track_started == 1:
            # 更新中心坐标
            center_x += dx
            center_y += dy
            # 计算窗口对角坐标
            top_left = (int(center_x - 30), int(center_y - 30))
            bottom_right = (int(center_x + 30), int(center_y + 30))
            # 在彩色帧上绘制窗口(保留彩色更直观)
            cv.rectangle(frame, top_left, bottom_right, (0, 255, 0), 2)
            # 显示匹配误差,用于判断跟踪可靠性
            cv.putText(frame, f"Error: {error:.2f}", (10, 30), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

        prev_frame = curr_frame
        cv.imshow('Window', frame)

    if cv.waitKey(20) & 0xFF == ord('d'):
        break

capture.release()
cv.destroyAllWindows()

额外建议
  • 汉宁窗的作用:相位相关对图像边界噪声敏感,应用汉宁窗可降低边缘高频干扰,提升位移计算准确性,原代码未使用该窗口,修正后已加入。
  • 跟踪失效判断:当error超过阈值(如0.3)时,说明两帧匹配度极低,可能目标丢失,需重新触发目标选定。
  • 论文拓展:当前仅实现基础平移跟踪,若要实现论文中的鲁棒跟踪,需结合Fourier-Mallin Transform处理旋转、缩放等复杂运动场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 08:35:41