Извлекать и анализировать кадры во время записи, используя PiCamera, OpenCV - PullRequest
0 голосов
/ 18 марта 2020

Я передаю видео с моего raspberryPi с помощью piCamera на веб-сокет, чтобы я мог просматривать его в своей локальной сети.

Я хочу создать свой собственный скрипт обнаружения движения с нуля, поэтому я хочу получить первое изображение из видеопотока (который будет простым фоном), а затем сравнить с функцией следующие кадры первого чтобы проверить, изменилось ли что-то (я написал эти функции отдельно), я не особо беспокоюсь об эффективности здесь.

ОСНОВНАЯ ВОПРОС: Я хочу получить данные из этих кадров в объекте BytesIO, а затем преобразовать их в массив 2D numpy в черно-белом, чтобы я мог выполнять операции. Все это при сохранении потока (на самом деле я уменьшил частоту кадров до 4 в секунду, чтобы ускорить его работу на моем компьютере).

ПРОБЛЕМА, ВСТАВЛЕННАЯ С СЛЕДУЮЩИМ КОДОМ: Одна часть проблемы, которую я определили, что цифры далеко. В моих настройках моя камера должна иметь разрешение около 640 * 480 (= 307 200 длины numpy массив пикселей данных в черно-белом виде), тогда как мои вычисления в len () возвращают менее 100 000 пикселей.

    def main():
    print('Initializing camera')
    base_image = io.BytesIO()
    image_captured = io.BytesIO()
    with picamera.PiCamera() as camera:
        camera.resolution = (WIDTH, HEIGHT)
        camera.framerate = FRAMERATE
        camera.vflip = VFLIP # flips image rightside up, as needed
        camera.hflip = HFLIP # flips image left-right, as needed
        sleep(1) # camera warm-up time
        print('Initializing websockets server on port %d' % WS_PORT)
        WebSocketWSGIHandler.http_version = '1.1'
        websocket_server = make_server(
            '', WS_PORT,
            server_class=WSGIServer,
            handler_class=WebSocketWSGIRequestHandler,
            app=WebSocketWSGIApplication(handler_cls=StreamingWebSocket))
        websocket_server.initialize_websockets_manager()
        websocket_thread = Thread(target=websocket_server.serve_forever)
        print('Initializing HTTP server on port %d' % HTTP_PORT)
        http_server = StreamingHttpServer()
        http_thread = Thread(target=http_server.serve_forever)
        print('Initializing broadcast thread')
        output = BroadcastOutput(camera)
        broadcast_thread = BroadcastThread(output.converter, websocket_server)
        print('Starting recording')
        camera.start_recording(output, 'yuv')

        try:
            print('Starting websockets thread')
            websocket_thread.start()
            print('Starting HTTP server thread')
            http_thread.start()
            print('Starting broadcast thread')
            broadcast_thread.start()
            time.sleep(0.5)

            camera.capture(base_image, use_video_port=True, format='jpeg')

            base_data = np.asarray(bytearray(base_image.read()), dtype=np.uint64)

            base_img_matrix = cv2.imdecode(base_data, cv2.IMREAD_GRAYSCALE)

            while True:
                camera.wait_recording(1)

                #insert here the code for frame analysis

                camera.capture(image_captured, use_video_port=True, format='jpeg')
                data_next = np.asarray(bytearray(image_captured.read()), dtype=np.uint64)
                next_img_matrix = cv2.imdecode(data_next, cv2.IMREAD_GRAYSCALE)

                monitor_changes(base_img_matrix, next_img_matrix)

        except KeyboardInterrupt:
            pass
        finally:
            print('Stopping recording')
            camera.stop_recording()
            print('Waiting for broadcast thread to finish')
            broadcast_thread.join()
            print('Shutting down HTTP server')
            http_server.shutdown()
            print('Shutting down websockets server')
            websocket_server.shutdown()
            print('Waiting for HTTP server thread to finish')
            http_thread.join()
            print('Waiting for websockets thread to finish')
            websocket_thread.join()


if __name__ == '__main__':
    main()

1 Ответ

0 голосов
/ 20 марта 2020

Решено, в основном проблема была в том, как я обрабатывал данные и файлы BytesIO. Прежде всего мне нужно было использовать unsigned int8 как тип файла для декодирования id. Затем я переключился на np.frombuffer, чтобы полностью прочитать файлы, потому что базовый образ не изменится, следовательно, он всегда будет читать одно и то же, а следующий будет инициализирован и исключен в каждый момент времени l * 1003. *. Также я могу заменить cv2.IMREAD_GRAYSCALE на 0 в функции.

camera.start_recording(output, 'yuv')
base_image = io.BytesIO()

    try:
        print('Starting websockets thread')
        websocket_thread.start()
        print('Starting HTTP server thread')
        http_thread.start()
        print('Starting broadcast thread')
        broadcast_thread.start()
        time.sleep(0.5)

        camera.capture(base_image, use_video_port=True, format='jpeg')

        base_data = np.frombuffer(base_image.getvalue(), dtype=np.uint8)

        base_img_matrix = cv2.imdecode(base_data, 0)

        while True:
            camera.wait_recording(0.25)
            image_captured = io.BytesIO()

            #insert here the code for frame analysis

            camera.capture(image_captured, use_video_port=True, format='jpeg')
            data_next = np.frombuffer(image_captured.getvalue(), dtype=np.uint8)
            next_img_matrix = cv2.imdecode(data_next, cv2.IMREAD_GRAYSCALE)

            monitor_changes(base_img_matrix, next_img_matrix)
            image_captured.close()
...