之前在研究目标追踪,现在把之前的东西整理一哈。
目标追踪领域有一个著名的算法——相关滤波,以及它的衍生——KCF。下面贴出一种用python实现KCF的方法,并给出必要的注释。
import numpy as np
import cv2
import fhog
import sys
PY3 = sys.version_info >= (3,)
if PY3:
xrange = range
#前面是一些数学工具,用来计算复数和FFT等,看函数名
# ffttools
def fftd(img, backwards=False):
# shape of img can be (m,n), (m,n,1) or (m,n,2)
# in my test, fft provided by numpy and scipy are slower than cv2.dft
return cv2.dft(np.float32(img), flags=(
(cv2.DFT_INVERSE | cv2.DFT_SCALE) if backwards else cv2.DFT_COMPLEX_OUTPUT)) # 'flags =' is necessary!
def real(img):
return img[:, :, 0]
def imag(img):
return img[:, :, 1]
def complexMultiplication(a, b):
res = np.zeros(a.shape, a.dtype)
res[:, :, 0] = a[:, :, 0] * b[:, :, 0] - a[:, :, 1] * b[:, :, 1]
res[:, :, 1] = a[:, :, 0] * b[:, :, 1] + a[:, :, 1] * b[:, :, 0]
return res
def complexDivision(a, b):
res = np.zeros(a.shape, a.dtype)
divisor = 1. / (b[:, :, 0] ** 2 + b[:, :, 1] ** 2)
res[:, :, 0] = (a[:, :, 0] * b[:, :, 0] + a[:, :, 1] * b[:, :, 1]) * divisor
res[:, :, 1] = (a[:, :, 1] * b[:, :, 0] + a[:, :, 0] * b[:, :, 1]) * divisor
return res
def rearrange(img):
# return np.fft.fftshift(img, axes=(0,1))
assert (img.ndim == 2)
img_ = np.zeros(img.shape, img.dtype)
xh, yh = img.shape[1] // 2, img.shape[0] // 2
img_[0:yh, 0:xh], img_[yh:img.shape[0], xh:img.shape[1]] = img[yh:img.shape[0], xh:img.shape[1]], img[0:yh, 0:xh]
img_[0:yh, xh:img.shape[1]], img_[yh:img.shape[0], 0:xh] = img[yh:img.shape[0], 0:xh], img[0:yh, xh:img.shape[1]]
return img_
# recttools
def x2(rect):
return rect[0] + rect[2]
def y2(rect):
return rect[1] + rect[3]
def limit(rect, limit):
if (rect[0] + rect[2] > limit[0] + limit[2]):
rect[2] = limit[0] + limit[2] - rect[0]
if (rect[1] + rect[3] > limit[1] + limit[3]):
rect[3] = limit[1] + limit[3] - rect[1]
if (rect[0] < limit[0]):
rect[2] -= (limit[0] - rect[0])
rect[0] = limit[0]
if (rect[1] < limit[1]):
rect[3] -= (limit[1] - rect[1])
rect[1] = limit[1]
if (rect[2] < 0):
rect[2] = 0
if (rect[3] < 0):
rect[3] = 0
return rect
def getBorder(original, limited):
res = [0, 0, 0, 0]
res[0] = limited[0] - original[0]
res[1] = limited[1] - original[1]
res[2] = x2(original) - x2(limited)
res[3] = y2(original) - y2(limited)
assert (np.all(np.array(res) >= 0))
return res
def subwindow(img, window, borderType=cv2.BORDER_CONSTANT):
cutWindow = [x for x in window]
limit(cutWindow, [0, 0, img.shape[1], img.shape[0]]) # modify cutWindow
assert (cutWindow[2] > 0 and cutWindow[3] > 0)
border = getBorder(window, cutWindow)
res = img[cutWindow[1]:cutWindow[1] + cutWindow[3], cutWindow[0]:cutWindow[0] + cutWindow[2]]
if (border != [0, 0, 0, 0]):
res = cv2