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

Chris Colbert sccolbert@gmail....
Tue Feb 24 20:49:37 CST 2009


As an update for any future googlers:
the problem was with revpixels = pixeldata[::-1,:,;:-1] which apparently
returns an array that is discontinuous in memory. What Lisandro suggested
worked. pixeldata[::-1,:,;:-1].copy() returns a continuous array object
which natively implements a single-segment buffer interface. i.e. no
buffer(revpixels) is needed; just simply revpixels.

array.copy() is also 50% faster than array.tostring() on my machine.

Chris

On Tue, Feb 24, 2009 at 9:27 PM, Chris Colbert <sccolbert@gmail.com> wrote:

> thanks for both answers!
>
> Lisandro, you're right, I should have declared the array outside the loop.
> Thanks for catching that!
>
> Robert, as always, thanks for the answer. Quick and to the point! You've
> helped me more than once on the enthought list :)
>
>
>
> On Tue, Feb 24, 2009 at 8:06 PM, Lisandro Dalcin <dalcinl@gmail.com>wrote:
>
>> 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@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@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
>> _______________________________________________
>> Numpy-discussion mailing list
>> Numpy-discussion@scipy.org
>> http://projects.scipy.org/mailman/listinfo/numpy-discussion
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://projects.scipy.org/pipermail/numpy-discussion/attachments/20090224/4da19b58/attachment.html 


More information about the Numpy-discussion mailing list