4

最近傍補間が 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]

案内してもらえますか?私はどこか間違っていますか?

4

3 に答える 3

3

を使用して通常の補間を適用する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

さらに、 MATLABOctaveの間の実装も場合によっては異なることが以前に観察されました。


編集:

補間

ご指摘のとおり、場合によっては、 を使用する際に浮動小数点の制限に注意する必要があります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
于 2013-09-20T12:22:43.493 に答える
1

NN は補間の最も単純な形式です。次のレシピがあります。最も近いサンプル位置の値を使用します。MATLAB の NN 補間は計算効率が高いですが、さらに精度が必要な場合は、バイリニアまたはバイキュービック補間を使用することをお勧めします。代わりにinterp1()を確認することもできます。

例を挙げて説明します: http://www.mathworks.com/help/vision/ug/interpolation-methods.html

于 2013-09-20T03:31:42.717 に答える
0

私はこれについての参照を持っていないので、使用して他の例に対してテストすることをお勧めします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しかし、他のケースをテストする必要はありません

于 2013-09-20T06:55:03.627 に答える