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

Lisandro Dalcin dalcinl at gmail.com
Tue Feb 24 20:06:21 EST 2009


When you do pixeldata[::-1,:,::-1], you just got a new array with
different strides, but now non-contiguous... So I believe you really
need a fresh copy of the data... tostring() copies, but could be
slow... try to use

revpixels = pixeldata[::-1,:,::-1].copy()

...

rgbBMP = wx.BitmapFromBuffer(640, 480, buffer(revpixels))


Perhaps you could optimize this by declaring revpixels outside de
loop, and then inside de loop doing

revpixels[...] = pixeldata[::-1,:,::-1]


This way you will save the mem allocation of revpixels at each step of the loop.





On Tue, Feb 24, 2009 at 9:15 PM, Chris Colbert <sccolbert at gmail.com> wrote:
> 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 ######
>
> _______________________________________________
> Numpy-discussion mailing list
> Numpy-discussion at scipy.org
> http://projects.scipy.org/mailman/listinfo/numpy-discussion
>
>



-- 
Lisandro Dalcín
---------------
Centro Internacional de Métodos Computacionales en Ingeniería (CIMEC)
Instituto de Desarrollo Tecnológico para la Industria Química (INTEC)
Consejo Nacional de Investigaciones Científicas y Técnicas (CONICET)
PTLC - Güemes 3450, (3000) Santa Fe, Argentina
Tel/Fax: +54-(0)342-451.1594



More information about the NumPy-Discussion mailing list