1

この質問は、次の 2 つに関連しています:
MATLAB でのベクトル化の紹介 - 良いチュートリアルはありますか?
2 つの配列の要素を同時に使用するフィルター

私が読んだチュートリアルに基づいて、本当に多くの時間がかかる手順をベクトル化しようとしていました。

私はこれを書き直しました:

function B = bfltGray(A,w,sigma_r)
dim = size(A);
B = zeros(dim);
for i = 1:dim(1)
    for j = 1:dim(2)

        % Extract local region.
        iMin = max(i-w,1);
        iMax = min(i+w,dim(1));
        jMin = max(j-w,1);
        jMax = min(j+w,dim(2));
        I = A(iMin:iMax,jMin:jMax);

        % Compute Gaussian intensity weights.
        F = exp(-0.5*(abs(I-A(i,j))/sigma_r).^2);
        B(i,j) = sum(F(:).*I(:))/sum(F(:));

    end
end

これに:

function B = rngVect(A, w, sigma)
W = 2*w+1;
I = padarray(A, [w,w],'symmetric');
I = im2col(I, [W,W]);
H = exp(-0.5*(abs(I-repmat(A(:)', size(I,1),1))/sigma).^2);
B = reshape(sum(H.*I,1)./sum(H,1), size(A, 1), []);


A行列はどこですか512x512
wはウィンドウ サイズの半分です。通常、5
sigmaは範囲 [0 1] のパラメータです (通常は 0.1、0.2、または 0.3 のいずれか)。
したがって、I行列には​​ 512x512x121 = 31719424 要素が含まれます。

しかし、このバージョンは最初のものと同じくらい遅いようですが、さらに多くのメモリを使用し、メモリの問題を引き起こすこともあります.

私は何か間違ったことをしたと思います。おそらく、ベクトル化に関する何らかの論理ミスです。実際、私は驚くことではありません。この方法は非常に大きな行列を作成し、おそらく計算はそれに比例して長くなります。

nlfilter を使用して記述しようとしましたが ( Jonas によって提供された 2 番目のソリューションと同様)、 Matlab 6.5 (R13)を使用しているため、難しいようです(使用できる洗練された関数ハンドルはありません)。

繰り返しになりますが、私はすぐに解決できる解決策を求めているのではなく、妥当な時間内にこれを解決するのに役立ついくつかのアイデアを求めています. たぶん、あなたは私が間違ったことを指摘してくれるでしょう。

編集: Mikhail が示唆したように、プロファイリングの結果 は
次のとおりです
H= exp(...)
im2col

4

1 に答える 1

1

I と H の大きさ (numel(I)*8バイト) は? ページングを開始すると、2 番目のソリューションのパフォーマンスが著しく低下します。

配列が大きすぎるために本当に問題があるかどうかをテストするには、 と を使用してtic、サイズが大きくなるtoc配列の計算速度を試してみることができます。A実行時間が A のサイズの 2 乗よりも速く増加する場合、または のサイズで実行時間がジャンプする場合はA、パディングIされたものをいくつかのサブ配列に分割して、そのような計算を実行できます。

そうでなければ、多くの時間を失う可能性がある明らかな場所は見当たりません。まあ、おそらく、関数内で置き換えBA(メモリも少し節約できます)、次のように書くことで 、形状変更をスキップできます。A(:) = sum(H.*I,1)./sum(H,1);

また、Matlab の最新バージョンへのアップグレードを検討することもできます - 彼らはパフォーマンスの向上に懸命に取り組んできました。

于 2010-05-23T18:53:25.417 に答える