我有几个问题。请容忍我。我写下了一个程序,并试图优化它。我只发布了我认为可以进一步优化的代码片段。
1.首先我试图计算图像的梯度。我以前使用的梯度算子的MATLAB,但发现它是缓慢的。所以我写下了我自己的代码。请在我的梯度码!找到我的代码
我在MATLAB上运行了分析器,发现我的程序仍然有一些瓶颈。我在这里张贴一张图片:

正如你所看到的,我使用两个额外的矩阵A和B,每一次计算水平和垂直方向的梯度。真的有必要吗?如果不使用额外矩阵A& B,不能将操作集成到第5行和第8行中吗?删除额外矩阵A&B会使代码运行得更快吗?
2.其次,我需要在代码中使用Laplacian运算符,发现它是程序的瓶颈之一。我已经阅读了matlab文档&还阅读了Matlab del2与Matlab梯度梯度的差异和理解Matlab中的DEL2函数以便在C++中编写的链接。
然后我检查了del2的概要文件并找到了这个。

。我的问题是,在这种情况下,子函数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。我也尝试写我自己的del2函数为matlab,以使它更快,但奇怪的是,我只能处理内部点。del2在MATLAB中的实现正确吗?为什么它要在边界点外推?
拉普拉斯算子的基础不应该始终是平等的吗?
laplacian = del2(image);
[x, y] = gradient(image);
[xx, xy] = gradient(x);
[yx, yy] = gradient(y);
laplacian = xx + yy;这段代码取自请检查代码。我看了那里的所有帖子,但解释没有让我满意。请您解释一下,为什么上面的代码没有提供相同的输出?
感谢大家阅读这组冗长乏味的问题。任何帮助都将不胜感激。如果有人有问题,我会把问题分开,然后分开张贴。伙计们就这么说吧!
提前谢谢!
编辑:经过一整天的努力后,终于成功地删除了违规矩阵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;

我画了速度比较图。请查收,男士们给出你的意见。
发布于 2013-09-25 14:46:43
鉴于有大量的问题,我试图总结如下:
(1) Matlab是高度优化的,基于大量的数值研究,不可能超过Mathworks的人编写的本地例程。请注意,由于Mathworks代码经常对输入执行错误、数据类型和维度检查,因此可以通过编写不执行这些任务的代码来节省执行期间的一些时间,但我不建议这样做,除非您有很好的理由这样做。您还可以编写mex函数,如果您有一个大型项目,它可以(但我无法验证)可以节省一些执行时间。
(2) Matlab例程一般用于按列处理数组(因为这些例程是为利用列数据存储而编写的)。例如,如果您阅读函数gradient后面的代码,您会发现其中一个步骤是“使渐变始终沿列进行。”
(3)我建议您查看del2 (与edit del2)和gradient后面的代码,以了解为什么将Laplacian计算为del2而在代码中计算xx+yy会有所不同。它与连续1阶导数与2阶导数的有限差分逼近有关。
就del2在边缘的行为而言,该算法的一个步骤是“从内部线性外推秒差”。这只是一种获得Laplacian对输入数组中所有点的近似的方法,包括在边缘,那里只有一个单边的近似。
最后,在parse_inputs上:这只是一个函数,负责为梯度计算中使用的所有变量赋值,使用用户输入或缺省值(视情况而定)。
发布于 2013-10-10 16:36:29
尝试使用Jan Simon的DGradient MEX函数。它比梯度快10-20倍,并提供了相同的结果。然后,您可以修改其源代码,以实现与del2性能类似的改进。
这确实是一个非常罕见的例子,其中一个Mex文件以如此显著的加速比超过了本地Matlab函数。
https://stackoverflow.com/questions/18996925
复制相似问题