6

これは、画像処理の宿題の演習です。私のコードは正常に動作しています。コードの最適化について助けてもらいたいです。

function C = convolve_slow(A,B)
(file name is accordingly convolve_slow.m ) 
This routine performs convolution between an image A and a mask B.
Input:      A - a grayscale image (values in [0,255]) 
            B - a grayscale image (values in [0,255]) serves as a mask in the convolution.
Output:     C - a grayscale image (values in [0,255]) - the output of the convolution. 
                      C is the same size as A.

Method:  Convolve A with mask B using zero padding. Assume the origin of B is at 
     floor(size(B)/2)+1.
Do NOT use matlab convolution routines (conv,conv2,filter2 etc). 
Make the routine as efficient as possible: Restrict usage of for loops which are expensive (use matrix multiplications and matlab routines such as dot etc).
To simplify and reduce ifs, you should pad the image with zeros before starting your convolution loop.
Do not assume the size of A nor B (B might actually be larger than A sometimes).

これが私たちのソリューションです

function [ C ] = convolve_slow( A,B )
%This routine performs convolution between an image A and a mask B.
% Input:      A - a grayscale image (values in [0,255])
%             B - a grayscale image (values in [0,255]) serves as a mask in the convolution.
% Output:     C - a grayscale image (values in [0,255]) - the output of the convolution. 
%             C is the same size as A.
% 
% Method:  Convolve A with mask B using zero padding. Assume the origin of B is at floor(size(B)/2)+1.
% init C to size A with zeros
C = zeros(size(A));
% make b xy-reflection and vector
vectB = reshape(flipdim(flipdim(B,1),2)' ,[] , 1);
% padding A with zeros
paddedA = padarray(A, [floor(size(B,1)/2) floor(size(B,2)/2)]);
% Loop over A matrix:
for i = 1:size(A,1)
    for j = 1:size(A,2)
        startAi = i;
        finishAi = i + size(B,1) - 1;
        startAj = j;
        finishAj = j + size(B,2) - 1;
        vectPaddedA = reshape(paddedA(startAi :finishAi,startAj:finishAj)',1,[]);
        C(i,j) = vectPaddedA* vectB;
    end
end
end  

私は画像処理とMatlabが初めてなので。コードの最適化、特に行列ベースの操作について教えてください。ループを使用しないことは可能ですか?

4

2 に答える 2

5

forコードを明示的に書き出さなくても、メインループを 1 つにまとめる方法がわかります。基本的に、A と B の各列をベクトルにアンラップすることにより、行列 A と B を列ベクトルと考えます (これが、MATLAB に内部的に格納されている方法です)。次に、各(i,j)座標をA線形インデックスにマップできます(たとえばk、関数を使用)。sub2ind次に、A の本体内の各線形インデックス (パディングを無視) について、この線形インデックスの周りのサブマトリックスに対応する線形インデックスのリストを計算します (おそらくここで最も難しい部分です)。次に、 と の内積を計算しA( theseIndices )ますB(:)。このメソッドを使用すると、 の各線形インデックスをループするだけですA

于 2012-12-15T23:38:48.833 に答える
3

これがより高速かどうかはわかりませんが、少なくとも for ループはありません (これは、最近の matlab バージョンで高速化する必要があるという意味ではありません)。

function A = tmpConv(A,B)

    filterSize = size(B,1);
    filterSize2 = floor(filterSize/2);
    inputSize = size(A);

    A = padarray(A,[filterSize2 filterSize2]);

    f = repmat(B(:),[1 inputSize(1)*inputSize(2)]);
    A = im2col(A,[filterSize filterSize]);
    A = reshape(sum(A.*f),inputSize);
于 2013-02-06T15:38:31.620 に答える