2012-12-15 69 views
6

這是我們在圖像處理作業中的練習。我的代碼工作正常。我想獲得一些代碼優化方面的幫助。matlab中的二維卷積 - 代碼優化

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。你能幫我完成代碼優化,特別是基於矩陣的操作。是否有可能不使用循環?

+1

你允許使用FFT2和ifft2以任何方式運作?如果是這樣,這將是一種獲得快速解決方案的方法。 – MarkV

+0

不,對不起,主要的概念是我們實施卷積以瞭解它是如何工作的。它的工作原理!現在我想看看是否有辦法做得更好。 – Gilad

回答

5

沒有明確地寫出代碼,我可以看到一種方法將其歸結爲一個主要的for循環。基本上,通過將A和B的每一列解包成一個向量(這是它在MATLAB中內部存儲的),將矩陣A和B看作列向量。然後可以將A的每個座標A映射到線性索引k(例如使用功能sub2ind)。然後,對於A體內的每個線性索引(忽略填充),計算與該線性索引周圍的子矩陣對應的線性索引列表(這可能是此處最難的部分)。然後計算A(theseIndices)B(:)的點積。使用此方法,您只需循環遍歷每個線性索引A

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); 
+0

這會計算相關性,而不是卷積。你必須爲此過濾器旋轉180度。此外,構建'f'矩陣並不是必需的,因爲通過將'A''與(反向)濾波器向量矩陣相乘來實現相同的結果。 – Joost