Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.sys.raspberry-pi > #9055 > unrolled thread

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

Started byAgustin Cruz <agustin.cruz@gmail.com>
First post2015-07-06 14:36 -0700
Last post2015-07-07 11:12 +0100
Articles 4 — 3 participants

Back to article view | Back to comp.sys.raspberry-pi


Contents

  Fast capture and 2D image stacking as 3D numpy array with Python and Raspberry Pi Agustin Cruz <agustin.cruz@gmail.com> - 2015-07-06 14:36 -0700
    Re: Fast capture and 2D image stacking as 3D numpy array with Python and Raspberry Pi Martin Gregorie <martin@address-in-sig.invalid> - 2015-07-06 23:34 +0000
    Re: Fast capture and 2D image stacking as 3D numpy array with Python and Raspberry Pi Dave Farrance <DaveFarrance@OMiTTHiSyahooANDTHiS.co.uk> - 2015-07-07 10:46 +0100
      Re: Fast capture and 2D image stacking as 3D numpy array with Python and Raspberry Pi Dave Farrance <DaveFarrance@OMiTTHiSyahooANDTHiS.co.uk> - 2015-07-07 11:12 +0100

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

FromAgustin Cruz <agustin.cruz@gmail.com>
Date2015-07-06 14:36 -0700
SubjectFast capture and 2D image stacking as 3D numpy array with Python and Raspberry Pi
Message-ID<f3915090-38d7-4240-9a3d-827a201ca65a@googlegroups.com>
I'm working on a Raspberry Pi project in which I need to take about 30 images 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 know 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 saving each 2D capture as a file

Best regards, Agustín

[toc] | [next] | [standalone]


#9056

FromMartin Gregorie <martin@address-in-sig.invalid>
Date2015-07-06 23:34 +0000
Message-ID<mnf39d$m4i$1@dont-email.me>
In reply to#9055
On Mon, 06 Jul 2015 14:36:49 -0700, Agustin Cruz wrote:

> 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 saving each 2D capture as a file
>
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
org       |

[toc] | [prev] | [next] | [standalone]


#9058

FromDave Farrance <DaveFarrance@OMiTTHiSyahooANDTHiS.co.uk>
Date2015-07-07 10:46 +0100
Message-ID<c46npat5ubkrp44o3be7rs4dt6csa794on@4ax.com>
In reply to#9055
Agustin Cruz <agustin.cruz@gmail.com> wrote:

>I'm working on a Raspberry Pi project in which I need to take about 30 images 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 know 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 saving each 2D capture as a file
>
>Best regards, Agustín

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.


[toc] | [prev] | [next] | [standalone]


#9059

FromDave Farrance <DaveFarrance@OMiTTHiSyahooANDTHiS.co.uk>
Date2015-07-07 11:12 +0100
Message-ID<0n8npahr472oq6orqosf9s0thm0gs58ln4@4ax.com>
In reply to#9058
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.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.sys.raspberry-pi


csiph-web