ほとんどの人は、タイトルを見てもなんのことやらさっぱりだと思いますが、検索でこの記事にたどり着いた方、あなたの求めるものはきっとここにあります。
はじめに
日立国際電機の監視カメラシステムISnexシリーズは、録画ファイルが.hvsという見慣れない形式で保存されます。
これを再生するには、「ISnex Viewer」というビューワーソフトが必要だそうですが、インストーラーのWeb配信がなく、機器に付属のCDからインストールする必要があります。
.hvsファイルを扱いたいけどCDが手元にない、そんな超ニッチなシュチュエーションを切り抜けるワザをここに記します。
- はじめに
- 元も子もない話
- まとめ
- そもそも.hvsファイルの正体とは?
- JPEGのバイナリ構成
- 自動で全フレーム切り出す
- フリーソフトで、AIを使ったアップコンバート
- フリーソフトでAIを使ったフレーム補完
- まとめ
元も子もない話
この記事を8割がた書いたところで、全てを無に帰す気付きがありました。
どうやら相手は、コマごとのJpeg画像を1ファイルにまとめたもののようです。(本文より)
ん? それはMotion JPEGのことでは? .hvsを.mjpegに変更...っと→VLC Playerで普通に再生できた→もちろんmp4などに変換もできた。
まとめ
- ISnexの.hsv動画は、拡張子を.mjpegに変えると再生できる。
- さらに、FFmpegを使えば拡張子をいじる必要もなく、そのまま変換できることがわかった。
- 例:ffmpeg -i 動画.hvs 動画mp4
というわけで、ここから先はただの徒労の記録です。
ただ、それだけでは悲しいので、AIによるアップコンバートとフレーム補完ができるフリーソフトについても簡単に紹介します。
それでは、まず僕の半日分の作業を供養させてください。
そもそも.hvsファイルの正体とは?
検索してみると、YAMAHAの音声合成ソフトが出ますが、もちろん別物です。
ネットでは有力情報が掴めなかったので、バイナリエディタの出番です。
とりあえず、Bitmap表示してみると、いかにもフレームの切れ目っぽい線が出ています。
線の辺りを見てみると、さっそく怪しげな痕跡が見つかりました、これはもう尻尾を掴んだぞ!
この文字列を信じるならば、どうやら相手は、コマごとのJpeg画像を1ファイルにまとめたもののようです。ということは、1コマづつ抜き出して、JPEGファイルとして保存すれば、中身を見ることができそうですね。
JPEGのバイナリ構成
1フレームがどこからどこまでなのか知るには、JPEGファイルの先頭と終端の目印を探す必要があります。
この記事によると、JPEGファイルは先頭がFFD8で始まり、末尾がFFD9で終わることなので、これを参考に先頭から1枚分切り出してみます。
FFD8から
DDF9まで
末尾は、ビットマップビューを参考にして、線が入っているあたりを見れば簡単に見つかります。
.jpgを付けて保存すると、無事に1コマ分の画像を取り出すことができました!
自動で全フレーム切り出す
こういう単純作業をさくっと自動化したいときは、Pythonの出番です。
import os # 入力ファイルの情報 target_path = r"c:\tmp" video_name = "hvsのファイル名" # 出力先フォルダを用意 output_path = fr"{target_path}\{video_name}" os.makedirs(output_path, exist_ok = True) # バイナリ読み込みモードで開く with open(fr"{target_path}\{video_name}.hvs","rb") as f: f_in = f.read() # ファイル名連番用のインデックス i = 0 # ファイルを1バイトづつ読み取る for idx in range(len(f_in)): # ffd8を見つけたら、JPEGファイルを作って開く if(f_in[idx] == 0xff and f_in[idx+1] == 0xd8): # ファイル名には5桁の連番を付ける file_name=fr"{video_name}-{str(i).zfill(5)}.jpg" f_out = open(fr"{output_path}\{file_name}","wb") print(fr"{output_path}\{file_name}") # ひたすらバイト列を転記する try: f_out.write(bytes([f_in[idx]])) except: pass # ffd9を見つけたらJPEGファイルを閉じる if(f_in[idx] == 0xff and f_in[idx+1] == 0xd9): f_out.close() # ファイル名連番のインデックスを繰り上げる i += 1
このスクリプトを実行すると、見事全フレームがJPEGファイルとして書き出されました。ここまで書いたところで、冒頭の元も子もない話に続きます。あぁ徒労徒労。
フリーソフトで、AIを使ったアップコンバート
こうして取り出した映像のサイズは640x480のSD画質、ドットがジャギジャギ、だいぶ見辛いものでした。
そこで、ニューラルネットワークで画像の解像度を上げる、Waifu2xというアプリを使ってみることにしました。
AI系のOSSを使うときは、大抵環境構築が面倒ですが、Windows用にWaifu-caffeというGUIツールが公開されていて、これを使うと面倒なところをすっ飛ばして、すぐに使うことができます。
拡大倍率を設定したら、あとはボタンを押すだけです。
CPUで処理することもできますが、恐ろしく時間がかかるので、動画に使うにはCUDA対応のGPU必須です。
フリーソフトでAIを使ったフレーム補完
苦労して取り出した動画は、フレームレートも低めだったので、つぎはフレーム補完です。
こちらは「Frowframe」というGUIアプリを使うと超簡単です、補完倍率を×2〜16の範囲で選んで、ボタンを押すだけです。(これもCUDAを使わないとけっこう厳しい)
まとめ
- 謎形式の動画を手に入れたら、まずはFFmpegを通してみる。
南無