諸事情で複数の画像を簡易的に1つのファイルに統合したいことがあり、またそのファイルをPythonから読み込みたい需要があった。
Numpyを使ったバイナリファイルの読み込み方、OpenCVを使ったデコードの仕方などの知識を使う。
V00000001_L0_VX0001_VY0000_mat0_080.spng&8&426991
とJSONに書いてある場合、データ範囲は8バイト目から426991バイト分なので、以下のように読む。
import cv2 import numpy as np f = open("V00000001_L0_VX0001_VY0000_mat0_080.spng", "rb") data = np.fromfile(f, np.uint8, 426991, "", 8) dst = cv2.imdecode(data, -1) cv2.imshow("window", dst) cv2.waitKey(0)
データ範囲の指定がないSPNGから全ての画像を読む方法は以下の通り。最初の8バイトは画像のデータサイズ(unsigned long long = uint64_t)を意味する。
import os import numpy as np import cv2 import matplotlib.pyplot as plt import struct filename = "ImageFilterWithStream_GPU_0_00000000_0_024_bin.spng" size = os.path.getsize(filename) f = open(filename, "rb") while True: if f.tell() == size:break n_bytes = struct.unpack('Q', f.read(8))[0] data = np.fromfile(f, np.uint8, n_bytes, "", 0) dst = cv2.imdecode(data, -1) plt.imshow(dst) plt.show()
サンプルデータ
https://1drv.ms/u/s!Ap9xAxIuzM0xvIwQ3C62NhsqgRoDfA
画像データのリスト images
がある状態で、SPNGファイルとして出力する方法
import numpy as np import cv2 import struct filename = "test.spng" f = open(filename, "wb") for frame in images: ret, encoded = cv2.imencode(".png",frame) f.write(struct.pack("Q", len(encoded))) encoded.tofile(f)