Musisz mieć cały czas uruchomiony proces kamery.
Jest to jedyny sposób, w jaki mogłem osiągnąć wyniki (średnio) 50ms. Wszędzie szukałem rozwiązania. 1 sekunda była po prostu zbyt wolna dla mojego projektu czujnika ruchu.
Projekt @Dave Jones pomógł mi wymyślić, jak to zrobić.
Tylko 2 pliki:
demon, działający cały czas i klient.
Demon to miejsce, w którym ustawiasz wszystkie ustawienia kamery.
picam-daemon.py
picam-client.py
python picam-daemon.py
import threading
import os, io, base64, time, socket, picamera, daemon
import daemon.runner
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"
def handle(clientsocket):
while 1:
buf = clientsocket.recv(MAX_LENGTH)
# Receive the SNAP command. Take a picture with PiCam.
if buf == 'snap':
start = time.time()
camera.capture('/home/pi/ir/picam-latest-snap.jpg')
finish = start - time.time()
print finish
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!)
while 1:
# 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()
while camThread.is_alive():
camThread.join(1)
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
(w drugim terminalu) python picam-client.py
import socket
import sys
HOST = '127.0.0.1'
PORT = 10000
s = socket.socket()
s.connect((HOST, PORT))
print s
while 1:
msg = raw_input("Command To Send: ")
if msg == "close":
s.close()
sys.exit(0)
s.send(msg)
Publikuję tę odpowiedź, ponieważ znalazłem ją w Google, sam próbując znaleźć odpowiedź. Nie mogłem go znaleźć, więc musiałem kopać jakieś projekty i sam coś wymyślić.
Musisz określić limit czasu równy 0.
Od pomocy raspistill
Aby sprawdzić, jak długo trwa wykonanie polecenia, możesz użyć „czasu”
źródło
-t
opcję. Jak stwierdza @Cerin, to w jakiś sposób niszczy obraz, jeśli jest ustawiony zbyt nisko. Szczerze mówiąc, dokumentacja Raspberry Pi ma zbyt mało informacji na temat tej opcji i prowadzi do fałszywego założenia, że przekroczenie limitu czasu jest zwykłym wyzwalaczem „opóźnienia” / „opóźnienia”, którego najwyraźniej nie ma.Podałem następujący alias w moim pliku .bash_profile, aby umożliwić łatwe i szybkie zdjęcia z aparatu:
Ilekroć piszę
shot
w wierszu polecenia, na przykład zapisywany jest obraz ze znacznikiem czasushot-2016-02-27_0934.jpg
.źródło
--timeout 1
argumentem (?) Byłbym zaskoczony, gdyby to było tak szybkie - ale ponieważ nie (jeszcze) doprowadziłem mój system do takiego stanu, że wystarczy jedno zdjęcie, kto kiedykolwiek próbuje odblokować mój front - drzwi Naprawdę nie umiem wybierać! 8-) Dobre wykorzystanie wiersza poleceń (zakładając, że zegar został ustawiony) - w tym umieszczenie znacznika daty i godziny z najważniejszymi wartościami na początku, aby alfanumeryczny porządek sortowania był taki sam jak porządek sortowania według daty!Możesz rzucić okiem na projekt złożony (pełne ujawnienie: jestem autorem). Jest przeznaczony do wyzwalania przechwyceń z wielu Pi z modułami kamery i wykorzystuje pakiety emisji UDP, aby wszystkie wyzwalały jak najbliżej siebie. Demon działa na każdym Pi, który uruchamia kamerę i wyzwala przechwytywanie po otrzymaniu pakietu UDP zawierającego polecenie CAPTURE (dostępne są inne polecenia do konfiguracji kamery; protokół jest dość dobrze udokumentowany ). Konfiguracja za pomocą Ethernetu jest idealna, ale wifi również będzie działać, chociaż może być konieczne użycie funkcji opóźnienia czasowego, aby uzyskać przyzwoitą synchronizację w tym przypadku (z powodu utraty pakietu / zmiennego opóźnienia).
Nie mogę powiedzieć, że został przetestowany ze 100 Pi - w tej chwili największa konfiguracja z jego użyciem obejmuje 20, ale byłbym zainteresowany, aby usłyszeć o wszelkich problemach dotyczących większych skal.
Projekt obejmuje klienta wiersza poleceń, klienta GUI (napisany w Qt, więc powinien działać na Linux / Mac / Windows, ale w tym momencie był testowany tylko na Ubuntu i nadal nie jest dokumentowany) oraz bibliotekę klienta opartą na Pythonie dla pisanie zadań wsadowych.
źródło