Blame view

3rdparty/opencv-4.5.4/samples/python/lk_homography.py 3.71 KB
f4334277   Hu Chunming   提交3rdparty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
  #!/usr/bin/env python
  
  '''
  Lucas-Kanade homography tracker
  ===============================
  
  Lucas-Kanade sparse optical flow demo. Uses goodFeaturesToTrack
  for track initialization and back-tracking for match verification
  between frames. Finds homography between reference and current views.
  
  Usage
  -----
  lk_homography.py [<video_source>]
  
  
  Keys
  ----
  ESC   - exit
  SPACE - start tracking
  r     - toggle RANSAC
  '''
  
  # Python 2/3 compatibility
  from __future__ import print_function
  
  import numpy as np
  import cv2 as cv
  
  import video
  from common import draw_str
  from video import presets
  
  lk_params = dict( winSize  = (19, 19),
                    maxLevel = 2,
                    criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03))
  
  feature_params = dict( maxCorners = 1000,
                         qualityLevel = 0.01,
                         minDistance = 8,
                         blockSize = 19 )
  
  def checkedTrace(img0, img1, p0, back_threshold = 1.0):
      p1, _st, _err = cv.calcOpticalFlowPyrLK(img0, img1, p0, None, **lk_params)
      p0r, _st, _err = cv.calcOpticalFlowPyrLK(img1, img0, p1, None, **lk_params)
      d = abs(p0-p0r).reshape(-1, 2).max(-1)
      status = d < back_threshold
      return p1, status
  
  green = (0, 255, 0)
  red = (0, 0, 255)
  
  class App:
      def __init__(self, video_src):
          self.cam = self.cam = video.create_capture(video_src, presets['book'])
          self.p0 = None
          self.use_ransac = True
  
      def run(self):
          while True:
              _ret, frame = self.cam.read()
              frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
              vis = frame.copy()
              if self.p0 is not None:
                  p2, trace_status = checkedTrace(self.gray1, frame_gray, self.p1)
  
                  self.p1 = p2[trace_status].copy()
                  self.p0 = self.p0[trace_status].copy()
                  self.gray1 = frame_gray
  
                  if len(self.p0) < 4:
                      self.p0 = None
                      continue
                  H, status = cv.findHomography(self.p0, self.p1, (0, cv.RANSAC)[self.use_ransac], 10.0)
                  h, w = frame.shape[:2]
                  overlay = cv.warpPerspective(self.frame0, H, (w, h))
                  vis = cv.addWeighted(vis, 0.5, overlay, 0.5, 0.0)
  
                  for (x0, y0), (x1, y1), good in zip(self.p0[:,0], self.p1[:,0], status[:,0]):
                      if good:
                          cv.line(vis, (int(x0), int(y0)), (int(x1), int(y1)), (0, 128, 0))
                      cv.circle(vis, (int(x1), int(y1)), 2, (red, green)[good], -1)
                  draw_str(vis, (20, 20), 'track count: %d' % len(self.p1))
                  if self.use_ransac:
                      draw_str(vis, (20, 40), 'RANSAC')
              else:
                  p = cv.goodFeaturesToTrack(frame_gray, **feature_params)
                  if p is not None:
                      for x, y in p[:,0]:
                          cv.circle(vis, (int(x), int(y)), 2, green, -1)
                      draw_str(vis, (20, 20), 'feature count: %d' % len(p))
  
              cv.imshow('lk_homography', vis)
  
              ch = cv.waitKey(1)
              if ch == 27:
                  break
              if ch == ord(' '):
                  self.frame0 = frame.copy()
                  self.p0 = cv.goodFeaturesToTrack(frame_gray, **feature_params)
                  if self.p0 is not None:
                      self.p1 = self.p0
                      self.gray0 = frame_gray
                      self.gray1 = frame_gray
              if ch == ord('r'):
                  self.use_ransac = not self.use_ransac
  
  
  
  def main():
      import sys
      try:
          video_src = sys.argv[1]
      except:
          video_src = 0
  
      App(video_src).run()
      print('Done')
  
  
  if __name__ == '__main__':
      print(__doc__)
      main()
      cv.destroyAllWindows()