简单的图像特征比较花费太多时间
simple Image feature camparision taking too much time
我有以下matlab代码用于比较图像的直方图特征;特征基本上是 3 维数组
for i=1:1:26
for j=1:1:26
s1=sum(image1(i,j,:));
s2=sum(image2(i,j,:));
if(s1>2 && s2>2)
for k=1:1:31
if image1(i,j,k)~=0 && image2(i,j,k)~=0
d = d + ((image1(i,j,k) - image2(i,j,k))^2)/ (image1(i,j,k) + image2(i,j,k));
end
end
count=count+1;
end
end
end
代码给出了令人满意的结果,但问题是它在我机器上的 matlab 中花费了很多时间(1 秒),我真的需要优化它,任何类型的帮助或建议以其他方式进行欢迎
这是一种 vectorized
方法 -
%// Sum elements of image1 & image2 along the third dimension corresponding
%// to s1 and s2 in the original loopy code
s1v = sum(image1,3);
s2v = sum(image2,3);
%// Pre-calculate all image1,image2 operations that lead to the calculation
%// of d in the original code
allvals = ((image1 - image2).^2)./(image1 + image2);
%// Calculate the first conditional values for the corresponding IF conditional
%// statement in original post - "if(s1>2 && s2>2)"
cond1 = s1v>2 & s2v>2
%// Sum all satisfying first conditional values for getting "count"
count = sum(cond1(:))
%// Calculate the second conditional values for the corresponding IF conditional
%// statement in original post - "if image1(i,j,k)~=0 && image2(i,j,k)~=0"
cond2 = image1~=0 & image2~=0;
%// Map both cond1 and cond2 onto allvals to select specific elements from
%// it and then sum those up for the final output, d
d = sum(cond1(:).'*reshape(cond2.*allvals,[],size(allvals,3)))
最后一行可以用 bsxfun
代替 -
d = sum(allvals(bsxfun(@and,cond1,cond2)))
加速 matlab 代码的黄金法则是避免 for 循环并尽可能使用矢量化代码和矩阵。使用矢量化和逻辑索引可以非常快速地进行此计算。我已经在 Octave 中测试了以下内容,它工作正常并且速度非常快 - 您可能需要将 != 替换为 ~= 以实现 matlab 兼容性。调整 n 和 p 以减轻测试的痛苦(或删除前 4 行)并将 d 初始化为您喜欢的任何值。
n=26;
p=31;
i1=1.5*rand(n,n,p); i2=1.5*rand(n,n,p);
s1=sum(i1,3); s2=sum(i2,3);
indices=((s1>2) & (s2>2)) & ((i1!=0) &(i2!=0));
d=0;
d=d+sum(sum( ( (i1(indices)-i2(indices)).^2 ) ./ (i1(indices)+i2(indices)) )),
count=sum(sum( (s1 > 2) & (s2 > 2) ) )
我有以下matlab代码用于比较图像的直方图特征;特征基本上是 3 维数组
for i=1:1:26
for j=1:1:26
s1=sum(image1(i,j,:));
s2=sum(image2(i,j,:));
if(s1>2 && s2>2)
for k=1:1:31
if image1(i,j,k)~=0 && image2(i,j,k)~=0
d = d + ((image1(i,j,k) - image2(i,j,k))^2)/ (image1(i,j,k) + image2(i,j,k));
end
end
count=count+1;
end
end
end
代码给出了令人满意的结果,但问题是它在我机器上的 matlab 中花费了很多时间(1 秒),我真的需要优化它,任何类型的帮助或建议以其他方式进行欢迎
这是一种 vectorized
方法 -
%// Sum elements of image1 & image2 along the third dimension corresponding
%// to s1 and s2 in the original loopy code
s1v = sum(image1,3);
s2v = sum(image2,3);
%// Pre-calculate all image1,image2 operations that lead to the calculation
%// of d in the original code
allvals = ((image1 - image2).^2)./(image1 + image2);
%// Calculate the first conditional values for the corresponding IF conditional
%// statement in original post - "if(s1>2 && s2>2)"
cond1 = s1v>2 & s2v>2
%// Sum all satisfying first conditional values for getting "count"
count = sum(cond1(:))
%// Calculate the second conditional values for the corresponding IF conditional
%// statement in original post - "if image1(i,j,k)~=0 && image2(i,j,k)~=0"
cond2 = image1~=0 & image2~=0;
%// Map both cond1 and cond2 onto allvals to select specific elements from
%// it and then sum those up for the final output, d
d = sum(cond1(:).'*reshape(cond2.*allvals,[],size(allvals,3)))
最后一行可以用 bsxfun
代替 -
d = sum(allvals(bsxfun(@and,cond1,cond2)))
加速 matlab 代码的黄金法则是避免 for 循环并尽可能使用矢量化代码和矩阵。使用矢量化和逻辑索引可以非常快速地进行此计算。我已经在 Octave 中测试了以下内容,它工作正常并且速度非常快 - 您可能需要将 != 替换为 ~= 以实现 matlab 兼容性。调整 n 和 p 以减轻测试的痛苦(或删除前 4 行)并将 d 初始化为您喜欢的任何值。
n=26;
p=31;
i1=1.5*rand(n,n,p); i2=1.5*rand(n,n,p);
s1=sum(i1,3); s2=sum(i2,3);
indices=((s1>2) & (s2>2)) & ((i1!=0) &(i2!=0));
d=0;
d=d+sum(sum( ( (i1(indices)-i2(indices)).^2 ) ./ (i1(indices)+i2(indices)) )),
count=sum(sum( (s1 > 2) & (s2 > 2) ) )