简洁版相关滤波跟踪演示

为了更好地理解相关滤波跟踪,同时练练编程,用python写了一个简单的相关滤波,可以从摄像头图像中用鼠标圈定目标进行跟踪,目前仅用了灰度特征,大概能跟上目标,效果一般。

# -*- coding: utf-8 -*-

import numpy as np
import cv2


def gaussian_label(sz, sigma):
    w, h = sz
    xs, ys = np.meshgrid(np.arange(w) - w // 2, np.arange(h) - h // 2)
    labels = np.exp(-0.5 * (xs ** 2 + ys ** 2) / (sigma ** 2))
    labels = np.roll(labels, -int(np.floor(w / 2)), axis=1)
    labels = np.roll(labels, -int(np.floor(h / 2)), axis=0)
    return labels


def get_cos_window(sz):
    w, h = sz
    cos_window = np.hanning(h)[:, np.newaxis].dot(np.hanning(w)[np.newaxis, :])
    return cos_window

class App(object):
    def __init__(self):
        self.cap = cv2.VideoCapture(0)
        ret, self.frame = self.cap.read()
        cv2.namedWindow('CFtracking')
        cv2.setMouseCallback('CFtracking', self.on_mouse)
        self.track_window = None
        self.selection = None
        self.drag_start = None
        self.tracking = False

    def on_mouse(self, event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            self.drag_start = (x, y)
        if event == cv2.EVENT_LBUTTONUP:
            self.drag_start = None
            self.track_window = self.selection
        if self.drag_start:
            xmin = min(x, self.drag_start[0])
            ymin = min(y, self.drag_start[1])
            xmax = max(x, self.drag_start[0])
            ymax = max(y, self.drag_start[1])
            self.selection = (xmin, ymin, xmax - xmin, ymax - ymin)

    def run(self):
        while True:
            ret, self.frame = self.cap.read()
            show = self.frame.copy()
            gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY).astype(np.float32)

            try:
                if self.track_window:
                    x, y, w, h = self.track_window
                    self.target_sz = (w, h)
                    self.window_sz = (int((1+1.5)*w), int((1+1.5)*h))
                    self.center = (x+w/2,y+h/2)
                    label = gaussian_label(self.window_sz, np.sqrt(w * h) // 10)
                    self.yf = np.fft.fft2(label)
                    self.cos_window = get_cos_window(self.window_sz)
                    xt = cv2.getRectSubPix(gray, self.window_sz, self.center) / 255 - 0.5
                    xt = xt * self.cos_window
                    xf = np.fft.fft2(xt)
                    hf = np.conjugate(self.yf) * xf / (np.conjugate(xf) * xf + 1e-3)
                    self.track_window = None
                    self.tracking = True

                if self.tracking:
                    xt = cv2.getRectSubPix(gray, self.window_sz, self.center) / 255 - 0.5
                    xt = xt * self.cos_window
                    xf = np.fft.fft2(xt)
                    response = np.real(np.fft.ifft2(np.conjugate(hf) * xf))
                    dy, dx = np.unravel_index(np.argmax(response, axis=None), response.shape)
                    if dx + 1 > self.window_sz[0]/2:
                        dx = dx - self.window_sz[0]
                    if dy + 1 > self.window_sz[1]/2:
                        dy = dy - self.window_sz[1]
                    xc,yc = self.center
                    xc += dx
                    yc += dy
                    self.center = (xc,yc)
                    xt = cv2.getRectSubPix(gray, self.window_sz, self.center) / 255 - 0.5
                    xt = xt * self.cos_window
                    xf = np.fft.fft2(xt)
                    new_hf = np.conjugate(self.yf) * xf / (np.conjugate(xf) * xf + 1e-3)
                    hf = (1 - 0.075) * hf + 0.075 * new_hf
                    xc, yc = self.center
                    cv2.rectangle(show, (xc - w/2,yc - h/2), (xc + w/2, yc + h/2), (0, 0, 255), 2)
            except:
                break

            cv2.imshow('CFtracking', show)
            if cv2.waitKey(1) == 27:
                break
        print('Program terminate')
        cv2.destroyAllWindows()


if __name__ == '__main__':
    app = App()
    app.run()

在这里插入图片描述

参考代码

https://github.com/wwdguu/pyCFTrackers
https://github.com/opencv/opencv/blob/master/samples/python/camshift.py

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值