video_threaded.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #!/usr/bin/env python
  2. '''
  3. Multithreaded video processing sample.
  4. Usage:
  5. video_threaded.py {<video device number>|<video file name>}
  6. Shows how python threading capabilities can be used
  7. to organize parallel captured frame processing pipeline
  8. for smoother playback.
  9. Keyboard shortcuts:
  10. ESC - exit
  11. space - switch between multi and single threaded processing
  12. '''
  13. # Python 2/3 compatibility
  14. from __future__ import print_function
  15. import numpy as np
  16. import cv2 as cv
  17. from multiprocessing.pool import ThreadPool
  18. from collections import deque
  19. from common import clock, draw_str, StatValue
  20. import video
  21. class DummyTask:
  22. def __init__(self, data):
  23. self.data = data
  24. def ready(self):
  25. return True
  26. def get(self):
  27. return self.data
  28. def main():
  29. import sys
  30. try:
  31. fn = sys.argv[1]
  32. except:
  33. fn = 0
  34. cap = video.create_capture(fn)
  35. def process_frame(frame, t0):
  36. # some intensive computation...
  37. frame = cv.medianBlur(frame, 19)
  38. frame = cv.medianBlur(frame, 19)
  39. return frame, t0
  40. threadn = cv.getNumberOfCPUs()
  41. pool = ThreadPool(processes = threadn)
  42. pending = deque()
  43. threaded_mode = True
  44. latency = StatValue()
  45. frame_interval = StatValue()
  46. last_frame_time = clock()
  47. while True:
  48. while len(pending) > 0 and pending[0].ready():
  49. res, t0 = pending.popleft().get()
  50. latency.update(clock() - t0)
  51. draw_str(res, (20, 20), "threaded : " + str(threaded_mode))
  52. draw_str(res, (20, 40), "latency : %.1f ms" % (latency.value*1000))
  53. draw_str(res, (20, 60), "frame interval : %.1f ms" % (frame_interval.value*1000))
  54. cv.imshow('threaded video', res)
  55. if len(pending) < threadn:
  56. _ret, frame = cap.read()
  57. t = clock()
  58. frame_interval.update(t - last_frame_time)
  59. last_frame_time = t
  60. if threaded_mode:
  61. task = pool.apply_async(process_frame, (frame.copy(), t))
  62. else:
  63. task = DummyTask(process_frame(frame, t))
  64. pending.append(task)
  65. ch = cv.waitKey(1)
  66. if ch == ord(' '):
  67. threaded_mode = not threaded_mode
  68. if ch == 27:
  69. break
  70. print('Done')
  71. if __name__ == '__main__':
  72. print(__doc__)
  73. main()
  74. cv.destroyAllWindows()