Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MATLAB中的图像卷积-conv如何比我的手工编码版本快360倍?_Matlab_Image Processing_Matrix_Vector_Convolution - Fatal编程技术网

MATLAB中的图像卷积-conv如何比我的手工编码版本快360倍?

MATLAB中的图像卷积-conv如何比我的手工编码版本快360倍?,matlab,image-processing,matrix,vector,convolution,Matlab,Image Processing,Matrix,Vector,Convolution,我正在用MATLAB玩图像处理算法。其中一个基本方法是用高斯函数卷积图像。我在灰度800x600图像上运行了以下测试: function [Y1, Y2] = testConvolveTime(inputImage) [m,n] = size(inputImage); % casting... inputImage = cast(inputImage, 'single'); Gvec = [1 4 6 4 1]; % sigma=1; Y1 = zeros(size(inputImage)

我正在用MATLAB玩图像处理算法。其中一个基本方法是用高斯函数卷积图像。我在灰度800x600图像上运行了以下测试:

function [Y1, Y2] = testConvolveTime(inputImage)
[m,n] = size(inputImage);

% casting...
inputImage = cast(inputImage, 'single');

Gvec = [1 4 6 4 1]; % sigma=1;

Y1 = zeros(size(inputImage)); % modify it
Y2 = zeros(size(inputImage)); % modify it


%%%%%%%%%%%%%%%%%%% MATLAB CONV %%%%%%%%%%%%%%%%%%%%%
t1 = cputime;

for i=1:m
    Y1(i,:) = conv(inputImage(i,:),Gvec,'same');
end

for j=1:n
    Y1(:,j) = conv(inputImage(:,j),Gvec','same');
end

Y1 = round(Y1 / 16);
e1 = cputime - t1

%%%%%%%%%%%%%%%%%%% HAND-CODED CONV %%%%%%%%%%%%%%%%%%%%%
t2 = cputime;

for i=1:m
    Y2(i,:) = myConv(inputImage(i,:),Gvec)';
end

for j=1:n
    Y2(:,j) = myConv(inputImage(:,j),Gvec');
end

Y2 = round(Y2 / 16);
e2 = cputime - t2

end
下面是我编写的实现两个向量卷积的代码:

% mimic MATLAB's conv(u,v,'same') function
% always returns column vec
function y = myConv(u_in, v_in)

len1 = length(u_in);
len2 = length(v_in);

if (len1 >= len2)
   u = u_in;
   v = v_in;
else
   u = v_in;
   v = u_in;
end

% from here on: v is the shorter vector (len1 >= len2)

len1 = length(u); 
len2 = length(v); 
maxLen = len1 + len2 - 1;

ytemp = zeros(maxLen,1);

% first part -- partial overlap
for i=1:len2-1
    sum = 0;
    for j=1:i
       sum = sum + u(i-j+1)*v(j);
    end
    ytemp(i) = sum;
end

% main part -- complete overlap
for i=len2:len1
    sum = 0;
    for j=1:len2
       sum = sum + u(i-j+1)*v(j);
    end
    ytemp(i) = sum;
end

% finally -- end portion
for i=len1+1:maxLen
    %i-len1+1
    sum = 0;
    for j=i-len1+1:len2
       sum = sum + u(i-j+1)*v(j);
    end
    ytemp(i) = sum;
end

%y = ytemp;

startIndex = round((maxLen - length(u_in))/2 + 1);
y = ytemp(startIndex:startIndex+length(u_in)-1); 
% ^ note: to match MATLAB's conv(u,v,'same'), the output length must be
%   that of the first argument. 
end
以下是我的测试结果:

>> [Y1, Y2] = testConvolveTime(A1);

e1 =

    0.5313


e2 =

  195.8906

>> norm(Y1 - Y2)

ans =

     0
范数为0验证数学正确性。我的问题如下:

1) 我的手工编码函数怎么会比使用MATLAB的conv的函数慢360x以上呢

2) 即使是MATLAB的conv对于图像处理来说仍然“缓慢”。如果用高斯函数进行卷积需要0.5秒,那么实时运行任何图像处理算法(例如,以24 FPS的速度)还有什么希望?作为参考,我的CPU是Intel N3540@2.16 GHz。带8GB内存

真正的问题是:当我在C++上切换到OpenCV时,这样的操作会变得更快吗?< /P> 非常感谢您的见解。

1)
conv
速度更快,因为它是一个内置的本机函数,而您的函数是用嵌套循环解释的MATLAB代码

2) 尝试图像处理工具箱中的imfilter。它可能比
conv
更快,并且可以在
uint8
阵列上工作。或者,如果您使用的是最新版本的MATLAB,并且您只需要高斯滤波器,请尝试
imgaussfilt

,因为(离散)卷积通常通过线性代数表示,但肯定不是通过for循环表示。事实上,每次您遍历行或列时,都应该寻找将其表示为代数运算的方法

典型的方法是通过Toeplitz矩阵实现,但可以扩展到更快的算法。一旦有了toeplitz结构,就可以进一步优化乘法


请注意,本机Matlab函数仍然可能很慢。它不是速度的指示,而是维护水平的指示。通常,您可以在文档中找到链接使用的算法,您可以决定是采用自定义实现还是标准

为什么matalab中的卷积更快? 实现本身非常高效。 他们使用快速技术进行乘法和卷积运算。 如果你想看到快速完成这些事情的技巧,请查看BLAS、ATLAS软件包


实际上(原始域中的卷积\时间或空间)和(频域中的乘法)是等效的。他们所做的是使用FFT(快速傅立叶变换)变换到频域,然后执行乘法,然后返回到原始域。

嗨,JDS,我不能保证OpenCV或实时图像处理,但很多Matlab函数都是开放阅读的。如果您键入:
edit conv
,您可能可以查看他们的代码,并查看他们是如何执行卷积运算的。在我的MATLAB(R2012b)
conv
上,只需调用没有可用源代码的
conv2
。啊,很抱歉。我觉得值得一试。@JDS你的代码的杀手是你使用
进行
循环。在大多数情况下,当使用循环时,MATLAB是出了名的慢,因为MATLAB是一种解释语言,并且没有优化(有时)。MATLAB的最新版本使用准时制(JIT)优化,因此,一旦他们看到使用循环的模式,就会动态地进行优化。但是,我看不到JIT在您的代码中起作用。在任何情况下,与Dima的回音都在下面,“代码> CONV 和 IMFSULTS/CODE>是内置的Matlab函数,这些函数对于实时性能是高度优化的。至于您的最后一个问题,切换到OpenCV C++时,您可能不会看到太大的不同。记住,
conv
是一个内置函数,它很可能使用了LAPACK/Suitesparse的一些变体,这是执行数值计算和分析的高度优化的C和FORTRAN代码。OpenCV基于类似的优化,因此,如果您并行运行OpenCV和MATLAB之间的等效函数调用,您可能会获得类似的性能。如果我可以再添加一件事,图像处理工具箱将利用Intel Integrated performance Primitives(IIPP)。如果您的CPU可以处理此框架(大多数CPU都是Intel),这就是图像处理工具箱中许多函数速度快的主要原因。速度快得多,特别是因为它通过FFT,需要的复杂度更低。@JemCpp IIRC,
imfilter
conv
不使用FFT执行滤波。你有文档吗?或者你能给我提供一些支持你陈述的参考资料吗?我在我的C实现中非常接近MATLAB-。你有没有办法更快地完成它?