OpenCV与WXPython的集成 [英] Opencv integration with wxpython
问题描述
我只是想将网络摄像头中的opencv视频流集成到比highgui所能提供的更复杂的gui中,没有什么花哨的只是几个按钮和其他功能,但是事实证明这并不是那么简单.我找不到任何可以开始设计gui的基本示例. 我尝试将此代码转换为新的opencv界面效果很差.我是opencv,numpy和gui设计的新手.确实有一些时间流传输视频,但是大多数时候它只是挂在那里.我猜我的一个错误可能是wx.BitmapFromBuffer(col,row,img),因为在较旧的版本中,他们使用的是pil图像格式,而现在使用的是numpy数组,因此在原始代码中使用了pil函数"imageData",而不是在执行操作时直接传递numpy数组. 任何帮助,我们真的很感激.
I just wanted to integrate the opencv video stream from my web cam into a more complex gui than highgui can offer, nothing fancy just a couple of buttons and something else, however it's proven to be not that trivial. I can't find any base example from which I can start designing the gui. I tried converting this code to the new opencv interface with quite a poor result. I'm a new to opencv, numpy and gui design. Some time does stream the video but most of the time it just hangs there. I guess my one mistake might be in wx.BitmapFromBuffer(col, row, img) since in the older version they used pil image format and now it's using numpy arrays so in the original code the used the pil function "imageData", instead of passing directly the numpy array as I'm doing. Any help it's really appreciated.
这是我的代码转换.
import wx
import cv2
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent)
self.displayPanel = wx.Panel(self)
self.displayPanel.SetSize(wx.Size(800,640))
self.cam = cv2.VideoCapture(1)
self.cam.set(3, 640)
self.cam.set(4, 480)
ret, img = self.cam.read()
cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
row, col, x = img.shape
self.SetSize((col,row))
self.bmp = wx.BitmapFromBuffer(col, row, img)
self.displayPanel.Bind(wx.EVT_PAINT, self.onPaint)
self.playTimer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.onNextFrame)
self.playTimer.Start(1000/15)
def onPaint(self, evt):
if self.bmp:
dc = wx.BufferedPaintDC(self.displayPanel)
self.PrepareDC(dc)
dc.DrawBitmap(self.bmp, 0, 0, True)
evt.Skip()
def onNextFrame(self, evt):
ret, img = self.cam.read()
if ret == True:
cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
self.bmp.CopyFromBuffer(img)
self.displayPanel.Refresh()
evt.Skip()
if __name__=="__main__":
app = wx.App()
MyFrame(None).Show()
app.MainLoop()
推荐答案
下面的示例代码在OS X下对我来说很好用,但是我对跨平台的wx感到惊讶.几乎相同的代码,不同之处在于重新分配了cvtColor
的结果,并添加了wx.Panel
的子类(这是重要的部分).
The following example code works fine for me under OS X, but I've had tiny surprises with wx across platforms. It is nearly the same code, the difference is that the result from cvtColor
is reassigned, and a subclass of wx.Panel
(which is the important part) was added.
import wx
import cv, cv2
class ShowCapture(wx.Panel):
def __init__(self, parent, capture, fps=15):
wx.Panel.__init__(self, parent)
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)
capture.set(cv.CV_CAP_PROP_FRAME_WIDTH, 320)
capture.set(cv.CV_CAP_PROP_FRAME_HEIGHT, 240)
app = wx.App()
frame = wx.Frame(None)
cap = ShowCapture(frame, capture)
frame.Show()
app.MainLoop()
这篇关于OpenCV与WXPython的集成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!