2016-05-15 117 views
0

我被修改以下代碼來跟蹤一個對象並保存對象的圖像被跟蹤:的OpenCV和Python:對象跟蹤和保存對象被跟蹤爲圖像

#!/usr/bin/env python 

''' 
MOSSE tracking sample 

This sample implements correlation-based tracking approach, described in [1]. 

Usage: 
    mosse.py [--pause] [<video source>] 

    --pause - Start with playback paused at the first video frame. 
       Useful for tracking target selection. 

    Draw rectangles around objects with a mouse to track them. 

Keys: 
    SPACE - pause video 
    c  - clear targets 

[1] David S. Bolme et al. "Visual Object Tracking using Adaptive Correlation Filters" 
    http://www.cs.colostate.edu/~bolme/publications/Bolme2010Tracking.pdf 
''' 

# Python 2/3 compatibility 
from __future__ import print_function 
import sys 
PY3 = sys.version_info[0] == 3 

if PY3: 
    xrange = range 

import numpy as np 
import cv2 
from common import draw_str, RectSelector 
import video 

def rnd_warp(a): 
    h, w = a.shape[:2] 
    T = np.zeros((2, 3)) 
    coef = 0.2 
    ang = (np.random.rand()-0.5)*coef 
    c, s = np.cos(ang), np.sin(ang) 
    T[:2, :2] = [[c,-s], [s, c]] 
    T[:2, :2] += (np.random.rand(2, 2) - 0.5)*coef 
    c = (w/2, h/2) 
    T[:,2] = c - np.dot(T[:2, :2], c) 
    return cv2.warpAffine(a, T, (w, h), borderMode = cv2.BORDER_REFLECT) 

def divSpec(A, B): 
    Ar, Ai = A[...,0], A[...,1] 
    Br, Bi = B[...,0], B[...,1] 
    C = (Ar+1j*Ai)/(Br+1j*Bi) 
    C = np.dstack([np.real(C), np.imag(C)]).copy() 
    return C 

eps = 1e-5 

