5

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.

Dom M.
  • 3,762
  • 8
  • 32
  • 40

3 Answers3

6

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.

Esteban Küber
  • 36,388
  • 15
  • 79
  • 97
  • 1
    I'm well aware that this post is a year old, but it's the current highest ranking SO question on Google for this problem. – Esteban Küber Jul 27 '10 at 14:37
3

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.

Ezekiel Kruglick
  • 4,496
  • 38
  • 48
1

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.

YOU
  • 120,166
  • 34
  • 186
  • 219
  • Could you elaborate a little? Where does data come from? – Dom M. Nov 19 '09 at 06:46
  • I have found that opencv does not have api to write ImageData into stream http://opencv.jp/opencv-1.0.0_org/docs/ref/opencvref_highgui.htm#highgui_func_index so finding some other ways. – YOU Nov 19 '09 at 07:33
  • Thank you for even trying, I appreciate it – Dom M. Nov 19 '09 at 07:39
  • Seems there is direct converter from ipl images to wxImage http://www.koders.com/cpp/fid4A270123EB2BF8B15C8F6F620770EA6D2821F509.aspx?s=opencv but seems like we need to port to python ourselves because its c++, * IPL image structure is seems based on RGB format too. http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.html#SECTION00041000000000000000 – YOU Nov 19 '09 at 08:53