Может ли OpenCV VideoWriter писать в отдельном процессе? - PullRequest
0 голосов
/ 29 марта 2019

Я пытаюсь сохранить видео на диск в отдельном процессе. Программа создает буфер изображений для сохранения в исходном процессе. По завершении записи он передает имя файла и буфер изображения второму процессу, который создаст свой собственный VideoWriter и сохранит файл. Когда второй процесс вызывает write, ничего не происходит. Он зависает и не выдает никаких ошибок.

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

Вот мой код

def stop_recording(self):
    """Stops recording in a separate process"""
    if self._file_dump_process is None:
        self._parent_conn, child_conn = multiprocessing.Pipe()
        self._file_dump_process = multiprocessing.Process(
            target=self.file_dump_loop, args=(child_conn, self.__log))
        self._file_dump_process.daemon = True
        self._file_dump_process.start()

    if self._recording:
        self.__log.info("Stopping recording. Please wait...")
        # Dump VideoWriter and image buffer to process

        # Comment out when running on main procress
        self._parent_conn.send([self._record_filename, self._img_buffer])
        """ Comment in when running on main procress
        fourcc = cv2.VideoWriter_fourcc(*"MJPG")
        effective_fps = 16.0
        frame_shape = (640, 480)

        record_file = cv2.VideoWriter(self._record_filename, fourcc,
                                      effective_fps, frame_shape,
                                      isColor=1)

        for img in self._img_buffer:
            self.__log.info("...still here...")
            record_file.write(img)

        # Close the file and set it to None
        record_file.release()
        self.__log.info("done.")
        """

    # Delete the entire image buffer no matter what
    del self._img_buffer[:]
    self._recording = False

@staticmethod
def file_dump_loop(child_conn, parent_log):
    fourcc = cv2.VideoWriter_fourcc(*"MJPG")
    effective_fps = 16.0
    frame_shape = (640, 480)
    while True:
        msg = child_conn.recv()
        record_filename = msg[0]
        img_buffer = msg[1]
        record_file = cv2.VideoWriter(record_filename, fourcc,
                                      effective_fps, frame_shape,
                                      isColor=1)
        for img in img_buffer:
            parent_log.info("...still here...")
            record_file.write(img)
        # Close the file and set it to None
        record_file.release()
        del img_buffer[:]
        parent_log.info("done.")

Вот вывод журнала, когда я запускаю его на одном процессе:

2019-03-29 16:19:02,469 - image_processor.stop_recording - INFO: Stopping recording. Please wait...
2019-03-29 16:19:02,473 - image_processor.stop_recording - INFO: ...still here...
2019-03-29 16:19:02,515 - image_processor.stop_recording - INFO: ...still here...
2019-03-29 16:19:02,541 - image_processor.stop_recording - INFO: ...still here...
2019-03-29 16:19:02,567 - image_processor.stop_recording - INFO: ...still here...
2019-03-29 16:19:02,592 - image_processor.stop_recording - INFO: ...still here...
2019-03-29 16:19:02,617 - image_processor.stop_recording - INFO: ...still here...
2019-03-29 16:19:02,642 - image_processor.stop_recording - INFO: ...still here...
2019-03-29 16:19:02,670 - image_processor.stop_recording - INFO: done.

Вот вывод журнала, когда я запускаю его на втором процессе:

2019-03-29 16:17:27,299 - image_processor.stop_recording - INFO: Stopping recording. Please wait...
2019-03-29 16:17:27,534 - image_processor.file_dump_loop - INFO: ...still here...

1 Ответ

0 голосов
/ 29 марта 2019

Я попробовал это, и был успешным со следующим кодом:

import cv2
cap, imgs = cv2.VideoCapture('exampleVideo.MP4'), []

# This function writes video
def write_video(list_of_images):
    vid_writer = cv2.VideoWriter('/home/stephen/Desktop/re_encode.avi',cv2.VideoWriter_fourcc('M','J','P','G'),120, (640,480))
    for image in list_of_images: vid_writer.write(image)

# Loop to read video and save images to a list
for frame in range(123):
    _, img = cap.read()
    imgs.append(img)
write_video(imgs)

cap.release()

Все работало, как ожидалось, и когда я проверил, сколько времени потребовалось для запуска, я обнаружил, что приведенный выше код занял .13 секундчтобы прочитать видео и .43 секунд, чтобы написать видео.Если я читаю видео и пишу видео в том же цикле (ниже), общее время обработки составляет .56 секунд (что составляет .13 + .43).

# Loop to save image to video
for frame in range(123):
    _, img = cap.read()
    vid_writer.write(img)

Существует большой недостаток записисначала изображения в буфер (в памяти), а затем запись изображений в видеофайл (на жесткий диск).Буфер сохраняется в ОЗУ, который очень быстро заполняется, и вы, скорее всего, получите ошибку памяти.

...