class MOSSE: 
    def __init__(self, frame, rect): 
     x1, y1, x2, y2 = rect 
     w, h = map(cv2.getOptimalDFTSize, [x2-x1, y2-y1]) 
     x1, y1 = (x1+x2-w)//2, (y1+y2-h)//2 
     self.pos = x, y = x1+0.5*(w-1), y1+0.5*(h-1) 
     self.size = w, h 
     img = cv2.getRectSubPix(frame, (w, h), (x, y)) 

     self.win = cv2.createHanningWindow((w, h), cv2.CV_32F) 
     g = np.zeros((h, w), np.float32) 
     g[h//2, w//2] = 1 
     g = cv2.GaussianBlur(g, (-1, -1), 2.0) 
     g /= g.max() 

     self.G = cv2.dft(g, flags=cv2.DFT_COMPLEX_OUTPUT) 
     self.H1 = np.zeros_like(self.G) 
     self.H2 = np.zeros_like(self.G) 
     for i in xrange(128): 
      a = self.preprocess(rnd_warp(img)) 
      A = cv2.dft(a, flags=cv2.DFT_COMPLEX_OUTPUT) 
      self.H1 += cv2.mulSpectrums(self.G, A, 0, conjB=True) 
      self.H2 += cv2.mulSpectrums( A, A, 0, conjB=True) 
     self.update_kernel() 
     self.update(frame) 

    def update(self, frame, rate = 0.125): 
     (x, y), (w, h) = self.pos, self.size 
     self.last_img = img = cv2.getRectSubPix(frame, (w, h), (x, y)) 
     img = self.preprocess(img) 
     self.last_resp, (dx, dy), self.psr = self.correlate(img) 
     self.good = self.psr > 8.0 
     if not self.good: 
      return 

     self.pos = x+dx, y+dy 
     self.last_img = img = cv2.getRectSubPix(frame, (w, h), self.pos) 
     img = self.preprocess(img) 

     A = cv2.dft(img, flags=cv2.DFT_COMPLEX_OUTPUT) 
     H1 = cv2.mulSpectrums(self.G, A, 0, conjB=True) 
     H2 = cv2.mulSpectrums( A, A, 0, conjB=True) 
     self.H1 = self.H1 * (1.0-rate) + H1 * rate 
     self.H2 = self.H2 * (1.0-rate) + H2 * rate 
     self.update_kernel() 

    @property 
    def state_vis(self): 
     f = cv2.idft(self.H, flags=cv2.DFT_SCALE | cv2.DFT_REAL_OUTPUT) 
     h, w = f.shape 
     f = np.roll(f, -h//2, 0) 
     f = np.roll(f, -w//2, 1) 
     kernel = np.uint8((f-f.min())/f.ptp()*255) 
     resp = self.last_resp 
     resp = np.uint8(np.clip(resp/resp.max(), 0, 1)*255) 
     vis = np.hstack([self.last_img, kernel, resp]) 
     return vis 

    def draw_state(self, vis): 
     (x, y), (w, h) = self.pos, self.size 
     x1, y1, x2, y2 = int(x-0.5*w), int(y-0.5*h), int(x+0.5*w), int(y+0.5*h) 
     cv2.rectangle(vis, (x1, y1), (x2, y2), (0, 0, 255)) 
     if self.good: 
      cv2.circle(vis, (int(x), int(y)), 2, (0, 0, 255), -1) 
     else: 
      cv2.line(vis, (x1, y1), (x2, y2), (0, 0, 255)) 
      cv2.line(vis, (x2, y1), (x1, y2), (0, 0, 255)) 
     draw_str(vis, (x1, y2+16), 'PSR: %.2f' % self.psr) 

    def preprocess(self, img): 
     img = np.log(np.float32(img)+1.0) 
     img = (img-img.mean())/(img.std()+eps) 
     return img*self.win 

    def correlate(self, img): 
     C = cv2.mulSpectrums(cv2.dft(img, flags=cv2.DFT_COMPLEX_OUTPUT), self.H, 0, conjB=True) 
     resp = cv2.idft(C, flags=cv2.DFT_SCALE | cv2.DFT_REAL_OUTPUT) 
     h, w = resp.shape 
     _, mval, _, (mx, my) = cv2.minMaxLoc(resp) 
     side_resp = resp.copy() 
     cv2.rectangle(side_resp, (mx-5, my-5), (mx+5, my+5), 0, -1) 
     smean, sstd = side_resp.mean(), side_resp.std() 
     psr = (mval-smean)/(sstd+eps) 
     return resp, (mx-w//2, my-h//2), psr 

    def update_kernel(self): 
     self.H = divSpec(self.H1, self.H2) 
     self.H[...,1] *= -1 

class App: 
    def __init__(self, video_src, paused = False): 
     self.cap = video.create_capture(video_src) 
     _, self.frame = self.cap.read() 
     cv2.imshow('frame', self.frame) 
     self.rect_sel = RectSelector('frame', self.onrect) 
     self.trackers = [] 
     self.paused = paused 

    def onrect(self, rect): 
     frame_gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY) 
     tracker = MOSSE(frame_gray, rect) 
     self.trackers.append(tracker) 

    def run(self): 
     while True: 
      if not self.paused: 
       ret, self.frame = self.cap.read() 
       if not ret: 
        break 
       frame_gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY) 
       for tracker in self.trackers: 
        tracker.update(frame_gray) 

      vis = self.frame.copy() 
      for tracker in self.trackers: 
       tracker.draw_state(vis) 
      if len(self.trackers) > 0: 
       cv2.imshow('tracker state', self.trackers[-1].state_vis) 
       cv2.imwrite('object.jpg', self.trackers[-1].state_vis) 

      self.rect_sel.draw(vis) 

      cv2.imshow('frame', vis) 
      ch = cv2.waitKey(10) & 0xFF 
      if ch == 27: 
       break 
      if ch == ord(' '): 
       self.paused = not self.paused 
      if ch == ord('c'): 
       self.trackers = [] 


if __name__ == '__main__': 
    print (__doc__) 
    import sys, getopt 
    opts, args = getopt.getopt(sys.argv[1:], '', ['pause']) 
    opts = dict(opts) 
    try: 
     video_src = args[0] 
    except: 
     video_src = '0' 

    App(video_src, paused = '--pause' in opts).run() 

但是在跟蹤器狀態窗口它捕捉跟蹤對象的輪廓和浮雕版本(我不需要)以及對象。我只需要對象的正常圖像(跟蹤器狀態窗口的第一部分)。

請注意,跟蹤器狀態窗口中有三個部分。 任何人都可以幫忙嗎?

謝謝!

+0

是否顯示真實的輪廓或周圍的輪廓(圓形,矩形...)?你可以發佈結果的截圖以幫助理解更好嗎? – Vtik

+0

我現在改了這個問題。希望你現在更好地理解它! – Vin

回答

1

基於這個Mosse跟蹤的video,我假設物體的輪廓是矩形的,這在查看代碼時很明顯。

我沒有一個簡單的答案(不喜歡的人在這裏發帖的功課),但是,我仍然有一個小竅門:

  • 嘗試評論含cv2.rectangle()link to doc)的線,因爲它是負責繪製矩形(你可能已經猜到了)。

這應該不會太難解決!