【问题标题】:picamera: capture a frame while continuous capture in backgroundpicamera:在后台连续捕捉的同时捕捉一帧
【发布时间】:2020-02-15 05:13:59
【问题描述】:

我正在使用 python 的 picamera 模块捕捉延时摄影:

from picamera import PiCamera, Color
class EggAlertCam:

    def __init__(self):
        self.camera = PiCamera()
        self.camera.start_preview()

    def capture_thread_task(self):

        filename = os.path.join(self.SAVEPATH, self.safe_camname + '_{timestamp:%Y%m%d-%H%M%S}-{counter:03d}' + '.jpg' )
        starttime = dt.datetime.now()
        current_time = dt.datetime.now()

        for filename in self.camera.capture_continuous(filename):
            print('Captured {}'.format(filename))
            self.wait(current_time)
            current_time = dt.datetime.now()

    def get_frame(self, size=None):
        if size is None:
            size = (640,480)
        output = io.BytesIO()
        self.camera.capture(output, format='jpeg', resize=size, use_video_port=True)
        output.seek(0)
        return output

这个 capture_thread_task 在线程中运行,我有一个 Flask 应用程序,允许通过调用 get_frame 的 REST 调用从相机捕获帧。

我正在使用video_port=True,希望即使在捕捉延时摄影时也能获取(更高的噪点,但我不在乎)图像,但我得到了一个例外:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1820, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/dist-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python3.7/dist-packages/xxx/webapp.py", line 53, in get_frame
    jpg = scheduler.cam.get_frame(size=size)
  File "/usr/local/lib/python3.7/dist-packages/xxx/xxx.py", line 124, in get_frame
    self.camera.capture(output, format='jpeg', resize=size, use_video_port=True)
  File "/usr/local/lib/python3.7/dist-packages/picamera/camera.py", line 1409, in capture
    camera_port, output_port = self._get_ports(use_video_port, splitter_port)
  File "/usr/local/lib/python3.7/dist-packages/picamera/camera.py", line 562, in _get_ports
    'The camera is already using port %d ' % splitter_port)
picamera.exc.PiCameraAlreadyRecording: The camera is already using port 0

我以为我会使用另一个端口进行捕获,但可惜它似乎不起作用。

从这里的文档:https://picamera.readthedocs.io/en/release-1.10/fov.html?highlight=splitter#under-the-hood 我认为 capture_continuous 函数使用端口 0,我应该能够使用端口 1,这是告诉 use_video_port=True 时使用的端口。 但是异常消息告诉我它仍然想使用端口 0..

编辑:我尝试使用分离器端口 2,对于我的一些 Pi 来说,它似乎可以工作,而对于其他人来说,端口 2 似乎已使用。几分钟后,端口开始可用,我可以从中获取帧。

这看起来像是一个需要很长时间的捕获,但我不知道如何正确地请求端口 2 释放自己以进行新的捕获。

我做错了什么?

【问题讨论】:

  • 不确定use_video_port 是否与此有关。 raspberrypi.org/forums/viewtopic.php?t=172257
  • 可能是 Flask 在一个单独的线程中产生了一个请求,创建了第二个摄像头实例,试图访问/dev/video... 设备。
  • @Joe,我在两个线程之间共享同一个对象,所以应该是GILd 不是吗?因此,当我捕捉一帧时,我使用的对象与进行延时拍摄的对象相同。我认为这样做可以,因为我从另一个端口询问数据。也许我应该创建一个专门用于捕获帧的第二个对象?
  • 您可以使用print(id(your_object))检查它是否真的是同一个对象。

标签: python raspberry-pi picamera


【解决方案1】:

您在哪里声明 EggAlertCam 对象 - 在视图方法内部还是外部?

在外面尝试或使用单例。
或者你可以在单独的线程/进程中运行它,然后从 Flask 向它发送命令。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-22
    • 2017-07-15
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多