簡潔版相關濾波跟蹤演示

爲了更好地理解相關濾波跟蹤,同時練練編程,用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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章