2016-06-22 4 views
0

Мне удалось передать видео в веб-камеру внутри окна Wx-Python с помощью Open-CV, но я хочу записать это видео с помощью кнопок управления. Дайте мне знать, как захватить видео в веб-камеру, нажав кнопку?Запись видео в веб-камере с помощью wxpython open-Cv с помощью кнопок управления?

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() 

ответ

0

Я изменил ваш код, чтобы кнопки управления отображались, видны и имеют функции. Но вам все равно придется работать над функциями. Вы также можете запрограммировать ползунок для перехода к точкам видео:

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() 

 Смежные вопросы

  • Нет связанных вопросов^_^