Raspistill lento para disparar?

18

Estoy tratando de desencadenar "muchas" frambuesas juntas, mientras que usar raspistill es solo para probar, me pregunto por qué tomar una foto es tan lento, hice una prueba y, al mismo tiempo que presiono enter en este comando:

raspistill -o /home/pi/test55.jpg -ex sports --nopreview

Comienzo un cronómetro de iPhone frente a la cámara. ¿El resultado? 7 segundos, 09 (pero fuerte, por lo que la velocidad de obturación, etc. estaba bien, no estaba obteniendo un número borroso). ¿Qué puedo hacer para que "no" tome X segundos antes de tomar la foto? Voy a sincronizar cientos de RPI y no quiero que algunos tomen la foto a las 4 y otro a los 10 segundos, así que me gustaría entender qué está sucediendo allí.

Ronan Thibaudau
fuente

Respuestas:

5

Necesita que el proceso de la cámara se ejecute todo el tiempo.

Esta es la única forma en que podría lograr resultados de (en promedio) 50 ms. Busqué una solución en todas partes. 1 segundo fue demasiado lento para mi proyecto de sensor de movimiento.

El proyecto de @Dave Jones me ayudó a descubrir cómo hacerlo.

Solo 2 archivos:

un demonio, corriendo todo el tiempo y un cliente.

El daemon es donde configuras todos los ajustes de la cámara.

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

(en una segunda terminal) 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)

Estoy publicando esta respuesta porque encontré esto en Google, tratando de encontrar una respuesta yo mismo. No pude encontrar uno, así que tuve que investigar algunos proyectos y encontrar algo yo mismo.

Entryton
fuente
Cuando encontré el mismo problema, se me ocurrió la misma solución, pero aún no había llegado a escribir el código. ¡Me alegra ver que alguien más me ganó!
Nick Coons
6

Debe especificar un tiempo de espera de 0.

De la ayuda raspistill

-timeout "Time (in ms) before takes picture and shuts down (if not specified, set to 5s)

Para probar cuánto tiempo tarda un comando en ejecutarse, puede usar "tiempo"

time raspistill -o /home/pi/test55.jpg -ex sports --nopreview --timeout 0
robar
fuente
Esto elimina el tiempo de espera predeterminado de 5 segundos, pero el problema es que estoy obteniendo más que eso, por lo que entiendo en el foro, no hay una forma real de usar raspistill, ya que no hay imágenes de retraso
Ronan Thibaudau,
8
En mi Raspberry, especificar el tiempo de espera de 0 parece significar "infinito", mientras que especificar un tiempo de espera de "1" parece ser el truco
MondKin
44
Además, el uso de un tiempo de espera tan bajo no le da a la cámara el tiempo suficiente para exponer a los recolectores, lo que da como resultado una imagen oscura. Me parece que no puedo bajar más de alrededor de 300 antes de que la imagen comience a oscurecerse y se vuelva borrosa.
Cerin
2
Si no es estrictamente necesario, deje la -topción fuera. Como @Cerin afirma, de alguna manera esto destruye la imagen si se configura demasiado bajo. Para ser honesto, la documentación de la Raspberry Pi tiene muy poca información sobre esta opción y lleva a la falsa suposición de que el tiempo de espera es un simple "retraso" / "disparador de tiempo" que claramente no lo es.
Flatron
4

He especificado el siguiente alias en mi .bash_profile para permitir tomas de cámara fáciles y rápidas:

alias shot='SHOTTIME=$(date +"%Y-%m-%d_%H%M") && raspistill -o shot-$SHOTTIME.jpg --nopreview --exposure sports --timeout 1

Cada vez que escribo shoten la línea de comando, se guarda una imagen con marca de tiempo, por ejemplo shot-2016-02-27_0934.jpg.

NDB
fuente
1
¡Bienvenido a la comunidad Raspberry Pi Stack Exchange! Incluso con el --timeout 1argumento (?) Me sorprendería si fuera tan rápido, pero como (todavía) no he llevado mi sistema a un estado tal que se toma una instantánea de quién intenta desbloquear mi frente. puerta realmente no puedo recoger liendres! 8-) Buen uso de la línea de comando (suponiendo que se haya configurado el reloj), ¡incluyendo poner el sello de fecha y hora con los valores más significativos primero para que el orden de clasificación alfanumérico sea el mismo que el orden de clasificación de fecha!
SlySven
1
~ $ time shot real 0m0.040s usuario 0m0.010s sys 0m0.020s qed;)
NDB
1
Desafortunadamente, 0.040 segundos es demasiado rápido para ser cierto. El uso del comando de tiempo anterior es defectuoso, en realidad solo medirá el tiempo necesario para asignar la variable TIEMPO DE TIEMPO, no capturando la imagen. El tiempo real es de ~ 1 segundo .
slackhacker
Gracias por tu comentario, tienes razón. He eliminado el tiempo que toma de mi texto original.
NDB
2

Es posible que desee echar un vistazo al proyecto compuestopi (divulgación completa: soy el autor). Está destinado a disparar capturas de numerosos Pi con módulos de cámara y utiliza paquetes de transmisión UDP para que todos se disparen lo más cerca posible. Se ejecuta un demonio en cada Pi que enciende la cámara y dispara capturas al recibir un paquete UDP que contiene el comando CAPTURE (hay otros comandos disponibles para configurar la cámara; el protocolo está bastante bien documentado ). Una configuración usando Ethernet es ideal, pero el wifi también funcionará, aunque es posible que tenga que usar la funcionalidad de retardo de tiempo para obtener una sincronización decente en ese caso (debido a la pérdida de paquetes / latencia variable).

No puedo decir que se haya probado con 100 Pi; en este momento, la configuración más grande que lo usa involucra 20, pero me interesaría saber de cualquier problema relacionado con escalas más grandes.

El proyecto incluye un cliente de línea de comandos , un cliente GUI (escrito en Qt, por lo que debería funcionar en Linux / Mac / Windows, pero solo se ha probado en Ubuntu en este momento, y todavía no está documentado), y una biblioteca de cliente basada en Python para escribir trabajos por lotes.

Dave Jones
fuente
No estoy muy preocupado por la parte de la udp ni por el cliente (no quiero controlarlos a mano, están controlados por un proyecto mucho más grande) pero el compuesto usa algo que requiere una captura casi instantánea o también tiene un retraso como raspistill?
Ronan Thibaudau
Dave, parece que eres el autor de proyectos que giran en torno a lo que necesito, ¿hay alguna posibilidad de que podamos tener una discusión por Skype o correo electrónico?
Ronan Thibaudau
Ciertamente, no dude en enviarme un correo electrónico directamente (mi dirección de correo electrónico debería estar visible en mi perfil de GitHub )
Dave Jones
1
Ah, y en su otra pregunta: es casi instantáneo. Cuando se inicia el demonio compuestopi, se inicializa y configura la cámara (que es de donde proviene un gran retraso en raspistill) y luego espera un comando de captura. El comando de captura puede provocar instantáneamente una captura o esperar hasta una marca de tiempo específica antes de capturar. En el caso actual, el retraso entre la recepción del comando y la captura debe ser de milisegundos.
Dave Jones
Dave Jones, esta idea de inicializar la cámara antes de tomar la captura, ¿puedes dar más información? ¿Podemos hacer esto desde la línea de comandos?
Ollie