はじめに
「その1」でバイキュービック補間の基本事項を解説しましたが、実際の実装では詳細事項が異なる場合があり得ます。API仕様書に記載されていない場合もあり、注意する必要があります。
パラメータAの値
Aには任意の値が設定できますが、数学的に意味があるのは-0.5、-0.75、-1.0のいずれかとされています。[1][2][3]
Aの値 | |
---|---|
-0.5 | 補間後の画像が、元の画像(サンプリング前の連続関数)の2次微分までのテイラー近似(剰余項除く)と一致する |
-0.75 | 補間関数の2次導関数が連続になる |
-1.0 | x=1で、補間関数の微分と正規化sinc関数の微分が一致する |
以下は各設定のバイキュービック補間で8倍拡大した例です。
入力 | A: -0.5 | A: -0.75 | A: -1.0 |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
端的には、-0.5のほうが元の画像に近く、-1.0のほうが鮮明ですがぎざぎざした画質になる傾向があります。最適な値は対象や用途によって異なり、一意には決まらないと思います。
Aの値による画質への影響については「その3」でさらに解説します。
Aの値は主な処理系でも割れているようです。
Aの値 | |
---|---|
-0.5 | Java Advanced Imaging (javax.media.jai.InterpolationBicubic) ImageMagick (Imagick::resizeImage) ※FILTER_CATROMを指定した場合 MATLAB (imresize) Pillow (Image.resize) TensorFlow (tf.image.resize) ※v1.x JAX (jax.image.resize) |
-0.75 | OpenCV (cv::resize) PyTorch (torch.nn.functional.grid_sample) TensorFlow (tf.image.resize) ※v2.0以降 (*1) |
-1.0 | Java Advanced Imaging (javax.media.jai.InterpolationBicubic2) |
(*1) -0.5になる場合もある(例:1.x用のモデルでhalf_pixel_centersがtrueになった場合)
最近は、OpenCVに合わせる方向の議論が主流のようですが[4][5]、当のOpenCVでも、-0.5あるいは変更できるようにすべき等の議論があります[6]。
拡大画像の画素の位置
OpenCVの画像拡大(resize)では、拡大倍率が整数の場合、拡大画像の画素の位置は入力画像の画素位置をはさむように設定されます。以下は2倍拡大の場合の例です。
一方で、入力画像の画素を含むよう設定する方法もあります。
前者のほうが、拡大画像の重心が入力画像に対しずれないため一般的だと思いますが、後者は入力画像の情報が完全に含まれる利点があり、可逆性が必要な場合や画像計測などの用途では需要があると思います。
外挿補間
バイキュービック補間は、補間のために左右(または上下)に2画素ずつ必要です。
本来、画像の外周は補間計算できない無効な領域ですが、不完全であっても「それらしく」補間拡大されているほうが好都合な場合もあるので、OpenCVのresizeでは最外周の画素値をコピーし外挿してから3次補間するようになっています。
以下の例は、入力画像の幅が4で拡大倍率が2の場合の、外挿や拡大画像の画素位置です。
この場合、拡大画像の両端3画素ずつは不完全な補間になります。
ちなみに、OpenCVでもアフィン変換(warpAffine)では外挿補間の方式をborderModeで選択することが可能です。
参考文献
-
George Wolberg
Digital Image Warping, pp.130-131
ISBN 0-8186-8944-7 -
K. W. Simon
Digital Image Reconstruction and Resampling for Geometric Manipulation
https://docs.lib.purdue.edu/cgi/viewcontent.cgi?article=1068&context=lars_symp -
Robert G Keys
Cubic convolution interpolation for digital image processing
https://ieeexplore.ieee.org/document/1163711 または
https://www.researchgate.net/publication/3177062_Cubic_convolution_interpolation_for_digital_image_processing_IEEE_Trans_Acoust_Speech_Signal_Process -
tf.image.resize_images() - weird padding behaviour? #6720
https://github.com/tensorflow/tensorflow/issues/6720 -
Notice a different between jax.image.resize and F.interpolate when using "bicubic" #15768
https://github.com/jax-ml/jax/issues/15768 -
INTER_CUBIC should default to Catmull-Rom interpolation #17720 (*2)
https://github.com/opencv/opencv/issues/17720
(*2) Aが-0.5の補間関数は、Catmull-Romスプラインのblending functionと一致するため、Catmull-Rom Interpolationと呼ばれる場合があります。
関連記事