Displaying OpenCV iplimage data structures with wxPython

4.9k views Asked by At

Here is my current code (language is Python):

newFrameImage = cv.QueryFrame(webcam)
newFrameImageFile = cv.SaveImage("temp.jpg",newFrameImage)
wxImage = wx.Image("temp.jpg", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
wx.StaticBitmap(self, -1, wxImage, (0,0), (wxImage.GetWidth(), wxImage.GetHeight()))

I'm trying to display an iplimage captured from my webcam in a wxPython window. The problem is I don't want to store the image on hard disk first. Is there any way to convert an iplimage into another image format in memory? Any other solution?

I found a few "solutions" to this problem in other languages, but I'm still having trouble with this issue.

Thanks.

3

There are 3 answers

4
YOU On BEST ANSWER

You could do with StringIO

stream = cStringIO.StringIO(data)
wxImage = wx.ImageFromStream(stream)

you can check more detail in \wx\lib\embeddedimage.py

just my 2 cents.

1
Esteban Küber On

What you have to do is:

frame = cv.QueryFrame(self.cam) # Get the frame from the camera
cv.CvtColor(frame, frame, cv.CV_BGR2RGB) # Color correction
                         # if you don't do this your image will be greenish
wxImage = wx.EmptyImage(frame.width, frame.height) # If your camera doesn't give 
                         # you the stream size, you might have to use (640, 480)
wxImage.SetData(frame.tostring()) # convert from cv.iplimage to wxImage
wx.StaticBitmap(self, -1, wxImage, (0,0), 
                (wxImage.GetWidth(), wxImage.GetHeight()))

I figured oyt out how to do this by looking at the Python OpenCV cookbook and at the wxPython wiki.

0
Ezekiel Kruglick On

Yes, this question is old but I came here like everybody else searching for the answer. Several versions of wx, numpy, and opencv after the above solutions I figured I'd share a fast solution using cv2 and numpy images.

This is how to convert a NumPy array style image as used in OpenCV2 into a bitmap you can then set to a display element in wxPython (as of today):

import wx, cv2
import numpy as np

# Start with a numpy array style image I'll call "source"

# convert the colorspace to RGB from cv2 standard BGR, ensure input is uint8
img = cv2.cvtColor(np.uint8(source), cv2.cv.CV_BGR2RGB) 

# get the height and width of the source image for buffer construction
h, w = img.shape[:2]

# make a wx style bitmap using the buffer converter
wxbmp = wx.BitmapFromBuffer(w, h, img)

# Example of how to use this to set a static bitmap element called "bitmap_1"
self.bitmap_1.SetBitmap(wxbmp)

Tested 10 minutes ago :)

This uses the built in wx function BitmapFromBuffer and takes advantage of the NumPy buffer interface so that all we have to do is swap the colors to get those in the expected order.