最近傍補間が MATLAB でどのように機能するかを知りたいです。入力データがあります:
A = [1 4 7 4 3 6] % 6 digit vector
次の MATLAB コードを使用します。
B = imresize(A,[1 9],'nearest');
次の結果が得られます。
[1,4,4,7,4,4,3,6,6]
手で解くと、次の結果が得られます。
[1 4 4 7 4 4 3 3 6]
案内してもらえますか?私はどこか間違っていますか?
最近傍補間が MATLAB でどのように機能するかを知りたいです。入力データがあります:
A = [1 4 7 4 3 6] % 6 digit vector
次の MATLAB コードを使用します。
B = imresize(A,[1 9],'nearest');
次の結果が得られます。
[1,4,4,7,4,4,3,6,6]
手で解くと、次の結果が得られます。
[1 4 4 7 4 4 3 3 6]
案内してもらえますか?私はどこか間違っていますか?
を使用して通常の補間を適用するinterp1と、手で計算した結果が得られます。
>> N = 9;
>> B = interp1(linspace(0,1,numel(A)), A, linspace(0,1,N), 'nearest')
B =
1 4 4 7 4 4 3 3 6
少し前に、IMRESIZE のソース コードを調べて、それがどのように機能するかを理解しようとしました。概要については、この投稿を参照してください。ある時点で、コードはプライベート MEX 関数を呼び出します (対応するソース コードは利用できません) が、コメントは実装を理解するのに十分です。
価値があるのは、 (バージョン R2006b 以前で使用されていた)imresize_oldの古い実装を提供する関数もあります。imresizeさらに別の結果が得られました。
>> B = imresize(A, [1 N], 'nearest')
B =
1 4 4 7 4 4 3 6 6
>> B = imresize_old(A, [1 N], 'nearest')
B =
1 4 4 7 7 4 3 6 6
さらに、 MATLABとOctaveの間の実装も場合によっては異なることが以前に観察されました。

ご指摘のとおり、場合によっては、 を使用する際に浮動小数点の制限に注意する必要がありますinterp1。したがって、x 番号を[0,1]範囲内、または のようなより安定した範囲に選択することで、補間を行うことができます[1,numel(A)]。エッジ ケースでの丸め誤差のため、これは異なる結果になる可能性があります。
たとえば、次の 2 つのコードを比較します。
% interpolation in [0,1]
N = 11;
y = [1 4 7 4 3 6];
x = linspace(0,1,numel(y));
xi = linspace(0,1,N);
yi = interp1(x, y, xi, 'nearest');
% print numbers with extended precision
fprintf('%.17f %g\n',[x;y])
fprintf('%.17f %g\n',[xi;yi])
に対して:
% interpolation in [1,k]
N = 11;
y = [1 4 7 4 3 6];
x = 1:numel(y);
xi = linspace(1,numel(y),N);
yi = interp1(x, y, xi, 'nearest');
% print numbers with extended precision
fprintf('%.17f %g\n',[x;y])
fprintf('%.17f %g\n',[xi;yi])
きれいにフォーマットされた出力は次のとおりです。
--------------------------------------------------------
[0,1] RANGE | [1,k] RANGE
--------------------------------------------------------
xi yi | xi yi
--------------------------------------------------------
0.00000000000000000 1 | 1.00000000000000000 1 |
0.20000000000000001 4 | 2.00000000000000000 4 |
0.40000000000000002 7 | 3.00000000000000000 7 |
0.59999999999999998 4 | 4.00000000000000000 4 | INPUT
0.80000000000000004 3 | 5.00000000000000000 3 |
1.00000000000000000 6 | 6.00000000000000000 6 |
--------------------------------------------------------
0.00000000000000000 1 | 1.00000000000000000 1 |
0.10000000000000001 4 | 1.50000000000000000 4 |
0.20000000000000001 4 | 2.00000000000000000 4 |
0.29999999999999999 4 | 2.50000000000000000 7 |
0.40000000000000002 7 | 3.00000000000000000 7 |
0.50000000000000000 4 | 3.50000000000000000 4 | OUTPUT
0.59999999999999998 4 | 4.00000000000000000 4 |
0.69999999999999996 4 | 4.50000000000000000 3 |
0.80000000000000004 3 | 5.00000000000000000 3 |
0.90000000000000002 6 | 5.50000000000000000 6 |
1.00000000000000000 6 | 6.00000000000000000 6 |
--------------------------------------------------------
したがって、[0,1] の範囲で作業する場合、一部の数値は倍精度で正確に表現できないことがわかります。そのため、[0.2, 0.4] の中間にあるはずの 0.3 は、丸め誤差のために 0.4 よりも下端の 0.2 に近くなります。反対側では、2.5 は [2,3] (すべての数値が正確に表されている) のちょうど真ん中にあり、最近傍を使用して上端 3 に割り当てられます。
また、 と が異なる出力を生成する場合があることにも注意してcolonくださいlinspace。
>> (0:0.1:1)' - linspace(0,1,11)'
ans =
0
0
0
5.5511e-17
0
0
0
0
0
0
0
NN は補間の最も単純な形式です。次のレシピがあります。最も近いサンプル位置の値を使用します。MATLAB の NN 補間は計算効率が高いですが、さらに精度が必要な場合は、バイリニアまたはバイキュービック補間を使用することをお勧めします。代わりにinterp1()を確認することもできます。
例を挙げて説明します: http://www.mathworks.com/help/vision/ug/interpolation-methods.html
私はこれについての参照を持っていないので、使用して他の例に対してテストすることをお勧めしますimresizeが、Mat;ab の値をこのように復元できます。
が値を表し、要素の位置が値をA表すと仮定します。だから今yAx
n = length(A);
N = 9;
x = 1:n %// i.e. 1:6
ここで、補間位置、つまりxiポイントを見つける必要があります。私は次のようにしました:
xi = round((1:N)/N)*n
を与える
xi =
1 1 2 3 3 4 5 5 6
その結果yi、
yi = A(xi)
yi =
1 1 4 7 7 4 3 3 6
あなたの答えとMatlabの答えの両方とは異なります(どうやってあなたの答えを手に入れましたか?)
それで、私は試しました:
xi = round(((0:N-1)/N)*n)+1
yi = A(xi)
これは同じくらい理にかなっており、Matlab の結果が得られます
yi =
1 4 4 7 4 4 3 6 6
だから私はそれが彼らのやり方だと推測しています。imresizeしかし、他のケースをテストする必要はありません