[Numpy-discussion] is there a faster way to get a buffer interface than ndarray.tostring()?
Andrew Straw
strawman@astraw....
Wed Feb 25 00:22:05 CST 2009
Given what you're doing, may I also suggest having a look at
http://code.astraw.com/projects/motmot/wxglvideo.html
-Andrew
Chris Colbert wrote:
> 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
> <mailto: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
> <mailto: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 <mailto: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 <mailto: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 <mailto:Numpy-discussion@scipy.org>
> http://projects.scipy.org/mailman/listinfo/numpy-discussion
>
>
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Numpy-discussion mailing list
> Numpy-discussion@scipy.org
> http://projects.scipy.org/mailman/listinfo/numpy-discussion
More information about the Numpy-discussion
mailing list