Darkside(https対応しました)

2022年05月の記事

<< 前のページ

2022年5月31日(火) 21:48

隙間ができた

 三角装甲をハンダ付けしようとしたら、1ミリほど隙間が開いてしまった。

 側面装甲が以前の現物合わせに比べてズレたのだろうが、どうズレたのか良くわからない。強引に修正しようにしも、どこを強引にいじれば良いか分からない。

 隙間ができていない辺も、継ぎ目にハンダが流れ込んでくれない。

 まっとうなハンダ付けになっていない。これでは実用的な強度は出ない。
 これは、裏側から作業しないと、どうにもならないと思われる。

 側面装甲をハンダすることで、取り外せなくなる可能性も懸念していた。

 どうせ裏側からいじらないと駄目なので、いったん装甲を取り外してみることにした。
 危惧に反し、特に問題なく外すことができた。大量のネジを外すのが面倒なだけだ。

written by higashino [Sタンク 1/16] [この記事のURL] [コメントを書く] [コメント(0)] [TB(0)]

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

2022年5月30日(月) 21:10

位相限定相関法が効果的

 1軸(横ズレ)だけのソフトウェア IBIS がそれなりに効果的だったことで、回転補正は行わなくても効果的であると推測できる。
 手ぶれ補正の対象はVR撮影であり、基本は三脚である。つまり、本来は三脚でアングル固定したいのに、三脚が使えないから手ぶれしてしまっているという前提だ。
 ソフトウェア IBIS が手ぶれ量を誤認識するのは、特徴点の抽出や照合が時々失敗しているからだと思われる。画面内の動体が影響を与える場合もあるだろう。動体に影響されず、画面中央に近い。そのような部分は必ずしも存在しない。

 まてよ・・・アングル固定が前提なのだから、特徴点などと言わず画像そのまんま照合すれば?
 画像そのまま照合ならば、面積が小さくても高精度な照合が可能である。そして面積が小さくても良いなら、画面中央に近く動体も絡まない場所を指定できる可能性がアップする。
 当然に前例があると思って探すと、やはり存在した。位相限定相関法と言うらしい。

 回転を無視し、2軸ズレだけ取り出してみる。
 取得ズレを見ると、縦ズレは横ズレの10分の1ぐらいしかない。これは、実態に合っている。一脚を使った結果ということだろう。
 取得できたズレ量が現実を反映しているかどうかだが、手ぶれ補正済みの動画を作ってみるのは非常に時間が掛かる。そこで、重要部分だけ切り出して動画を作ることにした。片側 4096×4096 あるが、640×640 ぐらいを切り出して効果の確認に使えば、時間を食いまくる png 圧縮の時間を劇的に減らせる。
 ソフトウェア IBIS の効果を確認するだけなら、ステッチもしなくていい。

 どうやら今度こそ、実用になりそうだ。
 回転が酷い部分はもちろん補正効果が落ちるが、それでも全体として充分に合格。三脚に据えたような完全停止補正までやっても、それほど破綻しない。
 一脚と三脚では使用可能な状況がかなり異なるので、一脚による安定化が実用になるとなれば VR180 3D の撮影機会も広がる。もちろん、手ぶれ補正に使えるような不動点を確保できる状況でなければならない。例えばファイヤーショーなどは、不動点を確保できない可能性が高い。

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

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

2022年5月29日(日) 21:26

悩み続行

 オキュラスの電源が入らなくなった。
 正面上の Oculus ロゴのところに白いLEDが点灯しているのに、画面真っ暗。あらゆるボタンが無反応。
 さっそく類似症状をネットで調べ、対策を片っ端から試す。その結果、電源ボタンを30秒も長押しするというやり方で復活できた。実際には25秒ぐらいだろうか。長押しは良くあるパターンだが、30秒も押させるのは珍しい。

 左右一緒にステッチしてしまうのは、まだバグ残りの可能性がある。そこでここで、片側ずつ処理する版を再掲。以前のものから、少しバグ取りしてある。

import sys
import numpy as np
import cv2
LEFT = 0 # left=1 right=0
videoname = 'bR'
videopath_i = 'e:/' + videoname + '.mov'
videopath_o = 'd:/' + videoname + '/'
dm_w = 4096
dm_h = 4096
dfish = 3684
frame2 = np.zeros((dm_w, dm_h, 3), dtype=np.uint8)
movie = cv2.VideoCapture(videopath_i)
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
            xmap[y,x-xst] = (dm_theta / (np.pi) * np.cos(-dm_phi)) * float(dfish) + float(dfish/2)
            ymap[y,x-xst] = (dm_theta / (np.pi) * np.sin(-dm_phi)) * float(dfish) + float(dfish/2)
    np.save("xmap.npy", xmap)
    np.save("ymap.npy", ymap)
LX = 2114
LY = 2023
RX = 1982
RY = 2037
if (LEFT == 1):
    CX = LX - dfish / 2
    CY = LY - dfish / 2
else:
    CX = RX - dfish / 2
    CY = RY - dfish / 2
for i in range(len(xmap)):
    xmap[i] += CX
for i in range(len(ymap)):
    ymap[i] += CY
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, [int(cv2.IMWRITE_PNG_COMPRESSION), 1]) #3-24
    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()

 自前ステッチが適切に実行できるようになると、同様に静止画もステッチできるようになる。例によって EOS VR Utility は静止画も jpeg 撮って出しでないとステッチしてくれないので、RAW 撮りしてじっくり絵を追い込み、それをステッチすることができない。自分で現像した結果の tiff や png だって処理してくれよ。

 png エンコードは、根本的に重いようだ。他に適切なエンコードも無いから困った。なぜ OpenCV では Cineform 書き出しが出来ないんだ!

 ソフトウェア IBIS は移動量推定に使う場所をうまく選べば、性能が向上するのではないかと考えた。しかし、まだまだ手ぶれが消えない。そこで、誤差の累積を防ぐため基準フレームを先頭フレームに固定。移動量が一定を超えたら基準フレームを最新フレームに入れ替えるようにした。
 15000フレームぐらいあるクリップで、10フレーム以上ズレて来たら基準フレームを切り替えるようにすると、切り替えは17回に収まった。これで IBIS 処理をやると、少しマシになった気がするが大差ない気もする。

 ならばと3軸(横ズレ・縦ズレ・回転ズレ)ではなく1軸(横ズレ)だけを補正してみた。
 すると、何とか鑑賞可能レベルの映像になった。しかし、補正が失敗して手ぶれを拡大してしまう箇所が幾つか残る。少なくとも、合格点は与えられない。

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

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

2022年5月28日(土) 23:16

工具箱の誤算

 三角装甲を、位置合わせしてスポットハンダ付け。

 ハンダ付けし直した経緯から不安があったが、危惧した通り工具箱を取り付けできない。少なくとも、予定の位置には。

 カメラマウント金具が想定より内側に寄り過ぎていて、工具箱もハンダ付けした位置より内側に寄せねば取り付けできない。そうすると、外側に2ミリほど隙間ができてしまう。
 スケールモデルとしてはそれでも許容範囲なのだが、このまま強行しようにも工具箱が装甲に片側乗り上げた状態となり、水平にハンダ付けできない。

 工具箱以外のハンダ付けを進める。

 左舷の側面装甲にも、ナットをハンダ付け。

 車体下部の側面に盛り上がっていたハンダを溶かし、滑らかにする。

 側面装甲を現物合わせし、スポットでハンダ付け。

written by higashino [Sタンク 1/16] [この記事のURL] [コメントを書く] [コメント(0)] [TB(0)]

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

2022年5月27日(金) 23:01

誤算に次ぐ誤算

 ソフトウェアIBIS は、残念ながら手元の動画では逆効果だった。魚眼という特殊な歪み画像では、的確な手ぶれ成分の認識が困難と思われる。

 更に、問題が他にもいろいろ発覚している。
 スカイツリーの近くで撮ったのだが、非常に異常がわかり易かった。スカイツリーの先端が左右にズレていて、つまりは無限遠じゃない。左右映像の間隔はしっかり確認済みだが、切り出し座標が不適切だったようだ。改めて、左右魚眼それぞれの中心座標を調査し計算し直す。

 次に OpenCV で Cineform を読むとき、YUV10bit だとフルスケール出力が正常に認識されない。ビデオレベルとみなされるようで黒潰れ白飛びになってしまう。おかしい。YUV10bit でも正常にフルスケールが読めていたはずなのに、どうなった?
 データーは膨れるが、RGB16bit で出力すれば問題ない。CineForm に限らず、over 8bit によるRGB出力すれば、フルスケールとビデオスケールが取り違えられることは無さそうだ。

 更に、OpenCV の png 書き込みが、異常に遅い。情報量の多い画だと、以前の測定値の何倍も時間を食う。無圧縮形式の画像なら高速に書き込めるが、それだと Davinci Resolve で読めない。
 pillow を試したが、更に遅くなっただけ。
 圧縮率を最低にすると、ファイルサイズはそれほど変わらずに相対的に速くなる。それでも充分に遅いが。
 元はと言えばステッチが遅過ぎるので OpenCV + CUDA で高速化を図ったのだが、それが成功したら結果的に画像処理系ではなく単なる画像の書き込み時が遥かに遅いというオチに。

 ただし、OpenCV に任せたことにより、左右映像の合体なども済ませておけるようになった。最終的に DaVinci Resolve では左右映像と音声の合体を行って最終エンコしていたが、今後は映像と音声の合体を行って最終エンコってことになる。合体処理が不要になったことで、DaVinci Resolve の消費リソースも減るはずだ。最終エンコばかりはタイムラインを8Kにせざるを得ないので、リソース不足で落ちる可能性を減らすことは重要だ。

 でもどうせなら、最終エンコまで OpenCV で出来ないだろうか?
 そうすれば、なぜか超絶に遅い png 書き込みが不要になる。
 OpenCV で mp4 をまっとうな画質で出力することが出来ていなかったが、FFmpeg をパイプラインで使うという記事を発見。
 これならば、単体の FFmpeg さえ動作する環境なら最終エンコが出来る!
 ・・・いや、音声どうするかって問題が残っているのだが。

 しかし試したところ、scikit-video の時の症状

とそっくりな出力となり、失敗に終わった。

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

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

<< 前のページ

Darkside(https対応しました)

Generated by MySketch GE 1.4.1

Remodelling origin is MySketch 2.7.4