Raspistill触发缓慢吗?


18

我试图一起触发“许多”覆盆子,而使用raspistill仅用于测试,我想知道为什么拍照这么慢,我进行了测试,并在按下命令的同时输入了Enter:

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

我在镜头前启动了一个iPhone天文钟。结果?7秒09(但很锐利,所以快门速度等还不错,我并没有变得模糊不清)。我该怎么做才能在拍摄照片之前“不”花X秒?我将同步数百个RPI,但我不希望其中的一些人在4秒时拍摄照片,而另一些人在10秒时拍摄照片,所以我想了解那里发生的一切。

Answers:


5

您需要使摄像头过程一直运行。

这是我可以获得(平均)50ms结果的唯一方法。我到处寻找解决方案。1秒对于我的运动传感器项目来说太慢了。

@Dave Jones的项目帮助我弄清楚了如何做。

仅2个文件:

一个始终运行的守护程序和一个客户端。

守护程序是您设置所有相机设置的地方。

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

(在第二个终端中)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)

我发布此答案的原因是,我在Google中找到了这个答案,试图自己找到答案。我找不到一个,所以我不得不深入研究一些项目,然后自己想出一些办法。


当遇到相同的问题时,我想出了相同的解决方案,但是还没有写出任何代码。很高兴看到有人击败了我!
Nick Coons,

6

您需要将超时指定为0。

从raspistill帮助

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

要测试命令执行所需的时间,您可以使用“时间”

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

这消除了默认的5秒超时,但是问题是我得到的不只是此,我在论坛上了解到,没有真正的方法使用raspistill来获取延迟图像
Ronan Thibaudau 2014年

8
在我的Raspberry中,将超时指定为0似乎意味着“无限”,而将超时指定为“ 1”似乎可以解决问题
MondKin 2015年

4
同样,使用如此低的超时时间不会给相机足够的时间来暴露收集器,从而导致图像变暗。我发现在图像开始变暗和模糊之前,我不能低于300。
塞林2015年

2
如果不是非常必要,请忽略该-t选项。如@Cerin所述,如果设置得太低,这会以某种方式破坏图像。老实说,Raspberry Pi的文档中关于此选项的信息太少,导致错误的假设,认为超时是简单的“延迟” /“时间触发”,而事实并非如此。
弗朗伦'16

4

我在.bash_profile中指定了以下别名,以方便快捷地拍摄照片:

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

每当我shot在命令行上键入时,都会保存带有时间戳的图像,例如shot-2016-02-27_0934.jpg


1
欢迎来到Raspberry Pi Stack Exchange社区!即使有--timeout 1论点(?),如果这么快我也会感到惊讶-但由于我(尚未)使我的系统处于这样一种状态,它需要对谁试图解锁我的前端进行快照,我真的不能挑剔的门!8-)尽管很好地使用了命令行(假设已经设置了时钟)-包括首先将具有最高有效值的日期时间戳放在首位,以便字母数字排序顺序与日期排序顺序相同!
SlySven

1
〜$次射击真实0m0.040s用户0m0.010s sys 0m0.020s qed;)
NDB

1
不幸的是,0.040秒实在难以实现。上面的time命令的用法有缺陷,它实际上只会测量分配SHOTTIME变量所花费的时间,而不能捕获图像。实际时间是〜1秒
slackhacker

谢谢您的评论,您是对的。我从原始文本中删除了花费的时间。
NDB

2

您可能想看一下compoundpi项目(完整披露:我是作者)。它旨在通过相机模块触发大量Pi的捕获,并使用UDP广播数据包使它们之间的触发尽可能地接近。每个Pi上都会运行一个守护进程,该守护进程将启动摄像机并在收到包含CAPTURE命令的UDP数据包时触发捕获(其他命令可用于配置摄像机;该协议已被详细记录)。使用以太网进行设置是理想的选择,但是wifi也可以使用,尽管在这种情况下(由于数据包丢失/可变的延迟),您可能必须使用延时功能来获得良好的同步。

我不能说它已经过100 Pi的测试-目前使用它的最大设置涉及20,但我想听听涉及更大规模的任何问题。

该项目包括一个命令行客户端,一个GUI客户端(写在Qt的,所以应该在Linux / MAC / Windows上工作,但它只有在这一点上Ubuntu的测试,它仍然无证),和基于Python的客户端库的编写批处理作业。


我不是很担心udp部分或客户端(我不想手动控制它们,它们是由一个更大的项目控制的),但是compoundpi是否使用需要立即捕获的东西,或者它也有像raspistill这样的延迟?
Ronan Thibaudau 2014年

Dave,看来您是围绕我需要的项目的作者,我们是否有可能进行Skype或电子邮件讨论?
Ronan Thibaudau 2014年

当然-可以直接直接给我发送电子邮件(我的电子邮件地址应该在我的GitHub个人资料上可见)
Dave Jones

1
哦,还有另一个问题:马上就要到了。当compoundpi守护程序启动时,它将初始化并配置摄像机(这是raspistill大量延迟的来源),然后等待捕获命令。capture命令可以立即引起捕获,也可以等到指定的时间戳记再捕获。在这种情况下,接收命令和捕获之间的延迟应为毫秒。
戴夫·琼斯

戴夫·琼斯(Dave Jones),在拍摄之前初始化摄像机的想法,您能提供更多信息吗?我们可以从命令行执行此操作吗?
Ollie
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.