💽

【Python】NumPyのmemmap()を使って、OpenCVの画像を他プロセスに受け渡すメモ

2023/09/16に公開

NumPyのmemmap()を使って、OpenCVの画像を他プロセスに受け渡すメモです🦔
以下のようなイメージ↓

書き込み側のスクリプトからメモリマップドファイルに書き込んで、別スクリプトから読み込む↓

画像の受け渡しデータはメモリマップドファイルに書き込まれているので、書き込み側のスクリプトを終了しても、最後に書き込まれた画像が参照できる↓

再度、書き込み側のスクリプトを実行すればメモリマップドファイルに書き込みが再開するので、読み取り側の表示も更新が再開する↓

それぞれのスクリプトは以下です。
メモリマップドファイル書き込み側↓

cv-np-memmap-writer.py
import os

import cv2
import numpy as np

# メモリマップドファイルで受け渡す画像のサイズ
frame_width = 640
frame_height = 360

# VideoCapture準備
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, frame_width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)

# メモリマップドファイル生成
np_memmap_filepath = 'np_memmap.dat'
if not os.path.isfile(np_memmap_filepath):
    # ファイルが存在しない場合は新規作成
    memmap_mode = 'w+'
else:
    # ファイルが存在する場合は既存ファイルを使用
    memmap_mode = 'r+'
np_mmap = np.memmap(
    np_memmap_filepath,
    dtype='uint8',
    mode=memmap_mode,
    shape=(frame_height, frame_width, 3),
)

while True:
    # フレーム読み込み
    ret, frame = cap.read()
    if not ret:
        continue

    # メモリマップドファイルのサイズにあわせてリサイズ
    frame = cv2.resize(frame, dsize=(frame_width, frame_height))

    # メモリマップドファイルに書き込み
    np_mmap[:] = frame[:]
    np_mmap.flush()

    # キー入力待ち、描画
    key = cv2.waitKey(50)
    if key == 27:  # ESC
        break
    cv2.imshow('np memmap writer', frame)

cap.release()
cv2.destroyAllWindows()

メモリマップドファイル読み込み側↓

cv-np-memmap-reader.py
import cv2
import numpy as np

# メモリマップドファイルで受け渡す画像のサイズ
frame_width = 640
frame_height = 360

# メモリマップドファイルオープン ※既存のファイルを開く
np_memmap_filepath = 'np_memmap.dat'
np_mmap = np.memmap(
    np_memmap_filepath,
    dtype='uint8',
    mode='r',
    shape=(frame_height, frame_width, 3),
)

while True:
    # キー入力待ち、描画 ※メモリマップドファイルは別プログラムから随時更新
    key = cv2.waitKey(50)
    if key == 27:  # ESC
        break
    cv2.imshow('np memmap reader', np_mmap)

cv2.destroyAllWindows()

Discussion