簡體   English   中英

matlab中的二維卷積 - 代碼優化

[英]2D convolution in matlab - code optimization

這是我們在圖像處理功課中的練習。 我的代碼工作正常。 我想得到一些代碼優化方面的幫助。

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  

因為我是Image Processing和Matlab的新手。 你可以幫助我進行代碼優化,特別是基於矩陣的操作。 有可能不使用循環嗎?

無需編寫代碼了明確,我可以看到一種方式來獲得它歸結為一個主要for循環。 基本上,通過將A和B的每一列展開到一個向量中(將其存儲在MATLAB內部),將矩陣A和B視為列向量。 然后, A每個(i,j)坐標可以被映射到線性索引k (例如,使用函數sub2ind )。 然后,對於A體內的每個線性索引(忽略填充),計算與該線性索引周圍的子矩陣相對應的線性索引列表(這可能是這里最難的部分)。 然后計算A( theseIndices )B(:)的點積。 使用此方法,您只需循環遍歷A每個線性索引。

不知道這是否更快,但至少沒有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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM