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 <sccolb...@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 <dalc...@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 <sccolb...@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 >> > >
_______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion