使用控制按钮使用 wxpython open-Cv 录制网络摄像头视频? [英] Record webcam video with wxpython open-Cv using control buttons?

查看:39
本文介绍了使用控制按钮使用 wxpython open-Cv 录制网络摄像头视频?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已设法使用 Open-CV 在 Wx-Python 窗口内流式传输网络摄像头视频,但我想使用控制按钮录制该视频.让我知道如何在单击按钮时捕获网络摄像头视频?

I have managed to stream a webcam video inside a Wx-Python window using Open-CV but i want to record that video using control buttons. Let me know how to capture a webcam video while a click a button?

import wx
import vlc
import numpy as np
import time
import os
import user
import cv2.cv

class MainWindow(wx.Panel):
    def __init__(self, parent,capture):
        wx.Panel.__init__(self, parent)
        mainSizer = wx.BoxSizer(wx.VERTICAL)

# video
       videoWarper = wx.StaticBox(self,size=(640,480))
       videoBoxSizer = wx.StaticBoxSizer(videoWarper, wx.VERTICAL)
       videoFrame = wx.Panel(self, -1,size=(640,480))
       capture = ShowCapture(videoFrame, capture)
       videoBoxSizer.Add(videoFrame,0)
       mainSizer.Add(videoBoxSizer,0)

       parent.Centre()
       self.Show()
       self.SetSizerAndFit(mainSizer)

# Panels
# The first panel holds the video and it's all black
       self.videopanel = wx.Panel(self, -1)
       self.videopanel.SetBackgroundColour(wx.BLACK)

# The second panel holds controls
       ctrlpanel = wx.Panel(self, -1 )
       self.timeslider = wx.Slider(ctrlpanel, -1, 0, 0, 1000)
       self.timeslider.SetRange(0, 1000)
       pause  = wx.Button(ctrlpanel, label="Pause")
       play   = wx.Button(ctrlpanel, label="Play")
       stop   = wx.Button(ctrlpanel, label="Stop")
       record = wx.Button(ctrlpanel, label="Record")
       cancel = wx.Button(ctrlpanel, label="Cancel")
       volume = wx.Button(ctrlpanel, label="Vol")
       self.volslider = wx.Slider(ctrlpanel, -1, 0, 0, 100, size=(100, -1))

# Bind controls to events
       self.Bind(wx.EVT_BUTTON, self.OnPlay, play)
       self.Bind(wx.EVT_BUTTON, self.OnPause, pause)
       self.Bind(wx.EVT_BUTTON, self.OnStop, stop)
       self.Bind(wx.EVT_BUTTON, self.OnRecord, record)
       self.Bind(wx.EVT_BUTTON, self.OnCancel, cancel)
       self.Bind(wx.EVT_BUTTON, self.OnToggleVolume, volume)
       self.Bind(wx.EVT_SLIDER, self.OnSetVolume, self.volslider)

# Give a pretty layout to the controls
       ctrlbox = wx.BoxSizer(wx.VERTICAL)
       box = wx.BoxSizer(wx.HORIZONTAL)

# box contains some buttons and the volume controls
       box.Add(play, flag=wx.RIGHT, border=5)
       box.Add(pause)
       box.Add(stop)
       box.Add(record)
       box.Add(cancel)
       box.Add((-1, -1), 1)
       box.Add(volume)
       box.Add(self.volslider, flag=wx.TOP | wx.LEFT, border=5)

# Merge box1 and box2 to the ctrlsizer
       ctrlbox.Add(box, flag=wx.EXPAND, border=10)
       ctrlpanel.SetSizer(ctrlbox)

# Put everything togheter
       sizer = wx.BoxSizer(wx.VERTICAL)
       sizer.Add(ctrlpanel, flag=wx.EXPAND | wx.BOTTOM | wx.TOP, border=10)
       self.SetSizer(sizer)
       self.SetMinSize((350, 300))

# finally create the timer, which updates the timeslider
       self.timer = wx.Timer(self)
       self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)

# VLC player controls
       self.Instance = vlc.Instance()
       self.player = self.Instance.media_player_new()

    def OnClose(self, evt):
       """Closes the window.
       """
       self.Close()

    def OnOpen(self, evt):
       """Pop up a new dialow window to choose a file, then play the selected file.
       """
# if a file is already running, then stop it.
       self.OnStop(None)

# Create a file dialog opened in the current home directory, where
# you can display all kind of files, having as title "Choose a file".
       dlg = wx.FileDialog(self, "Choose a file", user.home, "",
                        "*.*", wx.OPEN)
       if dlg.ShowModal() == wx.ID_OK:
           dirname = dlg.GetDirectory()
           filename = dlg.GetFilename()
