I'm trying to display OpenCV with Python interface in wxPython. I can display it but only a small region in the top left corner of the video. What is the problem with my code? is it the size of parent panel or something else? note that I use code from this https://stackoverflow.com/a/14818080/2389238 and It can run perfectly but I need to display it in a panel (or other parent frame).
Thank in Advance.
import wx
import cv, cv2
class MainWindow(wx.Panel):
def __init__(self, parent,capture):
wx.Panel.__init__(self, parent)
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.inputBox = wx.TextCtrl(self)
mainSizer.Add(self.inputBox, 0, wx.ALL, 5)
# video
videoWarper = wx.StaticBox(self, label="Video",size=(640,480))
videoBoxSizer = wx.StaticBoxSizer(videoWarper, wx.VERTICAL)
videoFrame = wx.Panel(self, -1,size=(640,480))
cap = ShowCapture(videoFrame, capture)
videoBoxSizer.Add(videoFrame,0)
mainSizer.Add(videoBoxSizer,0)
parent.Centre()
self.Show()
self.SetSizerAndFit(mainSizer)
class ShowCapture(wx.Panel):
def __init__(self, parent, capture, fps=24):
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)
app = wx.App(False)
frame = wx.Frame(None,-1,'HGA Count',size=(400, 400))
panel = MainWindow(frame,capture)
frame.Show()
app.MainLoop()
This is the image: http://i58.tinypic.com/2u5t7kh.png Sorry for the link I can't put image here due to low reputation.
Basically, nothing sets your ShowCapture
window size to the desired size, so it remains stuck at some default size. The simplest solution would probably be to do without videoFrame
at all as it seems to be not needed and just create cap
itself with the desired initial size, which will also become the minimal window size.
Follow up after the question update:
wxVERTICAL
box sizer, horizontal for... you guessed it) or wxEXPAND
flag if you want it to grow in the other direction. Or both, of course, if you want it to grow in both direction.videoFrame
is not necessary and, in fact, you ought to make your video window child of videoWarper
if you're using 3.0 for the best results: since 3.0, the contents of a wxStaticBoxSizer
should be created with its wxStaticBox
as parent.