使用 openCV 和 wxPython 从网络摄像头获取流
Posted
技术标签:
【中文标题】使用 openCV 和 wxPython 从网络摄像头获取流【英文标题】:Get stream from webcam with openCV and wxPython 【发布时间】:2016-05-02 18:55:26 【问题描述】:我已经阅读了互联网上关于这个主题的所有三个或四个当前主题,但到目前为止没有一个能准确回答这个问题。
虽然我对 FLTK 有一些经验,但我对 wxPython 还是很陌生。我是 OpenCV 的新手。
我正在尝试使用 openCV 从网络摄像头捕获图像并将该图像绘制到 wxPython 中。我取得了有限的成功(我可以得到一张图像并绘制它,但它很微弱并且没有正确对齐)。我可以确认我的网络摄像头和 openCV 正在独立工作,因为 sample code like this 可以正常工作。
这是我最近努力的一个例子,它是我从互联网上拼凑起来的,也是我自己对 opencv2 所做的努力。
import wx
import cv2
class viewWindow(wx.Frame):
imgSizer = (480,360)
def __init__(self, parent, title="View Window"):
super(viewWindow,self).__init__(parent)
self.pnl = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.image = wx.EmptyImage(self.imgSizer[0],self.imgSizer[1])
self.imageBit = wx.BitmapFromImage(self.image)
self.staticBit = wx.StaticBitmap(self.pnl,wx.ID_ANY,
self.imageBit)
self.vbox.Add(self.staticBit)
self.pnl.SetSizer(self.vbox)
self.timex = wx.Timer(self, wx.ID_OK)
self.timex.Start(1000/12)
self.Bind(wx.EVT_TIMER, self.redraw, self.timex)
self.capture = cv2.VideoCapture(0)
self.SetSize(self.imgSizer)
self.Show()
def redraw(self,e):
ret, frame = self.capture.read()
#print('tick')
self.imageBit = wx.BitmapFromImage(self.image)
self.staticBit = wx.StaticBitmap(self.pnl,
wx.ID_ANY, self.imageBit)
self.Refresh()
def main():
app = wx.PySimpleApp()
frame = viewWindow(None)
frame.Center()
frame.Show()
app.MainLoop()
if __name__ == '__main__':
main()
OpenCV 不是硬性要求(我对其他选项持开放态度,只要解决方案是跨平台的。如果我没记错的话,Gstreamer 不是跨平台的,PyGame 一直难以嵌入 wxPython,但我对想法持开放态度)。
wxPython 是一个硬性要求。
【问题讨论】:
wiki.videolan.org/Python_bindings 感谢您的建议。看起来很有希望。我仍然会坚持看看是否有人对 openCV 有深入了解,但 vlc 选项真的很值得了解! @bluekid 你会把你的评论转换成答案,所以我可以接受吗? 【参考方案1】:你可以试试这个修改过的代码,它应该将来自 opencv2 的网络摄像头图像显示到你的 wx python 环境中:
import wx
import cv2
class viewWindow(wx.Frame):
def __init__(self, parent, title="View Window"):
# super(viewWindow,self).__init__(parent)
wx.Frame.__init__(self, parent)
self.imgSizer = (480, 360)
self.pnl = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.image = wx.EmptyImage(self.imgSizer[0],self.imgSizer[1])
self.imageBit = wx.BitmapFromImage(self.image)
self.staticBit = wx.StaticBitmap(self.pnl, wx.ID_ANY, self.imageBit)
self.vbox.Add(self.staticBit)
self.capture = cv2.VideoCapture(0)
ret, self.frame = self.capture.read()
if ret:
self.height, self.width = self.frame.shape[:2]
self.bmp = wx.BitmapFromBuffer(self.width, self.height, self.frame)
self.timex = wx.Timer(self)
self.timex.Start(1000./24)
self.Bind(wx.EVT_TIMER, self.redraw)
self.SetSize(self.imgSizer)
else:
print "Error no webcam image"
self.pnl.SetSizer(self.vbox)
self.vbox.Fit(self)
self.Show()
def redraw(self,e):
ret, self.frame = self.capture.read()
if ret:
self.frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
self.bmp.CopyFromBuffer(self.frame)
self.staticBit.SetBitmap(self.bmp)
self.Refresh()
def main():
app = wx.PySimpleApp()
frame = viewWindow(None)
frame.Center()
frame.Show()
app.MainLoop()
if __name__ == '__main__':
main()
【讨论】:
【参考方案2】:如果 OpenCV 不是硬性要求
试试 libvlc 和它的 python 绑定
https://wiki.videolan.org/Python_bindings
【讨论】:
如果你有使用 libvlc+wxPython 的经验,也许你可以帮助我?我有两个问题:首先 - 我们无法将其日志从控制台中取出(应用程序在 our attempts 之后变得非常不稳定)其次 - 我们无法使视频垂直对齐顶部。 That's how我输出了。 VLC 播放器具有这样的功能,但 libvlc 占据了整个给定空间并将视频居中。 我们没有办法得到实际视频大小的windet(当然我们可以得到视频的尺寸并制作一个固定大小的面板,但我希望有更好的方法)如果你有一些答案,请在 GitHub 上打开一个问题或给我们写信给 Gitter,我真的需要知道这些东西的人。以上是关于使用 openCV 和 wxPython 从网络摄像头获取流的主要内容,如果未能解决你的问题,请参考以下文章