2014-11-22 76 views
1

我目前正在做一個案例研究,改善性能的可分離濾波器與方形濾波器。我理解時間複雜性差異背後的數學,但是我遇到了真實世界實現的問題。圖像濾波可分矩陣速度MATLAB

所以基本上我所要做的就是寫一個循環鑑於它實現了我的過濾圖像功能:

function imOut = FilterImage(imIn, kernel, boundFill, outputSize) 


VkernelOffset = floor(size(kernel,1)/2); 
HkernelOffset = floor(size(kernel,2)/2); 


imIn = padarray(imIn, [VkernelOffset HkernelOffset], boundFill); 


imInPadded = padarray(imIn, [VkernelOffset HkernelOffset], boundFill); 


imOut = zeros(size(imIn)); 


kernelVector = reshape(kernel,1, []); 
kernelVector3D = repmat(kernelVector, 1, 1, size(imIn,3)); 


for row = 1:size(imIn,1) 
    Vwindow = row + size(kernel,1)-1; 
    for column = 1:size(imIn,2) 
     Hwindow = column + size(kernel,2)-1; 

     imInWindowVector = reshape(... 
      imInPadded(row:Vwindow, column:Hwindow, :),1,[],size(imIn,3)); 

     imOut(row,column, :) = sum((imInWindowVector.*kernelVector3D),2); 
    end 
end 


ouputSize = lower(outputSize); 


if strcmp(outputSize, 'same') 
imOut = imOut((1+VkernelOffset):(size(imOut,1)-VkernelOffset), ... 
    (1+HkernelOffset):(size(imOut,2)-HkernelOffset), :); 
elseif strcmp(outputSize, 'valid') 
    imOut = imOut((1+VkernelOffset*2):(size(imOut,1)-VkernelOffset*2), ... 
     (1+HkernelOffset*2):(size(imOut,2)-HkernelOffset*2), :); 
end 
end 

我又寫了腳本執行一個740x976灰度圖像並記錄在以下兩個命令集他們的處理時間:

for n = 1:25 
    dim(n) = 6*n + 1; 
    h=fspecial('gaussian',dim(n), 4); 
    tic; 
    Im = FilterImage(I,h,0,'full'); 
    tM(n) = toc; 

    h1 = fspecial('gaussian', [dim(n) 1], 4); 
    h2 = fspecial('gaussian', [1 dim(n)], 4); 
    tic; 
    It = FilterImage(I,h1,0,'full'); 
    Is = FilterImage(It,h2,0,'full'); 
    tS(n) = toc; 
end 

密謀需要我得到以下結果相應時間後:Output Plot

我的問題是,爲什麼可分離方法的速度慢到49x49大小的內核矩陣,並且只顯示55x55以上的內核大小提高了速度,我的圖像過濾器代碼有問題?

p.s.圖像濾鏡代碼是爲3D圖像設計的,以考慮顏色深度,但是對於速度測試,我使用的是使用im2double轉換爲灰度圖像的灰度圖像。

PS2從而下面提到,比較我進行了使用MATLAB的本地CONV2功能,並在那裏爲你所期望的結果,也是令人難以置信的速度相同的過程... same exact measure, this time using conv2 instead of FilterImage

感謝

+1

它是我的,因爲Matlab的優化...或不。 – 2014-11-22 20:31:47

+1

您可以使用分析器更詳細地檢查代碼的時間。查看「55x55」後出現的區別。 – 2014-11-22 20:37:43

+0

因此,剖析器顯示,大多數時間飢餓的功能主要是重塑和總和。出於某種原因,在使用Profiler時,可分離的方法在內核尺寸大於67x67之後才變得更快:/ mind mind boggles ...感謝您的建議,儘管:) – 2014-11-22 22:17:18

回答

0

這似乎是一個優化錯誤。
我會使用函數conv2來代替。
讓我們寫一個示例代碼:

mOutputImage = conv2((vFilterCoeff.' * vFilterCoeff), mInputImage); 
mOutputImageSep = conv2(vFilterCoeff, vFilterCoeff.', mInputImage); 

嘗試那些在一個循環,vFilterCoeff(行向量!!!)的長度越來越大。

更新我們現在有什麼結果。

+0

在發佈之前,我嘗試了類似於此的內容,實現完全相同時間腳本,但與conv2而不是我的FilterImage。結果如你所料。分離出來的濾波器在每一個點上的表現都優於方形濾波器,而且開始時有一個很小的差別,這使得我相信這個問題在我自己的FilterImage函數中是有的,這導致我在這裏發佈..我會發布conv2的時間比較結果。 – 2014-11-23 10:41:10