0
Open-CVを使用してWx-Pythonウィンドウ内にウェブカメラビデオをストリーミングできましたが、コントロールボタンを使用してそのビデオを記録したいと思います。ボタンをクリックしているときにウェブカメラのビデオをキャプチャする方法を教えてください。コントロールボタンを使用して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()