KHLin
September 21, 2022, 12:47am
1
Backgournd:
(1) I apply the opencv with wx.StaticBitmap to get image frame stream from my webcam.
(2) It is works above to get image stream and show.
But, when I set “scale” function, it not works. The following shows the code in python:
color transfer
image1 = cv2.cvtColor(self.im_rd, cv2.COLOR_BGR2RGB)
image stream from buffer
pic = wx.Bitmap.FromBuffer(width, height, image1)
attach to the StaticBitmap
self.m_bmp01.SetBitmap(pic)
Set Scale, but not works
self.m_bmp01.SetScaleMode(wx.StaticBitmap.Scale_AspectFill)
print(self.m_bmp01.GetScaleMode()) # always printout 0
I have no idea to figure out, need your help
Thanks for your reply
According to the documentation:
Currently only the generic implementation supports all scaling modes. You may use generic implementation GenericStaticBitmap declared in <wx/generic/statbmpg.h> in all ports.
Have you tried:
from wx.lib.statbmp import GenStaticBitmap as StaticBitmap
1 Like
When I was experimenting with opencv a while ago, I created the app below. This uses opencv’s resize() method to resize the images instead of using the StaticBitmap’s SetScaleMode().
When you resize the frame, the images are automatically resized while maintaining the original aspect ratio.
# Based on an example from:
# https://stackoverflow.com/questions/35009984/get-stream-from-webcam-with-opencv-and-wxpython
#
# To install cv2:
# pip install opencv-python
#
import cv2
import wx
from wx.lib.statbmp import GenStaticBitmap
INIT_SIZE = (640, 480)
FRAMES_PER_SECOND = 17
TIMER_INTERVAL = 1000 // FRAMES_PER_SECOND
class ViewWindow(wx.Frame):
def __init__(self, parent, capture, title="Webcam Viewer"):
super(ViewWindow, self).__init__(parent, title=title)
self.capture = capture
self.SetSize(INIT_SIZE)
self.SetBackgroundColour(wx.BLACK)
v_sizer = wx.BoxSizer(wx.VERTICAL)
h_sizer = wx.BoxSizer(wx.HORIZONTAL)
v_sizer.Add(h_sizer, 1, wx.ALIGN_CENTER_HORIZONTAL, 0)
image = wx.Image(INIT_SIZE)
bitmap = wx.Bitmap(image)
self.static_bitmap = GenStaticBitmap(self, wx.ID_ANY, bitmap)
h_sizer.Add(self.static_bitmap, 0, wx.ALIGN_CENTER_VERTICAL, 0)
self.SetSizer(v_sizer)
self.Layout()
self.refreshView()
self.timer = wx.Timer(self)
self.timer.Start(TIMER_INTERVAL)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
def refreshView(self):
res, video_frame = self.capture.read()
if res:
cv_image = cv2.cvtColor(video_frame, cv2.COLOR_BGR2RGB)
ih, iw = video_frame.shape[:2]
pw, ph = self.GetSize()
p_ratio = ph / pw
i_ratio = ih / iw
if p_ratio == i_ratio:
rw, rh = pw, ph
else:
if p_ratio > i_ratio:
rw = pw
rh = round(rw * i_ratio)
else: # p_ratio < i_ratio:
rh = ph
rw = round(rh / i_ratio)
cv_image = cv2.resize(cv_image, (rw, rh), interpolation=cv2.INTER_CUBIC)
bitmap = wx.Bitmap.FromBuffer(rw, rh, cv_image)
self.static_bitmap.SetBitmap(bitmap)
self.Refresh()
else:
print("Failed to get video-frame from webcam")
def OnTimer(self, _e):
self.refreshView()
def main():
app = wx.App()
capture = cv2.VideoCapture(0)
if capture.isOpened():
frame = ViewWindow(None, capture)
frame.Center()
frame.Show()
app.MainLoop()
else:
print("Failed to open the webcam.")
if __name__ == '__main__':
main()
Tested on Python 3.10.4 + wxPython 4.2.0 gtk3 (phoenix) wxWidgets 3.2.0 + Linux Mint 21
1 Like
KHLin
September 24, 2022, 12:11am
4
Hi, Richard,
Thanks for your information (including sample and concept), and it is works.
When I run this program and manual change the frame size, the captured frame also changed in the meanwhile