YUY2のRAW画像を保存してPythonでRGB化

やったこと

  • YUY2出力可能なUSBカメラをLinuxに接続
  • ffmpegでRAW画像キャプチャしてファイル保存
  • Pythonからnumpyで読み込み+OpenCVでRGBへ変換
    • 正確にはBGRにしてファイル保存

キャプチャ(コマンドライン

$ ffmpeg -f v4l2 -input_format yuyv422 -video_size 800x600 -framerate 30 -i /dev/video0 -vcodec rawvideo -pix_fmt yuyv422 -f image2 sample-%04d.png
  • 素数とフレームレートの数値はffmpeg -f v4l2 -list_formats all -i /dev/video0で確認
  • Windowsはたぶん-f dshow-i "カメラデバイス名"にしたらいける予感(動作未確認)

Python

import cv2
import numpy as np
from pathlib import Path


_IMG_SHAPE = (600, 800, 2) # 縦幅, 横幅, 8bit2つ


# カレントディレクトリの.rawファイルをRGB変換してjpgで保存
for p in Path('.').glob('*.raw'):
    yuy2 = np.fromfile(str(p), dtype=np.uint8).reshape(_IMG_SHAPE) # YUY2のRAWファイルを8bitずつ読み出し+[600][800][2]に変形
    bgr = cv2.cvtColor(yuy2, cv2.COLOR_YUV2BGR_YUY2) # YUY2からBGRへ変換
    cv2.imwrite(str(p.with_suffix('.jpg')), bgr) # 拡張子をjpgにしてファイル保存

補足

  • YUY2?
    • YUVフォーマットのうち、UV要素を2ピクセルにつき1ピクセル分の情報に間引いた?フォーマットっぽい
    • データの並びはYUYVYUYV・・・と並ぶっぽい
      • YUYVで2ピクセル分。YUで8bitが2つ、YVで8bitが2つ
    • YUYV422と同じ?(少なくともffmpegは同じ扱いをしてるように見える)
  • Pythonで縦横逆っぽくない?
    • たぶんメモリ上で1次元配列っぽく並んでる
    • YUYV・・・が横方向に並んで、1行が終わると次の行、と並んでいる
    • 上記を3次元で確認すると[縦方向, 横方向, 2]になる