To take pictures in 0.025s with picamera you'll need a frame-rate greater than or equal to 80fps. The reason for requiring 80 rather 40fps (given that 1/0.025=40) is that currently there's some issue which causes every other frame to get skipped in the multi-image encoder so the effective capture rate winds up as half the camera's framerate.
The Pi's camera module is capable of 80fps in later firmwares (see camera modes in the picamera docs), but only at a VGA resolution (requests for higher resolutions with framerates >30fps will result in upscaling from VGA to the requested resolution, so this is a limitation you'd face even at 40fps). The other problem you'll likely encounter is SD card speed limitations. In other words, you'll probably need to capture to something faster like a network port or in-memory streams (assuming all the images you need to capture will fit in RAM).
The following script gets me a capture rate of ~38fps (i.e. just above 0.025s per pic) on a Pi with overclocking set to 900Mhz:
import io
import time
import picamera
with picamera.PiCamera() as camera:
# Set the camera's resolution to VGA @40fps and give it a couple
# of seconds to measure exposure etc.
camera.resolution = (640, 480)
camera.framerate = 80
time.sleep(2)
# Set up 40 in-memory streams
outputs = [io.BytesIO() for i in range(40)]
start = time.time()
camera.capture_sequence(outputs, 'jpeg', use_video_port=True)
finish = time.time()
# How fast were we?
print('Captured 40 images at %.2ffps' % (40 / (finish - start)))
If you wish to do something in between each frame, this is possible even with capture_sequence
by providing a generator function instead of a list of outputs:
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)))
Bear in mind that in the example above, the processing is occurring serially before the next capture (i.e. any processing you do will necessarily delay the next capture). It is possible to reduce this latency with threading tricks but doing so involves a certain amount of complexity.
You may also wish to look into unencoded captures for processing (which remove the overhead of encoding and then decoding JPEGs). However, bear in mind that the Pi's CPU is small (especially compared to the VideoCore GPU). While you may be able to capture at 40fps, there is no way you're going to be able to perform any serious processing of those frames at 40fps even with all the tricks mentioned above. The only realistic way of performing frame processing at that rate is to ship the frames over a network to a faster machine, or perform the processing on the GPU.