Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv与wxpython的集成_Python_Opencv_Numpy_Wxpython_Python Imaging Library - Fatal编程技术网

Opencv与wxpython的集成

Opencv与wxpython的集成,python,opencv,numpy,wxpython,python-imaging-library,Python,Opencv,Numpy,Wxpython,Python Imaging Library,我只是想将我的网络摄像头中的opencv视频流集成到一个比highgui提供的更复杂的gui中,没有什么特别的,只是几个按钮和其他一些东西,但事实证明它并不是那么简单。我找不到任何可以开始设计gui的基本示例。 我尝试将其转换为新的opencv接口,但结果很差。我是opencv、numpy和gui设计的新手。有一段时间确实会播放视频,但大部分时间它只是挂在那里。我想我的一个错误可能是在wx.BitmapFromBuffer(col,row,img)中,因为在旧版本中他们使用了pil图像格式,现在

我只是想将我的网络摄像头中的opencv视频流集成到一个比highgui提供的更复杂的gui中,没有什么特别的,只是几个按钮和其他一些东西,但事实证明它并不是那么简单。我找不到任何可以开始设计gui的基本示例。 我尝试将其转换为新的opencv接口,但结果很差。我是opencv、numpy和gui设计的新手。有一段时间确实会播放视频,但大部分时间它只是挂在那里。我想我的一个错误可能是在wx.BitmapFromBuffer(col,row,img)中,因为在旧版本中他们使用了pil图像格式,现在它使用了numpy数组,所以在原始代码中使用了pil函数“imageData”,而不是像我这样直接传递numpy数组。 谢谢你的帮助。

这是我的代码转换

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

下面的示例代码在OSX下运行良好,但在wx跨平台运行时,我有一些小小的惊喜。它几乎是相同的代码,不同之处在于重新分配了
cvtColor
的结果,并添加了
wx.Panel
的子类(这是重要的部分)

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

您必须设置面板的大小以显示捕获的图像。 我使用了你的代码并添加了“


没关系

您应该为下面的行添加注释

#self.PrepareDC(dc)

它对我有效。

你的代码对我不起作用,但经过轻微调整后就可以了。我看到的问题是,例如,当我调整窗口大小时,流会被中断,直到我停止调整大小。但是如果我不触摸窗口,它就会正常运行。除了显示帧之外,你还在做其他事情吗?@mmgp你说得对如果我对设置大小的两行进行注释,它会起作用,尽管我想我失去了颜色通道。我附加了图片。关于颜色,
cvtColor
没有发生在适当的位置,因此您必须将其结果重新分配给
img
@mmgp。现在,除了显示捕获的帧,我没有执行任何其他操作,eve如果你有一个函数
f(x)
如果操作不到位,则必须将结果分配给某个对象才能保存结果。
cvtColor
就是这样一个函数。为什么要将panel子类化而不是frame?不应该是wx。frame是wx层次结构中的第一个“容器”?第二个导入也不会在OSX上工作,因为我想,要访问从cv2导入旧cv您需要导入cv2.cv。您的代码在我的机器上工作,顺便说一句,这是一台基于linux debian的机器,但是它没有将大小帧设置为640X480。我可以在OSX中导入
cv
很好。该帧当然没有设置为
640X480
,因为在示例中它被设置为
320x240
,您是否尝试过更改正在创建一个
wx.Frame
,它是
wx.Panel
子类的父类。我尝试用新模块和旧模块更改大小,但是一旦我调整大小,它就不再刷新,并且再次开始崩溃“您的意思是调整运行程序的窗口的大小吗?当我调整这个窗口的大小时,我也不再得到更新,正如前面评论的那样。但它不会使程序崩溃。你所说的崩溃是指程序退出?也许你收到的错误信息会有用。对不起,我没有说清楚,我的意思是它没有反应,并且停止了自我更新。
#self.PrepareDC(dc)