cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
video_threaded.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # *****************************************************************************
4 # * cloudFPGA
5 # * Copyright 2016 -- 2022 IBM Corporation
6 # * Licensed under the Apache License, Version 2.0 (the "License");
7 # * you may not use this file except in compliance with the License.
8 # * You may obtain a copy of the License at
9 # *
10 # * http://www.apache.org/licenses/LICENSE-2.0
11 # *
12 # * Unless required by applicable law or agreed to in writing, software
13 # * distributed under the License is distributed on an "AS IS" BASIS,
14 # * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # * See the License for the specific language governing permissions and
16 # * limitations under the License.
17 # *----------------------------------------------------------------------------
18 
19 # *****************************************************************************
20 # * OpenCV
21 # * Copyright 2021 -- OpenCV team
22 # * Licensed under the Apache License, Version 2.0 (the "License");
23 # * you may not use this file except in compliance with the License.
24 # * You may obtain a copy of the License at
25 # *
26 # * http://www.apache.org/licenses/LICENSE-2.0
27 # *
28 # * Unless required by applicable law or agreed to in writing, software
29 # * distributed under the License is distributed on an "AS IS" BASIS,
30 # * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 # * See the License for the specific language governing permissions and
32 # * limitations under the License.
33 # *----------------------------------------------------------------------------
34 
35 
36 '''
37 Multithreaded video processing sample.
38 Usage:
39  video_threaded.py {<video device number>|<video file name>}
40 
41  Shows how python threading capabilities can be used
42  to organize parallel captured frame processing pipeline
43  for smoother playback.
44 
45 Keyboard shortcuts:
46 
47  ESC - exit
48  space - switch between multi and single threaded processing
49 '''
50 
51 # Python 2/3 compatibility
52 from __future__ import print_function
53 
54 import numpy as np
55 import cv2 as cv
56 
57 from multiprocessing.pool import ThreadPool
58 from collections import deque
59 
60 from common import clock, draw_str, StatValue
61 import video
62 
63 
64 # import the necessary packages
65 import datetime
66 class FPS:
67  def __init__(self):
68  # store the start time, end time, and total number of frames
69  # that were examined between the start and end intervals
70  self._start_start = None
71  self._end_end = None
72  self._numFrames_numFrames = 0
73  def start(self):
74  # start the timer
75  self._start_start = datetime.datetime.now()
76  return self
77  def stop(self):
78  # stop the timer
79  self._end_end = datetime.datetime.now()
80  def update(self):
81  # increment the total number of frames examined during the
82  # start and end intervals
83  self._numFrames_numFrames += 1
84  def elapsed(self):
85  # return the total number of seconds between the start and
86  # end interval
87  return (self._end_end - self._start_start).total_seconds()
88  def fps(self):
89  # compute the (approximate) frames per second
90  return self._numFrames_numFrames / self.elapsedelapsed()
91 
92 
93 
94 
95 class DummyTask:
96  def __init__(self, data):
97  self.datadata = data
98  def ready(self):
99  return True
100  def get(self):
101  return self.datadata
102 
103 def main():
104  import sys
105 
106  try:
107  fn = sys.argv[1]
108  except:
109  fn = 0
110  cap = video.create_capture(fn)
111  fps = FPS().start()
112 
113 
114  def process_frame(frame, t0):
115  # some intensive computation...
116  frame = cv.medianBlur(frame, 19)
117  frame = cv.medianBlur(frame, 19)
118  return frame, t0
119 
120  threadn = cv.getNumberOfCPUs()
121  pool = ThreadPool(processes = threadn)
122  pending = deque()
123 
124  threaded_mode = True
125 
126  latency = StatValue()
127  frame_interval = StatValue()
128  last_frame_time = clock()
129  while True:
130  while len(pending) > 0 and pending[0].ready():
131  res, t0 = pending.popleft().get()
132  latency.update(clock() - t0)
133  draw_str(res, (20, 20), "threaded : " + str(threaded_mode))
134  draw_str(res, (20, 40), "latency : %.1f ms" % (latency.value*1000))
135  draw_str(res, (20, 60), "frame interval : %.1f ms" % (frame_interval.value*1000))
136  draw_str(res, (20, 80), "FPS : %.1f" % (1.0/frame_interval.value))
137  cv.imshow('threaded video', res)
138  if len(pending) < threadn:
139  _ret, frame = cap.read()
140  t = clock()
141  frame_interval.update(t - last_frame_time)
142  last_frame_time = t
143  if threaded_mode:
144  task = pool.apply_async(process_frame, (frame.copy(), t))
145  else:
146  task = DummyTask(process_frame(frame, t))
147  pending.append(task)
148  ch = cv.waitKey(1)
149  if ch == ord(' '):
150  threaded_mode = not threaded_mode
151  if ch == 27:
152  break
153  # update the FPS counter
154  fps.update()
155 
156  print('Done')
157 
158  # stop the timer and display FPS information
159  fps.stop()
160  print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
161  print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))
162 
163 if __name__ == '__main__':
164  print(__doc__)
165  main()
166  cv.destroyAllWindows()
def clock()
Definition: common.py:174
def draw_str(dst, target, s)
Definition: common.py:113