You need to have the camera process running all the time.
This is the only way I could acheive results of (on average) 50ms. I looked everywhere for a solution. 1 second was just too slow for my motion sensor project.
@Dave Jones 's project helped me figure out how to do it.
Just 2 files:
a daemon, running all the time and a client.
The daemon is where you set all the camera settings.
import os, io, base64, time, socket, picamera, daemon
MAX_LENGTH = 50 # max length of any possible entry from "client"
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # setup socket
PORT = 10000 # port 10000
HOST = '127.0.0.1' # runs on local host
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # this allows us to override port, prevents error
serversocket.bind((HOST, PORT)) # lock server to this port and host
serversocket.listen(10) # max 10 clients
# Waits for commands, such as "snap" and "ack"
# Runs over "sockets"
buf = clientsocket.recv(MAX_LENGTH)
# Receive the SNAP command. Take a picture with PiCam.
if buf == 'snap':
start = time.time()
finish = start - time.time()
print 'Picture Taken!'
if buf == 'ack':
print 'Ping: Hello!'
if len(buf) == 0: break
# Camera is always loaded here
# The "magic" is in the camThread, this allows a picture to be captured, then it gracefully closed the camera connection and reopens it. This produces very fast captures (54ms vs 1.5s!)
# setup camera
camera = picamera.PiCamera()
camera.resolution = (640, 480)
#camera.zoom = (0.2, 0.2, 1.0, 1.0)
camera.exposure_mode = 'sports'
print('Camera server running')
# accept connections from outside, in order to receive commands
(clientsocket, address) = serversocket.accept()
ct = threading.Thread(target=handle, args=(clientsocket,))
ct.run() # this can be run(), because it can be scaled.
print 'Camera thread starting.'
camThread = threading.Thread()
camThread.run() # this must be start(), otherwise PiCam will crash. This is because PiCam cannot receive more than 1 connection.
print 'Camera thread ended'
camera.close() # Gracefully close PiCam if client disconnects
(in a second terminal) python picam-client.py
HOST = '127.0.0.1'
PORT = 10000
s = socket.socket()
msg = raw_input("Command To Send: ")
if msg == "close":
I'm posting this answer because I found this in Google, trying to find an answer myself. I couldn't find one, so I had to dig around some projects and come up with something myself.