サイズ変更内挿カーネルの作成と比較
この例では、イメージのサイズを変更するカーネルを定義し、サンプル イメージでさまざまな内挿カーネルを比較する方法を示します。
内挿カーネルでは、隣接するピクセルの値の加重平均を使用してピクセルの値を計算します。関数 imresize
は、双一次、双三次、および Lanczos のリサンプリングを実行する多くの組み込みカーネルを提供しています。カスタム カーネルを定義し、そのカスタム カーネルを使用してイメージのサイズを変更することもできます。
この例では、内挿カーネルを評価および比較するために、各カーネルを使用して小さいイメージを拡大します。内挿カーネルの性能を完全に評価するには、さまざまなイメージとスケール係数で調べる必要があります。
imresize
の内挿法に基づくカーネルの作成
双一次法では、次のように定義される三角内挿カーネルを使用します。
triangleResampling
という関数を使用して、双一次内挿カーネルを作成します。この関数の定義については、この例の最後にある「補助関数」の節で示してあります。次に、近傍 [-3.5, 3.5] の双一次内挿カーネルを表示します。
nhood = [-3.5 3.5];
fplot(@triangleResampling,nhood)
title("Bilinear (Triangular) Interpolation Kernel")
双三次法では、次の区分的 3 次内挿カーネルを使用します。
bicubicResampling
という補助関数を使用して、双三次内挿カーネルを作成します。この関数の定義については、この例の最後にある「補助関数」の節で示してあります。次に、双三次内挿カーネルを表示します。
fplot(@bicubicResampling,nhood)
title("Bicubic Interpolation Kernel")
lanczos2
カーネルおよび lanczos3
カーネルは、Lanczos 系の内挿カーネルに基づきます。Lanczos カーネルは、それぞれ または として次のように定義されます。
lanczosResampling
という関数を使用して係数 を指定し、lanczos2 および lanczos3 の内挿カーネルを作成します。
lanczos2 = @(x) lanczosResampling(x,2); lanczos3 = @(x) lanczosResampling(x,3);
lanczos2
および lanczos3
の内挿カーネルを表示します。
fplot(lanczos2,nhood) hold on fplot(lanczos3,nhood) hold off legend(["Lanczos 2","Lanczos 3"]) title("lanczos2 and lanczos3 Interpolation Kernels")
カスタム内挿カーネルの定義
接触有理内挿に基づく区分的有理関数について考えます [1]。
oscResampling
という関数を使用して、接触有理内挿を実行するカスタム内挿カーネルを作成します。この関数の定義については、この例の最後にある「補助関数」の節で示してあります。次に、カスタム内挿カーネルを表示します。
fplot(@oscResampling,nhood)
title("Custom Osculatory Rational Interpolation Kernel")
内挿カーネルを使用したイメージのサイズ変更
小さいアイコンのイメージを読み取り、100% の倍率で表示します。
A = imread("region-analyzer-icon.png"); imshow(A,"InitialMagnification",100)
それぞれの組み込みの内挿法を使用して、イメージのサイズを f
倍に変更します。最近傍法は近傍ピクセルの加重平均を取らないことに注意してください。代わりに、最近傍法では最も近い入力ピクセルの値が出力ピクセルに代入されます。
f = 10; B_nearest = imresize(A,f,'nearest'); B_bilinear = imresize(A,f,'bilinear'); B_bicubic = imresize(A,f,'bicubic'); B_lanczos2 = imresize(A,f,'lanczos2'); B_lanczos3 = imresize(A,f,'lanczos3');
カスタム カーネルを使用してイメージのサイズを変更するには、関数ハンドルと非ゼロのカーネルの幅を imresize
の method
引数として指定します。
width = 4; B_osc = imresize(A,f,{@oscResampling,width});
サイズ変更後のイメージを整列イメージとして表示し、結果を主観的に比較します。
最近傍の結果 (左上) には、かなりのブロック ノイズがあります。双一次の結果 (中央上) は、ほとんどの点において最近傍の結果よりも優れていますが、少しぼやけて見えます。双三次の結果 (右上) と lanczos2 の結果 (左下) はよく似ており、双一次の結果よりも鮮明です。たとえば、イメージの上部付近の数字 "3" と "8" に注目してください。lanczos3 の結果 (中央下) は、双三次と lanczos2 の結果よりも鮮明ですが、目に見える "リンギング" アーティファクトがあります。リンギング アーティファクトは、灰色の境界の外側にぼんやりとしたエコーとして現れており、イメージの真ん中を区切る黒色の太い線の左右で見られます。
カスタム内挿の結果 (右下) は、双三次と lanczos2 の結果よりもわずかに鮮明であり、対角方向のエッジが少し滑らかです。カスタム内挿の結果にリンギング アーティファクトは見られません。
t = imtile({B_nearest,B_bilinear,B_bicubic, ... B_lanczos2,B_lanczos3,B_osc},BackgroundColor="white"); imshow(t)
補助関数
補助関数 triangleResampling
は、双一次内挿を実行します。
function f = triangleResampling(x) f = (1 - abs(x)) .* (abs(x) <= 1); end
補助関数 bicubicResampling
は、双三次内挿を実行します。
function f = bicubicResampling(x) absx = abs(x); absx2 = absx.^2; absx3 = absx.^3; f = (1.5*absx3 - 2.5*absx2 + 1) .* (absx <= 1) + ... (-0.5*absx3 + 2.5*absx2 - 4*absx + 2) .* ... ((1 < absx) & (absx <= 2)); end
補助関数 lanczosResampling
は、指定された係数 a
を使用して Lanczos 内挿を実行します。
function f = lanczosResampling(x,a) f = a*sin(pi*x) .* sin(pi*x/a) ./ ... (pi^2 * x.^2); f(abs(x) > a) = 0; f(x == 0) = 1; end
補助関数 oscResampling
は、接触有理内挿を実行します。
function f = oscResampling(x) absx = abs(x); absx2 = absx.^2; f = (absx <= 1) .* ... ((-0.168*absx2 - 0.9129*absx + 1.0808) ./ ... (absx2 - 0.8319*absx + 1.0808)) ... + ... ((1 < absx) & (absx <= 2)) .* ... ((0.1953*absx2 - 0.5858*absx + 0.3905) ./ ... (absx2 - 2.4402*absx + 1.7676)); end
参照
[1] Hu, Min, and Jieqing Tan. "Adaptive Osculatory Rational Interpolation for Image Processing." Journal of Computational and Applied Mathematics 195, no. 1–2 (October 2006): 46–53. https://doi.org/10.1016/j.cam.2005.07.011.