picamera: захват кадра во время непрерывной съемки в фоновом режиме - PullRequest
5 голосов
/ 07 февраля 2020

Я записываю интервал с помощью модуля picamera для python:

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, позволяющее захватывать кадры из камера через вызов REST, который вызывает get_frame.

Я использую 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. освободить себя для нового захвата.

Что я делаю не так?

1 Ответ

0 голосов
/ 15 февраля 2020

Где вы объявили объект EggAlertCam - внутри или снаружи метода представления?

Попробуйте снаружи или используйте синглтон.
Или вы можете запустить его в отдельном потоке / процессе и отправлять команды из Flask в это.

...