Fast capture and 2D image stacking as 3D numpy array with Python and Raspberry Pi

I'm working on a Raspberry Pi project in which I need to take about 30 imag es per second (no movie) and stack each 2D image to a 3D array using numpy array, without saving each 2D capture as a file (because is slow).

I found this Python code to take images as fast as possible, but i don't kn ow how to stack all images fast to a 3D stack of images.

import io import time import picamera #from PIL import Image

def outputs(): stream = io.BytesIO() for i in range(40): # This returns the stream for the camera to capture to yield stream # Once the capture is complete, the loop continues here # (read up on generator functions in Python to understand # the yield statement). Here you could do some processing # on the image... #stream.seek(0) #img = Image.open(stream) # Finally, reset the stream for the next capture stream.seek(0) stream.truncate()

with picamera.PiCamera() as camera: camera.resolution = (640, 480) camera.framerate = 80 time.sleep(2) start = time.time() camera.capture_sequence(outputs(), 'jpeg', use_video_port=True) finish = time.time() print('Captured 40 images at %.2ffps' % (40 / (finish - start)))

Does anyone of you know how to stack the 2D images taken in this code to a

3D numpy array using Python and the Raspberry Pi camera module? Without sav ing each 2D capture as a file
Reply to
Agustin Cruz
Loading thread data ...

Write the files to an in-memory temporary filing system, from where you can read them out more slowly, saving them somewhere more permanent before clearing the temporary storage.

--
martin@   | Martin Gregorie 
gregorie. | Essex, UK 
 Click to see the full signature
Reply to
Martin Gregorie

o

Hi Martin, Im intending to take many pictures very fast and perform some processing la ter. I think is possible to stack each 2D image to a 3D array using dstack and numpy array. And when finish capturing and stacking I can save each 2D picture as individual files (because encoding to jpg is a slow process).

Im new in Python, but I managed to take 80 pictures per second at 640x480 w ith the picamera. The problem is that I don't know how to create and save t he stack of pictures.

Reply to
Agustin Cruz

I don't have a PiCamera and I find that construct a bit confusing. Anyway, if the comment in the outputs() function is correct, a BytesIO buffer filled with bytes is accessible for each frame following the "yield stream" line. To get the minimum processing overhead during the capture, I'd suggest initially creating a _two_ dimensional numpy array, to place all the bytes from each frame into each row of the array. Put this at the start:

capt=numpy.ndarray(shape=(40,480*640), dtype=numpy.int8)

That assumes a byte for each pixel (which is probably wrong), so you'll have to figure out how the colour is represented, and how many bytes for each pixel is needed.

Then, in the outputs() function, after the yield line, where it says "Here you could do some processing", insert the line:

capt[i,:] = bytearray(stream.getvalue())

Afterwards, you can reshape the completed array with the numpy reshape command to however you want it ordered.

Reply to
Dave Farrance

But why the heck is it clearing the buffers for each frame? That BytesIO buffer could hold the whole lot.

Remove the "stream = io.BytesIO()" from the function and put it above the function as a global variable.

Comment out the "stream.seek(0)" and "stream.truncate()" lines.

Then at the _end_ of the script put:

capt = numpy.array(bytearray(stream.getvalue()))

Then reshape this one-dimensional array as required.

Reply to
Dave Farrance

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.