Darkside(https対応しました)

2022年7月15日(金) 21:53

画像保存の高速化

 繰り返し処理で時間が掛かるのは、仕方ない。ムカつくのは、png 圧縮がやたら遅いこと。しかし、imwrite には CUDA 関数が存在しないようなのだ。png のエンコードを GPU で高速化するには、どうすれば良いのだろう?
 調べると、どうやら方法は無さそうなのだ。

 だが、そもそもなぜ png 出力かと言うと、DaVinci Resolve で読み込めて OpenCV で書き出せる高画質な映像形式が他に存在しないからだ。mp4 でも高画質なパラメーターで書き出せるなら、それで良い。そして、OpenCV には、cudacodec なるものが存在し、DaVinci Resolve がやっているようなグラボによる mp4 エンコードができるらしい。
 処理時間を要しても画質を最優先したい静止画ステッチなどは、現状のまま png 出力で良い。だが、動画に関しては高画質 mp4 出力が可能かどうかを調べる価値がある。

 ところが調べ始めて、最近の成功例が無いことに気付く。最近はデフォルトで GPU を使ってくれるという説も流れているが、それは解決にならない。なぜなら、mp4 エンコード自体はずっと前に成功しているのであって、問題は高画質な mp4 エンコードができないこと。fps やサイズなど基本的なパラメーターしか指定できず、画質に関係するパラメーターを設定できないのだ。
 泥沼の香りが強烈。

 ここで、単純な解決策を発見。png ではなく jpg で書き出せば良い。
 imwrite では jpeg 画質の指定が可能であり、最高画質の100にすると不可逆圧縮とはいえかなり画質が上がる。png の半分ぐらいのサイズで、エンコードは遥かに速い。フォトショップで最高画質設定した jpeg と、ほぼサイズは同じ。たぶん、色情報が省略されていない。
 ステッチ結果の出力を最高画質 jpeg に変えると、ほぼ倍速になった。DaVinci Resolve でも連番 jpeg は読み込める。速度と品質のバランスで、これがベストだろう。

 さてここで、png を GPU で速くすることはできなかったが jpeg はどうだろう?

 NVIDIA が公式で nvJpeg を出している。そのものズバリで、GPU をフル活用して jpeg のエンコードやデコードを高速化する。人工知能の学習で膨大な量の jpeg を読むという状況を想定して作られたらしい。だが、問題は使い方が恐ろしく複雑なこと。特に Python からどのように使うかに関しては、まるで資料がない。これも、泥沼が確定的。
 プランBとして、GPU は使わないが高速化可能な libjpeg turbo を試してみる。OpenCV をコンパイルしないといけないが、コンパイルに成功したばかり。cmake にパラメーターを追加して、コンパイルし直す。

 1分間あたりの処理フレーム数は、png だと約17枚。jpeg だと約35枚。jpeg turbo だと約45枚。劇的ではないがプログラムそのままで済むことを考えると、かなり意義がある。生成される jpeg のサイズも、完全に同一だ。ここから映像処理を GPU 対応にすると、更に処理枚数が向上すると期待できる。

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