我试图优化我的代码,但发现我的一个代码是瓶颈。我的代码是:
function [] = one(x)
I = imread('coins.png');
I = double(I);
I = imresize(I,[x x]);
sig=.8; % scale parameter in Gaussian kernel
G=fspecial('gaussian',15,sig); % Caussian kernel
Img_smooth=conv2(I,G,'same'); % smooth image by Gaussiin convolution
[Ix,Iy]=gradient(Img_smooth);
f=Ix.^2+Iy.^2;
g=1./(1+f); % edge indicator function.
end
我试过这样运行它: 清除所有;关闭所有;
x=4000;N=1;
tic
for i=1:N
one(x);
end
toc
我发现gradient operator语句消耗的时间最多(约占总时间的60%)。所以这让我开始思考如何进一步优化我的代码....
我咨询了几个网站,例如:Dgradient和 http://regularize.wordpress.com/2013/06/19/how-fast-can-you-calculate-the-gradient-of-an-image-in-matlab/
但是 Dgradient 是一个 MEX 文件,我不想使用它。我想编写自己的渐变函数。我在博客中读到,matlab 中的梯度运算符速度明显较慢,但通过使用 shift & substract 和稀疏矩阵可以加快速度。
我不了解稀疏矩阵。但是我确实尝试通过使用 shift 和 substract 方法来做到这一点。但是我很确定我的代码是错误的。请任何人都可以澄清 matlab 使用什么样的差异来计算其梯度?并告诉我如何在我的代码中做到这一点?
clc;clear all;close all;
I = imread('coins.png');
I = double(I(:,:,1));
I = imresize(I,[4 4]);
tic
[dx dy] = gradient(I);
toc
tic
%//Doing forward difference on both directions
dx1 = [I(:,2:end) I(:,end)] - I;
dy1 = [I(2:end,:);I(end,:)] - I;
toc
请你们看看代码并建议我如何正确应用它?或者指导我如何使用稀疏矩阵这样做?
最佳答案
感谢您的所有回答和有用的建议。我采纳了pseudoDust、Hugues、Dima 和High Performance Mark 的建议,编写了自己的代码。我的代码如下:
clc;clear all;close all;
x=32;
I = imread('coins.png');
I = imresize(I,[x x]);
I = double(I(:,:,1));
tic
[dx dy] = gradient(I);
toc
tic
[m,n]=size(I);
A = [I(:,2:end) zeros(m,1)];
B = [zeros(m,1) I(:,1:end-1)];
dx1 = [I(:,2)-I(:,1) (A(:,2:end-1)-B(:,2:end-1))./2 I(:,end)-I(:,end-1)];
A = [I(2:end,:) ; zeros(1,n)];
B = [zeros(1,n) ; I(1:end-1,:)];
dy1 = [I(2,:)-I(1,:) ; (A(2:end-1,:)-B(2:end-1,:))./2 ; I(end,:)-I(end-1,:)];
toc
nnz(dx-dx1)
nnz(dy-dy1)
我的基本想法是:梯度平均 2 个相邻位置(左右或顶部和底部),边缘除外,它取值与相邻位置之间的差异。然后我用matlab梯度函数生成的矩阵(dx,dy)检查了我生成的矩阵(dx1,dy1)。
Elapsed time is 0.010232 seconds.
Elapsed time is 0.000066 seconds.
ans =
0
ans =
0
所以我相信我的代码是正确的。至少可以说,计时结果也令人惊讶。然后我用 matlab 为不同大小的图像计时我的代码。
我得到了这个结果:
%x=16
Elapsed time is 0.010790 seconds.
Elapsed time is 0.000057 seconds.
%x=32
Elapsed time is 0.010564 seconds.
Elapsed time is 0.000069 seconds.
%x=64
Elapsed time is 0.010627 seconds.
Elapsed time is 0.000152 seconds.
%x=128
Elapsed time is 0.011346 seconds.
Elapsed time is 0.000669 seconds.
%x=256
Elapsed time is 0.017311 seconds.
Elapsed time is 0.004468 seconds.
%x=512
Elapsed time is 0.044148 seconds.
Elapsed time is 0.030435 seconds.
%x=1024
Elapsed time is 0.093386 seconds.
Elapsed time is 0.093029 seconds.
%x=2048
Elapsed time is 0.345423 seconds.
Elapsed time is 0.387762 seconds.
所以我的结论是:对于最大 1024X1024 的图像大小,我的代码比 matlab 中内置的渐变命令更快。
编辑:我更新了我的答案并添加了这张图:
它清楚地表明对于较小的数组大小,我的代码明显快于 matlab 梯度函数。
我的代码正确吗? 请大伙仔细检查一下。请提供您的反馈。我真的是 matlab 的新手,对这个结果感到非常惊讶。请检查我在做什么是否正确?
关于matlab - 在matlab中快速计算图像的梯度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18958231/