在matlab中制作渐变和del2的速度更快

时间:2013-09-25 05:29:29

标签: matlab optimization image-processing matrix

我有几个问题。拜托我。我写了一个程序,并试图优化它。我只发布了我认为可以进一步优化的代码片段。

1。首先,我正在尝试计算图像的渐变。我之前使用过MATLAB的梯度算子,但发现它很慢。所以我写下了自己的代码。请在my gradient code here!

找到我的代码

我在MATLAB上运行了探查器,发现我的程序仍有一些瓶颈。我在这里张贴一张图片: gradient profile

正如你所看到的,我正在使用两个额外的矩阵A和B,每个矩阵两次用于计算水平和梯度中的梯度。垂直方向。真的有必要吗?不能将操作集成到第5行和第5行中。第8行没有使用额外的矩阵A& B.是否删除额外的矩阵A& B让我的代码运行得更快?

2. 其次我需要在我的代码中使用拉普拉斯算子,并发现它是我程序的瓶颈之一。我已经阅读过matlab文档&另请阅读Discrepancy between Matlab del2 and Matlab gradient of gradientUnderstanding DEL2 function in Matlab in order to code it in C++链接。

然后我检查了del2的配置文件并找到了这个。 enter image description here。我的问题是,在这种情况下,儿童功能 parse_inputs ipermute 的功能是什么? 需要注意的是,我正在处理一个大小总是大于64X64的图像矩阵。

我阅读了permute的解释,并说“置换以便del2始终沿着列。”。实际上是什么意思?我读过MATLAB使用列主格式的地方。谁能解释一下这意味着什么?

关于parse_inputs子函数,我阅读了说明

的解释
 %PARSE_INPUTS
                  %   [ERR,F,LOC,CFLAG] = PARSE_INPUTS(F,V) returns the spacing LOC
                  %   along the x,y,z,... directions and a column vector flag CFLAG. ERR
                  %   will be true if there is an error.

我不知道这个功能是做什么的。请任何人解释一下吗?

第3 即可。我也尝试为matlab写下我自己的del2函数,以便让它更快,但奇怪的是我只能处理内部点。 MATLAB中的实现是否适用于del2?为什么要在边界点进行外推?

拉普拉斯算子的基础不应该总是它应该保持相等吗?

laplacian = del2(image);

[x, y] = gradient(image);
[xx, xy] = gradient(x);
[yx, yy] = gradient(y);
laplacian = xx + yy;

此代码取自Please check code。我阅读了那里的所有帖子,但解释并不能让我满意。请问你能解释为什么上面的代码没有给出相同的输出吗?

感谢大家阅读这一长篇无聊的问题。任何帮助将不胜感激。如果有人有问题,我会分开问题并单独发布。就这么说吧!

提前致谢!

编辑:经过一整天的努力,终于成功删除了违规的矩阵A& B.我正在写下面的代码:

function [dx dy] = gradient_my_code(I)
dx=[I(:,2)-I(:,1) (I(:,3:end)-I(:,1:end-2))./2 I(:,end)-I(:,end-1)];
dy=[I(2,:)-I(1,:) ; (I(3:end,:)-I(1:end-2,:))./2 ; I(end,:)-I(end-1,:)];

对于计时目的,我这样做了:

xaxis = [10,20,30,40,50,60,70,80,90,100,200,300,400,500,600,700,800,900,1000,2000,3000,4000,5000];
n1 = zeros(1,length(xaxis));
n2 = zeros(1,length(xaxis));
for i=1:length(xaxis);
    x=xaxis(i);
    u=magic(x);
    tic
    [dx dy] = gradient(u);
    n1(i)=toc;
    tic
    [dx dy] = gradient_my_code(u);
    n2(i)=toc;
end
plot(n1,'r','LineWidth',3);
hold on;
plot(n2,'b','LineWidth',3);
hold off;

Speed comparison between gradient of matlab and my code

我绘制了速度比较。请检查,然后你们发表评论。

2 个答案:

答案 0 :(得分:3)

尝试使用Jan Simon的DGradient MEX功能。它比 渐变 快10-20倍,并提供相同的结果。然后,您可以修改其源代码,以便对 del2 性能进行类似的改进。

这确实是一个罕见的例子,其中Mex文件通过如此显着的加速优于原生Matlab函数。

答案 1 :(得分:2)

鉴于我试图总结的大量问题:

(1)Matlab是高度优化的,所以你不可能在Mathworks基于广泛的数值研究的基础上击败人们编写的本机例程。作为一个警告,因为Mathworks代码经常对输入执行错误,数据类型和维度检查,您可以在执行期间通过编写不执行这些任务的代码来节省一些时间,但我不建议除非您有一个非常有充分理由这样做。您还可以编写mex函数,如果您有一个大型项目,可以(但我无法验证这一点)在执行时节省一些时间。

(2)Matlab例程通常按列写入进程数组(因为编写例程以利用列式数据存储)。如果您阅读函数gradient背后的代码,您会发现,例如,其中一个步骤是“置换,以便始终沿着列进行渐变。”

(3)我建议您查看del2edit del2)和gradient背后的代码,了解为什么将拉普拉斯算术计算为del2xx+yy在你的代码中会有所不同。它与连续的第一和第二导数的不同有限差分近似有关。

就边缘del2的行为而言,算法中的一步是“线性推断内部的第二个差异”。它只是为输入数组中的所有点获得拉普拉斯算子的近似值的一种方法,包括在只有单边近似的边缘处。

最后,在parse_inputs上:这只是一个函数,它负责为梯度计算中使用的所有变量赋值,使用用户输入或默认值(视情况而定)。