script_video.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #!/usr/bin/env python
  2. import numpy as np
  3. import cv2
  4. from time import clock
  5. from numpy import pi, sin, cos
  6. import common
  7. class VideoSynthBase(object):
  8. def __init__(self, size=None, noise=0.0, bg = None, **params):
  9. self.bg = None
  10. self.frame_size = (640, 480)
  11. if bg is not None:
  12. self.bg = cv2.imread(bg, 1)
  13. h, w = self.bg.shape[:2]
  14. self.frame_size = (w, h)
  15. if size is not None:
  16. w, h = map(int, size.split('x'))
  17. self.frame_size = (w, h)
  18. self.bg = cv2.resize(self.bg, self.frame_size)
  19. self.noise = float(noise)
  20. def render(self, dst):
  21. pass
  22. def read(self, dst=None):
  23. w, h = self.frame_size
  24. if self.bg is None:
  25. buf = np.zeros((h, w, 3), np.uint8)
  26. else:
  27. buf = self.bg.copy()
  28. self.render(buf)
  29. if self.noise > 0.0:
  30. noise = np.zeros((h, w, 3), np.int8)
  31. cv2.randn(noise, np.zeros(3), np.ones(3)*255*self.noise)
  32. buf = cv2.add(buf, noise, dtype=cv2.CV_8UC3)
  33. return True, buf
  34. class Chess(VideoSynthBase):
  35. def __init__(self, **kw):
  36. super(Chess, self).__init__(**kw)
  37. w, h = self.frame_size
  38. self.grid_size = sx, sy = 10, 7
  39. white_quads = []
  40. black_quads = []
  41. for i, j in np.ndindex(sy, sx):
  42. q = [[j, i, 0], [j+1, i, 0], [j+1, i+1, 0], [j, i+1, 0]]
  43. [white_quads, black_quads][(i + j) % 2].append(q)
  44. self.white_quads = np.float32(white_quads)
  45. self.black_quads = np.float32(black_quads)
  46. fx = 0.9
  47. self.K = np.float64([[fx*w, 0, 0.5*(w-1)],
  48. [0, fx*w, 0.5*(h-1)],
  49. [0.0,0.0, 1.0]])
  50. self.dist_coef = np.float64([-0.2, 0.1, 0, 0])
  51. self.t = 0
  52. def draw_quads(self, img, quads, color = (0, 255, 0)):
  53. img_quads = cv2.projectPoints(quads.reshape(-1, 3), self.rvec, self.tvec, self.K, self.dist_coef) [0]
  54. img_quads.shape = quads.shape[:2] + (2,)
  55. for q in img_quads:
  56. cv2.fillConvexPoly(img, np.int32(q*4), color, cv2.CV_AA, shift=2)
  57. def render(self, dst):
  58. t = self.t
  59. self.t += 1.0/30.0
  60. sx, sy = self.grid_size
  61. center = np.array([0.5*sx, 0.5*sy, 0.0])
  62. phi = pi/3 + sin(t*3)*pi/8
  63. c, s = cos(phi), sin(phi)
  64. ofs = np.array([sin(1.2*t), cos(1.8*t), 0]) * sx * 0.2
  65. eye_pos = center + np.array([cos(t)*c, sin(t)*c, s]) * 15.0 + ofs
  66. target_pos = center + ofs
  67. R, self.tvec = common.lookat(eye_pos, target_pos)
  68. self.rvec = common.mtx2rvec(R)
  69. self.draw_quads(dst, self.white_quads, (245, 245, 245))
  70. self.draw_quads(dst, self.black_quads, (10, 10, 10))
  71. classes = dict(chess=Chess)
  72. def create_capture(source):
  73. '''
  74. source: <int> or '<int>' or '<filename>' or 'synth:<params>'
  75. '''
  76. try: source = int(source)
  77. except ValueError: pass
  78. else:
  79. return cv2.VideoCapture(source)
  80. source = str(source).strip()
  81. if source.startswith('synth'):
  82. ss = filter(None, source.split(':'))
  83. params = dict( s.split('=') for s in ss[1:] )
  84. try: Class = classes[params['class']]
  85. except: Class = VideoSynthBase
  86. return Class(**params)
  87. return cv2.VideoCapture(source)
  88. presets = dict(
  89. empty = 'synth:',
  90. lena = 'synth:bg=../cpp/lena.jpg:noise=0.1',
  91. chess = 'synth:class=chess:bg=../cpp/lena.jpg:noise=0.1:size=640x480'
  92. )
  93. if __name__ == '__main__':
  94. import sys
  95. import getopt
  96. print 'USAGE: video.py [--shotdir <dir>] [source0] [source1] ...'
  97. print "source: '<int>' or '<filename>' or 'synth:<params>'"
  98. print
  99. args, sources = getopt.getopt(sys.argv[1:], '', 'shotdir=')
  100. args = dict(args)
  101. shotdir = args.get('--shotdir', '.')
  102. if len(sources) == 0:
  103. sources = [ presets['chess'] ]
  104. print 'Press SPACE to save current frame'
  105. caps = map(create_capture, sources)
  106. shot_idx = 0
  107. while True:
  108. imgs = []
  109. for i, cap in enumerate(caps):
  110. ret, img = cap.read()
  111. imgs.append(img)
  112. cv2.imshow('capture %d' % i, img)
  113. ch = cv2.waitKey(5)
  114. if ch == 27:
  115. break
  116. if ch == ord(' '):
  117. for i, img in enumerate(imgs):
  118. fn = '%s/shot_%d_%03d.bmp' % (shotdir, i, shot_idx)
  119. cv2.imwrite(fn, img)
  120. print fn, 'saved'
  121. shot_idx += 1