[Numpy-discussion] is there a faster way to get a buffer interface than ndarray.tostring()?

Chris Colbert sccolbert@gmail....
Tue Feb 24 18:15:20 CST 2009


Hi all,

 I'm new to mailing list and relatively new (~1 year) to python/numpy. I
would appreciate any insight any of you may have here. The last 8 hours of
digging through the docs has left me, finally, stuck.

I am making a wxPython program that includes webcam functionality. The
script below just brings up a simple display window that shows the webcam
feed. The problem I am running into is in the WebCamWorker.run() method.
This method reads the raw pixel data (in string form) from the webcam
buffer. This data (thank you microsoft!) comes in BGR and bottom-to-top. I
feed this buffer to the array constructor and then swap the pixel order to
RGB and top-to-bottom. This all happens very fast, ~1ms on a Quad Core, and
the majority of that time is spent constructing the array (the numpy pixel
swapping is on the order of E-5s !). The tostring() method, however, takes a
whopping 10ms to execute. Unfortunately, the wx.BitmapFromBuffer needs a
single segment buffer interface as an argument. Is there a way to expose my
numpy array as a buffer to cut down on this conversion time?

I have tried sending the array to the PIL Image.fromarray(), but that
eventually requires me to do a Image.tostring() anyway, which negates any
benefit.

Thanks in advance for the help!

S. Chris Colbert
Rehabilitation Robotics Laboratory
University of South Florida


####  Code #######

import VideoCapture
import wx
import time
import threading
import numpy as np
import Image


class WebCamWorker(threading.Thread):
    _abort = 0

    def __init__(self, parent):
        super(WebCamWorker, self).__init__()

        self._parent = parent
        self.panel = wx.Panel(parent)

    def run(self):

        while not self._abort:

            #numpy arrays reverse pixel data that comes in from CCD as BGR
and bottom to top

            pixeldata = np.ndarray((480,640,3),
buffer=webcam.getBuffer()[0], dtype='u1')
            revpixels = pixeldata[::-1,:,::-1].tostring()      #tostring is
an order of magnitude slower than the entire array manipulation. need a
faster method.

            rgbBMP = wx.BitmapFromBuffer(640, 480, revpixels)
            dc = wx.ClientDC(self.panel)
            dc.DrawBitmap(rgbBMP, 0, 0)
            #b = time.clock()
            #print b-a
            time.sleep(0.015)


        return



class TestWxWebCam(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, size=(640,480))

        self.worker = WebCamWorker(self)
        self.worker.start()



class TestApp(wx.App):
    def OnInit(self):
        self.frame = TestWxWebCam(None)
        self.frame.Show()

        return True

    def OnExit(self):
        WebCamWorker._abort = 1 #this is a hack


if __name__ == '__main__':
    webcam = VideoCapture.Device()
    webcam.setResolution(640, 480)
    webcam.displayCapturePinProperties()
    app = TestApp()
    app.MainLoop()
    del webcam


### /Code ######
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://projects.scipy.org/pipermail/numpy-discussion/attachments/20090224/3df3d854/attachment-0001.html 


More information about the Numpy-discussion mailing list