Darkside(https対応しました)

2022年5月23日(月) 21:41

VR180専用正距円筒変換

 Davinci Resolve に連番png を読み込むとき、カットページ以外に放り込まないと動画として扱われない。メディアプールに放り込むのが無難。
 無事に左右合体させ、目的のVRファイルが完成した。

・RICOH THETA SのためのDualfisheyeからEquirectangularに変換を行うGstreamerプラグイン
 マップファイルの作成や remap の実行サンプルとして。

・ドーム射影変換フィルタ for AviUtl
 移植元のプラグイン。これを VR180 片側専用に修正して利用。

 言語は Python + OpenCV で、CUDA を使うことにより GPU を活用。高速化している。CUDA 入れておかないと速度が出ないので注意。他にも numpy とかいろいろ入れておかないと動かない。
 入力ファイルは、VR180 片側の画角180度分をちょうどを切り出しておかねなばらない。DUAL FISHEYE なら 3684x3684 で良いはず。出力ファイルは、ディレクトリを掘っておく。先頭付近を環境に応じて書き換えること。dm_w と dm_h は、出力解像度。

import sys
import numpy as np
import cv2
videoname = 'xxxL'
videopath_i = 'e:/' + videoname + '.mp4'
videopath_o = 'd:/' + videoname + '/'
dm_w = 4096
dm_h = 4096
movie = cv2.VideoCapture(videopath_i)
fps = int(movie.get(cv2.CAP_PROP_FPS))
w = int(movie.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(movie.get(cv2.CAP_PROP_FRAME_HEIGHT))
arr_sin_dm_phi = [np.pi] * (dm_w * 2)
arr_cos_dm_phi = [np.pi] * (dm_w * 2)
xmap = np.zeros((dm_h, dm_w), np.float32)
ymap = np.zeros((dm_h, dm_w), np.float32)
try:
    # try to load map file
    xmap = np.load("xmap.npy")
    ymap = np.load("ymap.npy")
except IOError:
    # if the map files are not exist, generate new map files.
    print("Generating map files...")
    for x in range(dm_w * 2):
        dm_x = float(x)
        dm_phi = np.pi * 2.0 * dm_x / dm_w / 2.0
        arr_sin_dm_phi[x] = np.sin(dm_phi)
        arr_cos_dm_phi[x] = np.cos(dm_phi)
    for y in range(dm_h):
        dm_y = float(y)
        dm_theta = np.pi * dm_y / (dm_h-1)
        sin_dm_theta = np.sin(dm_theta)
        cos_dm_theta = np.cos(dm_theta)
        xst = int(dm_w / 2)
        xen = int(dm_w * 3 / 2)
        for x in range(xst,xen):
            dm_x = float(x)
            sin_dm_phi = arr_sin_dm_phi[x]
            cos_dm_phi = arr_cos_dm_phi[x]
            tmp2_x = sin_dm_theta * cos_dm_phi
            tmp2_y = sin_dm_theta * -sin_dm_phi
            tmp2_z = cos_dm_theta
            tmp_x = tmp2_x
            tmp_y = tmp2_y
            tmp_z = tmp2_z
            tmp2_x = tmp_x
            tmp2_y = tmp_y
            tmp2_z = tmp_z
            car_x = tmp2_x
            car_y = tmp2_y
            car_z = tmp2_z
            tmp_x = car_x
            tmp_y = car_y
            tmp_z = car_z
            car_x = tmp_z;
            car_y = tmp_y;
            car_z = -tmp_x;
            dm_theta = np.arccos(car_z)
            if (car_y > 0):
                dm_phi = np.arctan(car_x / car_y)
            elif (car_y < 0):
                dm_phi = np.pi - np.arctan(car_x / -car_y)
            elif (car_y == 0 and car_x > 0):
                dm_phi = np.pi / 2.0
            elif (car_y == 0 and car_x < 0):
                dm_phi = -np.pi / 2.0
            else:
                dm_phi = 0
            if (dm_theta < (np.pi / 2.0)):
                xmap[y,x-xst] = (dm_theta / (np.pi) * np.cos(-dm_phi)) * float(w) + float(w/2)
                ymap[y,x-xst] = (dm_theta / (np.pi) * np.sin(-dm_phi)) * float(w) + float(h/2)
    np.save("xmap.npy", xmap)
    np.save("ymap.npy", ymap)
count = 0
ret, frame = movie.read()
while ret:
    frame = cv2.remap(frame, xmap, ymap, cv2.INTER_LINEAR, cv2.BORDER_CONSTANT)
    cv2.imwrite(videopath_o + str(100000 + count) + '.png', frame)
    ret, frame = movie.read()
    if count % 3600 == 0:
        print(int(count/3600), end="")
        sys.stdout.flush()
    elif count % 60 == 0:
        print('.', end="")
        sys.stdout.flush()
    count += 1
movie.release()
print()

 Davinci Resolve は ver.18 になって規格を守るようになってしまった。ver.17 では over 4K を H264 でエンコードできたのだが、ver.18 ではできない。規格破りの H264 は再生負荷が小さくて Quest 2 で重宝してるんだけどなあ・・・

written by higashino [Virtual Reality] [この記事のURL] [コメントを書く] [コメント(0)] [TB(0)]

この記事へのトラックバックPingURL

Comments

TrackBacks

Darkside(https対応しました)

Generated by MySketch GE 1.4.1

Remodelling origin is MySketch 2.7.4