# Creation
       self.Media =  self.Instance.media_new(unicode(os.path.join(dirname, filename)))
       self.player.set_media(self.Media)
# Report the title of the file chosen
       title = self.player.get_title()
# if an error was encountred while retriving the title, then use
# filename
       if title == -1:
           title = filename
           self.SetTitle("%s - wxVLCplayer" % title)

# set the window id where to render VLC's video output
       self.player.set_xwindow(self.videopanel.GetHandle())
# FIXME: this should be made cross-platform
       self.OnPlay(None)

# set the volume slider to the current volume
      self.volslider.SetValue(self.player.audio_get_volume() / 2)

# finally destroy the dialog
      dlg.Destroy()

    def OnPlay(self, evt):
      """Toggle the status to Play/Pause.

      If no file is loaded, open the dialog window.
      """
# check if there is a file to play, otherwise open a
# wx.FileDialog to select a file
      if not self.player.get_media():
        self.OnOpen(None)
      else:
# Try to launch the media, if this fails display an error message
        if self.player.play() == -1:
            self.errorDialog("Unable to play.")
        else:
            self.timer.Start()

    def OnPause(self, evt):
      """Pause the player.
      """
      self.player.pause()

    def OnStop(self, evt):
      """Stop the player.
      """
      self.player.stop()
# reset the time slider
      self.timeslider.SetValue(0)
      self.timer.Stop()

# -------begin capturing and saving video
    def OnRecord(self, evt):
      capture=cv2.VideoCapture(0)
      if (not capture.isOpened()):
        print "Error"    
# video recorder
# Define the codec and create VideoWriter object
      fourcc = cv2.cv.FOURCC('M','P','E','G')
      out = cv2.VideoWriter('output.mp4',fourcc, 20.0, (640,480), isColor=True)    
      while(capture.isOpened()):
         ret, frame = capture.read()
         if ret==True:
# write the flipped frame
             out.write(frame) 
             cv2.imshow('frame',frame)
             if cv2.waitKey(1) & 0xFF == ord('q'):
                 break
         else:
             break

   def OnCancel(self, evt):
      out = cv2.VideoWriter()
      capture.release()
      out.release()
      cv2.destroyAllWindows()

   def OnTimer(self, evt):
      """Update the time slider according to the current movie time.
      """
# since the self.player.get_length can change while playing,
# re-set the timeslider to the correct range.
      length = self.player.get_length()
      self.timeslider.SetRange(-1, length)

# update the time on the slider
      time = self.player.get_time()
      self.timeslider.SetValue(time)

   def OnToggleVolume(self, evt):
      """Mute/Unmute according to the audio button.
      """
      is_mute = self.player.audio_get_mute()

      self.player.audio_set_mute(not is_mute)
# update the volume slider;
# since vlc volume range is in [0, 200],
# and our volume slider has range [0, 100], just divide by 2.
      self.volslider.SetValue(self.player.audio_get_volume() / 2)

   def OnSetVolume(self, evt):
      """Set the volume according to the volume sider.
      """
      volume = self.volslider.GetValue() * 2
# vlc.MediaPlayer.audio_set_volume returns 0 if success, -1 otherwise
      if self.player.audio_set_volume(volume) == -1:
          self.errorDialog("Failed to set volume")

class ShowCapture(wx.Panel):

   def __init__(self, parent, capture, fps=24):
      wx.Panel.__init__(self, parent, wx.ID_ANY, (0,0), (640,480))

      self.capture = capture
      ret, frame = self.capture.read()

      height, width = frame.shape[:2]

      parent.SetSize((width, height))

      frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

      self.bmp = wx.BitmapFromBuffer(width, height, frame)

      self.timer = wx.Timer(self)
      self.timer.Start(1000./fps)

      self.Bind(wx.EVT_PAINT, self.OnPaint)
      self.Bind(wx.EVT_TIMER, self.NextFrame)

   def OnPaint(self, evt):
      dc = wx.BufferedPaintDC(self)
      dc.DrawBitmap(self.bmp, 0, 0)

   def NextFrame(self, event):
      ret, frame = self.capture.read()
      if ret:
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        self.bmp.CopyFromBuffer(frame)
        self.Refresh()

capture = cv2.VideoCapture(0)

app = wx.App(False)
frame = wx.Frame(None, title='CamGUI')
panel = MainWindow(frame,capture)
frame.Show()
app.MainLoop()

推荐答案

我已经修改了您的代码,以便控制按钮出现、可见且具有功能.但是你仍然需要在函数上工作.您还可以对滑块进行编程以跳转到视频中的点:

I have modified your code so that control buttons come up, are visible and have functions. But you still have to work on the functions. You could also program the slider to jump to the points in the video:

import wx
import vlc
import numpy as np
import sys
import time
import os
import user
import cv2.cv

class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent)
        self.size = (640,480)
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.title = title
        self.SetTitle(self.title)
        self.panel = wx.Panel(self)
        # video
        self.Playing = False
        self.capture = cv2.VideoCapture(0)
        self.videoFrame = wx.Panel(self.panel, -1, size=self.size)
        image = wx.EmptyImage(self.size[0], self.size[1])
        imageBitmap = wx.BitmapFromImage(image)
        self.videobmp = wx.StaticBitmap(self.videoFrame, wx.ID_ANY, imageBitmap)
        self.ShowCapture()

        videoSizer = wx.BoxSizer(wx.HORIZONTAL)
        videoSizer.Add(self.videoFrame, 0)

        mainSizer.Add(videoSizer, 0)

        # The second panel holds controls
        ctrlbox = wx.BoxSizer(wx.VERTICAL)
        # ctrlpanel = wx.Panel(self, -1 )
        self.timeslider = wx.Slider(self.panel, -1, 0, 0, 1000)
        self.timeslider.SetRange(0, 1000)
        ctrlbox.Add(self.timeslider, flag=wx.EXPAND, border=10)
        box = wx.BoxSizer(wx.HORIZONTAL)
        pause  = wx.Button(self.panel, label="Pause")
        play   = wx.Button(self.panel, label="Play")
        stop   = wx.Button(self.panel, label="Stop")
        record = wx.Button(self.panel, label="Record")
        cancel = wx.Button(self.panel, label="Cancel")
        volume = wx.Button(self.panel, label="Vol")
        self.volslider = wx.Slider(self.panel, -1, 0, 0, 100, size=(100, -1))
        self.volslider.SetValue(50)
        # Bind controls to events
        self.Bind(wx.EVT_BUTTON, self.OnPlay, play)
        self.Bind(wx.EVT_BUTTON, self.OnPause, pause)
        self.Bind(wx.EVT_BUTTON, self.OnStop, stop)
        self.Bind(wx.EVT_BUTTON, self.OnRecord, record)
        self.Bind(wx.EVT_BUTTON, self.OnCancel, cancel)
        self.Bind(wx.EVT_BUTTON, self.OnToggleVolume, volume)
        self.Bind(wx.EVT_SLIDER, self.OnSetVolume, self.volslider)

        # box contains some buttons and the volume controls
        box.Add(play, flag=wx.RIGHT, border=5)
        box.Add(pause)
        box.Add(stop)
        box.Add(record)
        box.Add(cancel)
        box.Add((-1, -1), 1)
        box.Add(volume)
        box.Add(self.volslider, flag=wx.TOP | wx.LEFT, border=5)

        # Merge box1 and box2 to the ctrlsizer
        ctrlbox.Add(box, flag=wx.EXPAND, border=10)
        # ctrlpanel.SetSizer(ctrlbox)
        mainSizer.Add(ctrlbox, 0)

        # finally create the timer, which updates the timeslider
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)

        # VLC player controls
        self.Instance = vlc.Instance()
        self.player = self.Instance.media_player_new()

        self.panel.SetSizer(mainSizer)
        mainSizer.Fit(self)
        # self.SetSizerAndFit(mainSizer)
        self.Centre()
        self.Show()

    def OnClose(self, evt):
       """Closes the window.
       """
       # self.Close()
       self.Destroy()

    def OnOpen(self, evt):
       """Pop up a new dialow window to choose a file, then play the selected file.
       """
       # if a file is already running, then stop it.
       self.OnStop(None)

       # Create a file dialog opened in the current home directory, where
       # you can display all kind of files, having as title "Choose a file".
       dlg = wx.FileDialog(self, "Choose a file", user.home, "",
                        "*.*", wx.OPEN)
       if dlg.ShowModal() == wx.ID_OK:
           self.Playing = True
           dirname = dlg.GetDirectory()
           filename = dlg.GetFilename()
           # Creation
           self.Media =  self.Instance.media_new(unicode(os.path.join(dirname, filename)))
           self.player.set_media(self.Media)
           # Report the title of the file chosen
           title = self.player.get_title()
           # if an error was encountred while retriving the title, then use
           # filename
           if title == -1:
               title = filename
               self.SetTitle("%s - wxVLCplayer" % title)

           # set the window id where to render VLC's video output
           # set the window id where to render VLC's video output

           # handle = self.videopanel.GetHandle()
           handle = self.videoFrame.GetHandle()
           if sys.platform.startswith('linux'): # for Linux using the X Server
               self.player.set_xwindow(handle)
           elif sys.platform == "win32": # for Windows
               self.player.set_hwnd(handle)
           elif sys.platform == "darwin": # for MacOS
               self.player.set_nsobject(handle)

           self.OnPlay(None)

           # set the volume slider to the current volume
           self.volslider.SetValue(self.player.audio_get_volume() / 2)

           # finally destroy the dialog
       dlg.Destroy()

    def OnPlay(self, evt):
      """Toggle the status to Play/Pause.

      If no file is loaded, open the dialog window.
      """
      # check if there is a file to play, otherwise open a
      # wx.FileDialog to select a file
      if not self.player.get_media():
        self.OnOpen(None)
      else:
      # Try to launch the media, if this fails display an error message
        if self.player.play() == -1:
            self.errorDialog("Unable to play.")
        else:
            self.timer.Start()
            self.Playing = True

    def OnPause(self, evt):
      """Pause the player.
      """
      self.player.pause()
      self.Playing = True

    def OnStop(self, evt):
      """Stop the player.
      """
      self.player.stop()
      # reset the time slider
      self.timeslider.SetValue(0)
      self.timer.Stop()
      self.Playing = False

      # -------begin capturing and saving video
    def OnRecord(self, evt):
      # capture=cv2.VideoCapture(0)
      if (not self.capture.isOpened()):
        print "Error"    
      # video recorder
      # Define the codec and create VideoWriter object
      fourcc = cv2.cv.FOURCC('M','P','E','G')
      out = cv2.VideoWriter('output.mp4',fourcc, 20.0, (640,480), isColor=True)    
      while(self.capture.isOpened()):
         ret, frame = self.capture.read()
         if ret==True:
             # write the flipped frame
             out.write(frame) 
             cv2.imshow('frame',frame)
             if cv2.waitKey(1) & 0xFF == ord('q'):
                 break
         else:
             break

    def OnCancel(self, evt):
      out = cv2.VideoWriter()
      self.capture.release()
      out.release()
      cv2.destroyAllWindows()

    def OnTimer(self, evt):
      """Update the time slider according to the current movie time.
      """
      # since the self.player.get_length can change while playing,
      # re-set the timeslider to the correct range.
      length = self.player.get_length()
      self.timeslider.SetRange(-1, length)

      # update the time on the slider
      time = self.player.get_time()
      self.timeslider.SetValue(time)

    def OnToggleVolume(self, evt):
      """Mute/Unmute according to the audio button.
      """
      is_mute = self.player.audio_get_mute()

      self.player.audio_set_mute(not is_mute)
      # update the volume slider;
      # since vlc volume range is in [0, 200],
      # and our volume slider has range [0, 100], just divide by 2.
      self.volslider.SetValue(self.player.audio_get_volume() / 2)

    def OnSetVolume(self, evt):
      """Set the volume according to the volume sider.
      """
      volume = self.volslider.GetValue() * 2
      # vlc.MediaPlayer.audio_set_volume returns 0 if success, -1 otherwise
      if self.player.audio_set_volume(volume) == -1:
          self.errorDialog("Failed to set volume")

    def ShowCapture(self, fps=24):
      ret, self.frame = self.capture.read()
      self.height, self.width = self.frame.shape[:2]
      # self.SetSize((self.width, self.height))
      self.frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
      self.bmp = wx.BitmapFromBuffer(self.width, self.height, self.frame)
      self.timer2 = wx.Timer(self)
      self.timer2.Start(1000./fps)
      # self.Bind(wx.EVT_PAINT, self.OnPaint)
      self.Bind(wx.EVT_TIMER, self.NextFrame)

    # def OnPaint(self, evt):
    #   dc = wx.BufferedPaintDC(self)
    #   dc.DrawBitmap(self.bmp, 0, 0)

    def NextFrame(self, event):
      if not self.Playing:
        ret, self.frame = self.capture.read()
        if ret:
          self.frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
          self.bmp.CopyFromBuffer(self.frame)
          self.videobmp.SetBitmap(self.bmp)
          self.Refresh()

app = wx.App(False)
frame = MainWindow(None, title='CamGUI')
frame.Show()
app.MainLoop()

这篇关于使用控制按钮使用 wxpython open-Cv 录制网络摄像头视频?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