Opencv integration with wxpython

I just wanted to integrate the opencv video stream from my webcam into a more complex gui than highgui can offer, nothing is just a few buttons and something else, but it turned out to be not so trivial. I cannot find a basic example from which I can start gui design. I tried to convert this codeinto the new opencv interface with a pretty bad result. I am new to opencv, numpy and gui design. For some time the video stream, but most of the time it just hangs there. I assume that my one mistake could be in wx.BitmapFromBuffer (col, row, img), because in the old version they used the saw image format, and now it uses numpy arrays, so the pil function “imageData" is used in the source code, and not passing directly the numpy array as I do it. Any help he really appreciated. color_channels_pic

This is my code conversion.

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()
+6
source share
3 answers

OS X, 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()
+11

, . , "

self.SetSize(width,height)

0

, , , , wx.Python 2.8. Phoenix (> 4.00) . , ? :

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import numpy as np
import cv2
import wx
import sys, time
wxversion = wx.__version__

class webcamPanel(wx.Panel):
    def __init__(self, parent, camera, fps=10, pause=False, mirror=False):
        wx.Panel.__init__(self, parent)
        self.camera = camera
        return_value, self.frame = self.camera.read()
        height, width = self.frame.shape[:2]
        self.frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
        if mirror:
            self.frame = cv2.flip(self.frame, 1)
        if wxversion[0] == "2":
            self.bmp = wx.BitmapFromBuffer(width, height, self.frame)
        else:
            self.bmp = wx.Bitmap.FromBuffer(width, height, self.frame)
        self.SetSize((width,height))
        self.pause = pause
        self.mirror = mirror
        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 GetState(self):
        return self.pause

    def Kill(self):
        self.Pause()
        self.timer.Stop()

    def Mirror(self, mirror=None):
        if mirror is None:
            self.mirror = not self.mirror
        else:
            self.mirror = mirror

    def OnPaint(self, e):
        dc = wx.BufferedPaintDC(self)
        dc.DrawBitmap(self.bmp, 0, 0)

    def Pause(self):
        self.pause = True

    def Start(self):
        self.pause = False

    def NextFrame(self, e):
        if not self.pause:
            return_value, self.frame = self.camera.read()
            if return_value:
                self.frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
                if self.mirror:
                    self.frame = cv2.flip(self.frame, 1)
                self.bmp.CopyFromBuffer(self.frame)
                self.Refresh()

class mainWindow(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, style=wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN)
        self.Bind(wx.EVT_CLOSE, self.CloseApp)

        # Creating any menubar.
        filemenu= wx.Menu()
        filemenu.Append(101, "Open", "Open")
        filemenu.Append(102, "Save", "Save")
        filemenu.Append(wx.ID_ABOUT, "About","About")
        filemenu.Append(wx.ID_EXIT,"Exit","Close")
        menuBar = wx.MenuBar()
        menuBar.Append(filemenu,"File")
        self.SetMenuBar(menuBar)

        #main ui
        self.camera = cv2.VideoCapture(0)
        return_value, frame = self.camera.read()
        self.mirror = True
        self.height, self.width, _ = frame.shape
        self.iteration = 0
        self.webcampanel = webcamPanel(self, self.camera, mirror=self.mirror)
        self.button = wx.Button(self, label="Take Picture!")
        self.button1 = wx.Button(self, label="Toggle Camera on/off")
        self.button2 = wx.Button(self, label="Mirror")

        main_window_sizer = wx.BoxSizer(wx.VERTICAL)
        main_window_sizer.Add(self.webcampanel, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 10)
        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        buttonSizer.Add(self.button, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 10)
        buttonSizer.Add(self.button1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 10)
        buttonSizer.Add(self.button2, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 10)
        main_window_sizer.Add(buttonSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 10)
        self.SetSizer(main_window_sizer)
        main_window_sizer.Fit(self)

        self.Bind(wx.EVT_BUTTON, self.take_picture, self.button)
        self.Bind(wx.EVT_BUTTON, self.toggle, self.button1)
        self.Bind(wx.EVT_BUTTON, self.toggle_mirror, self.button2)

    def toggle_mirror(self, event):
        self.webcampanel.Mirror()

    def take_picture(self, e):
        image = self.webcampanel.frame
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        # show the image in a new window!
        cv2.imshow('Snapshot!', image)

    def toggle(self, event):
        if self.webcampanel.GetState(): # pause
            self.webcampanel.Start()
        else:
            self.webcampanel.Pause()

    def CloseApp(self, event):
        self.webcampanel.Kill()
        time.sleep(.2)
        self.camera.release()
        cv2.destroyAllWindows()
        self.Destroy()
        sys.exit()

if __name__ == '__main__':
    app = wx.App()
    window = mainWindow()
    window.Show()
    window.Maximize()
    app.MainLoop()
0

All Articles