官术网_书友最值得收藏!

Handling video streams

The video stream of the webcam is handled by a series of steps that begin with the __init__ method. These steps might appear overly complicated at first, but they are necessary in order to allow the video to run smoothly, even at higher frame rates (that is, to counteract flickering).

The wxPython module works with events and callback methods. When a certain event is triggered, it can cause a certain class method to be executed (in other words, a method can bind to an event). We will use this mechanism to our advantage and display a new frame every so often using the following steps:

  1. We create a timer that will generate a wx.EVT_TIMER event whenever 1000./self.fps milliseconds have passed:
        self.timer = wx.Timer(self)
self.timer.Start(1000. / self.fps)
  1. Whenever the timer is up, we want the _on_next_frame method to be called. It will try to acquire a new video frame:
        self.Bind(wx.EVT_TIMER, self._on_next_frame)
  1. The _on_next_frame method will process the new video frame and store the processed frame in a bitmap. This will trigger another event, wx.EVT_PAINT. We want to bind this event to the _on_paint method, which will paint the display of the new frame. So, we create a placeholder for the video and bind wx.EVT_PAINT to it:
        self.video_pnl.Bind(wx.EVT_PAINT, self._on_paint)

The _on_next_frame method grabs a new frame and, once done, sends the frame to another method, process_frame, for further processing (which is an abstract method and should be implemented by the child class):

    def _on_next_frame(self, event):
"""
Capture a new frame from the capture device,
send an RGB version to `self.process_frame`, refresh.
"""
success, frame = self._acquire_frame()
if success:
# process current frame
frame = self.process_frame(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
...

The processed frame (frame) is then stored in a bitmap buffer (self.bmp). Calling Refresh triggers the aforementioned wx.EVT_PAINT event, which binds to _on_paint:

            ...
# update buffer and paint (EVT_PAINT triggered by Refresh)
self.bmp.CopyFromBuffer(frame)
self.Refresh(eraseBackground=False)

The paint method then grabs the frame from the buffer and displays it:

    def _on_paint(self, event):
""" Draw the camera frame stored in `self.bmp` onto `self.video_pnl`.
"""
wx.BufferedPaintDC(self.video_pnl).DrawBitmap(self.bmp, 0, 0)

The next section shows you how to create a custom filter layout.

主站蜘蛛池模板: 云龙县| 思南县| 台东县| 麦盖提县| 云林县| 新竹市| 五家渠市| 湖南省| 夏邑县| 彰武县| 叙永县| 九江县| 牡丹江市| 和平区| 蓬溪县| 和平区| 兰溪市| 旬邑县| 新绛县| 益阳市| 山西省| 岱山县| 仙居县| 隆子县| 泊头市| 建瓯市| 萨嘎县| 曲靖市| 离岛区| 乾安县| 佳木斯市| 万山特区| 鄂托克前旗| 武汉市| 红原县| 施秉县| 贵南县| 安义县| 抚顺市| 洪泽县| 灯塔市|