PFM形式の画像とmiddleburyデータセットの読み取り
16669 ワード
PFM形式の画像とmiddleburyデータセットの読み取り PFM形式画像 画像フォーマット Middlebury 2014データセット データセット紹介 Middleburyデータ集中視差マップを読み取るdepth map を生成する.
PFM形式画像
http://www.pauldebevec.com/Research/HDR/PFM/https://linux.die.net/man/5/pfmPFM(Portable Float Map)は、ファイル情報とファイルバイナリデータの2つの部分を含む浮動小数点画素の画像フォーマットである.
画像フォーマット
PFMにおけるファイル情報をヘッダと呼び,バイナリ画像データをrasterと呼ぶ.
ヘッダーファイル情報:3行の情報が共有され、Unixスタイルの改行記号「」の16進数「0 sa」で終わる. Identifier Line値は「PF」または「Pf」です. 「PF」は、RGB 3チャネル画像 であることを示す."Pf"は、単一チャネル画像 であることを示す.
Dimensions Lineこの行は画像の行列情報(チャネルを含まない)であり、中間は をスペースで隔てている. Scale Factor/Endiannessスケーリングファクタ/バイト順で、この行に書き込まれた情報はグローバル浮動小数点数スケーリングファクタ値であり、正負の区別がある.正の値であれば、画像のバイナリデータは大端シーケンスで格納され、負の値は小端シーケンスで格納される(0値は存在しない).このscale factorはdepth mapを取得する場合にのみ使用され、disparity mapの値をこのscale factorで除算する必要があります.
raster画像データ領域:画像中の各画素値は4バイト、RGBチャネルは12バイト順に記憶され、画像の画素点読取順は下から上へ左から右の順に読み取られる.
Middlebury 2014データセット
http://vision.middlebury.edu/stereo/data/scenes2014/#description
データセットの紹介
Middleburyデータ集中視差マップを読み出してdepth mapを生成
結果:
PFM形式画像
http://www.pauldebevec.com/Research/HDR/PFM/https://linux.die.net/man/5/pfmPFM(Portable Float Map)は、ファイル情報とファイルバイナリデータの2つの部分を含む浮動小数点画素の画像フォーマットである.
画像フォーマット
PFMにおけるファイル情報をヘッダと呼び,バイナリ画像データをrasterと呼ぶ.
ヘッダーファイル情報:3行の情報が共有され、Unixスタイルの改行記号「」の16進数「0 sa」で終わる.
raster画像データ領域:画像中の各画素値は4バイト、RGBチャネルは12バイト順に記憶され、画像の画素点読取順は下から上へ左から右の順に読み取られる.
Middlebury 2014データセット
http://vision.middlebury.edu/stereo/data/scenes2014/#description
データセットの紹介
Middleburyデータ集中視差マップを読み出してdepth mapを生成
from pathlib import Path
import numpy as np
import csv
import re
import cv2
def read_calib(calib_file_path):
with open(calib_file_path, 'r') as calib_file:
calib = {}
csv_reader = csv.reader(calib_file, delimiter='=')
for attr, value in csv_reader:
calib.setdefault(attr, value)
return calib
def read_pfm(pfm_file_path):
with open(pfm_file_path, 'rb') as pfm_file:
header = pfm_file.readline().decode().rstrip()
channels = 3 if header == 'PF' else 1
dim_match = re.match(r'^(\d+)\s(\d+)\s$', pfm_file.readline().decode('utf-8'))
if dim_match:
width, height = map(int, dim_match.groups())
else:
raise Exception("Malformed PFM header.")
scale = float(pfm_file.readline().decode().rstrip())
if scale < 0:
endian = ' # littel endian
scale = -scale
else:
endian = '>' # big endian
dispariy = np.fromfile(pfm_file, endian + 'f')
#
img = np.reshape(dispariy, newshape=(height, width, channels))
img = np.flipud(img).astype('uint8')
#
show(img, "disparity")
return dispariy, [(height, width, channels), scale]
def create_depth_map(pfm_file_path, calib=None):
dispariy, [shape,scale] = read_pfm(pfm_file_path)
if calib is None:
raise Exception("Loss calibration information.")
else:
fx = float(calib['cam0'].split(' ')[0].lstrip('['))
base_line = float(calib['baseline'])
doffs = float(calib['doffs'])
# scale factor is used here
depth_map = fx*base_line / (dispariy / scale + doffs)
depth_map = np.reshape(depth_map, newshape=shape)
depth_map = np.flipud(depth_map).astype('uint8')
return depth_map
def show(img, win_name='image'):
if img is None:
raise Exception("Can't display an empty image.")
else:
cv2.namedWindow(win_name, cv2.WINDOW_NORMAL)
cv2.imshow(win_name, img)
cv2.waitKey()
cv2.destroyWindow(win_name)
def main():
pfm_file_dir = Path(r'middlebury\2014\Adirondack-imperfect')
calib_file_path = pfm_file_dir.joinpath('calib.txt')
disp_left = pfm_file_dir.joinpath('disp0.pfm')
# calibration information
calib = read_calib(calib_file_path)
# create depth map
depth_map_left = create_depth_map(disp_left, calib)
show(depth_map_left, "depth_map")
if __name__ == '__main__':
main()
結果: