物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

OpenCVのPNG形式でエンコードする時の各パラメータの圧縮率と圧縮時間について

OpenCVで画像をPNGファイル、すなわち可逆な形式で圧縮し、ファイルで出力することなくデータを取得したいとき、 cv::imencode というエンコード関数を使う。原理的には以下のように記述する。(そのままでは動かないよ)

vector<int> params = vector<int>(2);
params[0] = CV_IMWRITE_PNG_COMPRESSION;
params[1] = 3; //level
std::vector<uchar> buf;
cv::imencode(".png", img, buf, params);

ここで、paramsの中身について色々と調べてみた。一種の使い方でもある。以下、CV_IMWRITE_PNG_ は略す。

params[0] params[1] 説明
COMPRESSION=16 0-9 圧縮する。レベルは0-9まで可変
STRATEGY=17 STRATEGY_DEFAULT=0 ノーマルデータ
STRATEGY_FILTERED=1 フィルターされた?
STRATEGY_HUFFMAN_ONLY=2 ハフマン符号化
STRATEGY_RLE=3 一致距離を1つに制限
STRATEGY_FIXED=4 単純なデコーダーが可能になる?
BILEVEL=18 0 2値化=Bilevelなし
0以外 2値化=Bilevelあり

COMPRESSION では、ストラテジーSTRATEGY_RLE が使われ、圧縮は必ず行われる。

STRATEGYBILEVEL を使うと、圧縮レベルは内部的に-1アサインされ、圧縮されない。

paramsを与えない場合、STRATEGYSTRATEGY_RLEと同じになる。

画像とビデオの読み込みと書き込み — opencv v2.1 documentation

利用可能な上記のテーブルのパラメータについて、圧縮後のデータサイズと処理時間を測定してみた。圧縮レベルは0-3のみ試した。 条件は、ピクセルサイズは2048×1088で、Sizeは出力ファイルサイズ[byte]、Timeは320回の平均の処理時間[msec]である。

2値画像

輝度値、すなわち要素の値が0または1の二値画像(元は原子核乾板の顕微鏡画像)に対して行った。

params[0] params[1] Size Time
16 0 118,938 26.3
16 1 49,204 24.5
16 2 49,204 23.8
16 3 49,204 23.6
17 0 95,730 8.35
17 1 95,730 8.77
17 2 290,162 18.2
17 3 61,402 7.43
17 4 115,524 8.29
18 0 61,402 7.72
18 1 64,694 6.44
bmp bmp 2,229,302 1.17

Timeが3倍変わるのはおいしくないので、 CV_IMWRITE_PNG_STRATEGYCV_IMWRITE_PNG_STRATEGY_RLE あたりがバランスが良いだろうか。

通常のモノクロ画像

輝度値、すなわち要素の値が0から255までの256階調のモノクロ画像(原子核乾板の顕微鏡画像)に対して行った。

params[0] params[1] Size Time
16 0 2,233,319 48.8
16 1 1,141,548 53.0
16 2 1,141,548 52.4
16 3 1,141,548 53.4
17 0 1,371,852 47.2
17 1 1,371,852 47.5
17 2 1,212,549 25.1
17 3 1,212,854 27.8
17 4 1,925,222 49.6
18 0 1,212,854 27.2
18 1 エラー エラー
bmp bmp 2,229,302 1.03

CV_IMWRITE_PNG_STRATEGYCV_IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY あたりがバランスが良いだろうか。

カラー画像は用途外なので試していない。

乱数で生成したモノクロ画像

ピクセルサイズ2048×1088の画像に、全てのピクセルに乱数で適当な輝度値を与えた。

params[0] params[1] Size Time
16 0 2,233,324 49.1
16 1 2,233,324 52.3
16 2 2,233,324 52.6
16 3 2,233,324 53.5
17 0 2,233,319 70.6
17 1 2,233,319 67.8
17 2 2,233,324 24.3
17 3 2,233,324 27.6
17 4 2,233,319 76.1
18 0 2,233,324 26.1
18 1 エラー エラー
bmp bmp 2,229,302 1.17

ランダムな輝度値の画像は、想像通りほぼ圧縮されていない。こういうケースでは、bmpをそのまま出力するべきだろう。

パラメータ名の変更

OpenCV3系列から、 CV_IMWRITE_PNG_STRATEGY_DEFAULT 等のグローバル変数は、名前空間 cv内の変数に変わっています。なので、以下のパラメータ名を使ってください。

 cv::IMWRITE_PNG_COMPRESSION
 cv::IMWRITE_PNG_STRATEGY
 cv::IMWRITE_PNG_BILEVEL

 cv::IMWRITE_PNG_STRATEGY_DEFAULT
 cv::IMWRITE_PNG_STRATEGY_FILTERED
 cv::IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY
 cv::IMWRITE_PNG_STRATEGY_RLE
 cv::IMWRITE_PNG_STRATEGY_FIXED