【发布时间】:2016-03-11 17:38:31
【问题描述】:
我想加快我的代码速度。目前,我使用 if 语句来做到这一点。但是,如果我们使用convolution way,它可以编写更快的代码。但是,它仅适用于简单情况(作为成对邻域)。让我们定义我的问题。
我有一个矩阵I=[1 1 1;2 2 2;2 2 1],它有两个标签{1,2}。我将填充添加为其右侧。对于I 中的每个像素,我们可以定义成对或三元组邻域。我们将根据规则“如果这些邻域值与像素具有相同的类别,则设置成本值等于-beta,否则设置成本等于beta”。
例如,让我们考虑上图中的黄色像素。它的标签是 2。我们需要计算可能的邻域情况下的总成本值,如最右侧所示。有趣像素的值将从标签 {1,2} 设置。在上图中。我只展示了将黄色像素设置为 1 的第一种情况。我们可以有相同的数字,但在下一种情况下设置黄色像素为 2。我的任务是根据上述规则计算成本函数。
这是我的代码。但是,它使用 if 语句。太慢了。你能帮我加快速度吗?我尝试使用卷积方式,但我不知道如何为三邻域定义掩码。谢谢大家
function U=compute_gibbs(Imlabel,beta,num_class)
num_class=2;
Imlabel=[1 1 1;2 2 2;2 2 1]
beta=1;
U=zeros([size(Imlabel) num_class]);
Imlabel = padarray(Imlabel,[1 1],'replicate','both');
[row,col] = size(Imlabel);
for ii = 2:row-1
for jj = 2:col-1
for l = 1:num_class
U(ii-1,jj-1,l)=GibbsEnergy(Imlabel,ii,jj,l,beta);
end
end
end
function energy = GibbsEnergy(img,i,j,label,beta)
% img is the labeled image
energy = 0;
if (label == img(i,j)) energy = energy-beta;
else energy = energy+beta;end
% North, south, east and west
if (label == img(i-1,j)) energy = energy-beta;
else energy = energy+beta;end
if (label == img(i,j+1)) energy = energy-beta;
else energy = energy+beta;end
if (label == img(i+1,j)) energy = energy-beta;
else energy = energy+beta;end
if (label == img(i,j-1)) energy = energy-beta;
else energy = energy+beta;end
% diagonal elements
if (label == img(i-1,j-1)) energy = energy-beta;
else energy = energy+beta;end
if (label == img(i-1,j+1)) energy = energy-beta;
else energy = energy+beta;end
if (label == img(i+1,j+1)) energy = energy-beta;
else energy = energy+beta;end
if (label == img(i+1,j-1)) energy = energy-beta;
else energy = energy+beta;end
%% Triangle elements
% Case a
if(label==img(i-1,j)&label==img(i-1,j-1)) energy = energy-beta;
else energy = energy+beta;end
if(label==img(i,j-1)&label==img(i+1 ,j)) energy = energy-beta;
else energy = energy+beta;end
if(label==img(i,j+1)&&label==img(i+1 ,j+1)) energy = energy-beta;
else energy = energy+beta;end
% Case b
if(label==img(i-1,j-1)&label==img(i,j-1)) energy = energy-beta;
else energy = energy+beta;end
if(label==img(i-1,j)&label==img(i ,j+1)) energy = energy-beta;
else energy = energy+beta;end
if(label==img(i+1,j)&label==img(i+1,j+1)) energy = energy-beta;
else energy = energy+beta;end
% Case c
if(label==img(i,j-1)&label==img(i+1,j-1)) energy = energy-beta;
else energy = energy+beta;end
if(label==img(i+1,j)&label==img(i,j+1)) energy = energy-beta;
else energy = energy+beta;end
if(label==img(i-1 ,j)&label==img(i-1,j+1)) energy = energy-beta;
else energy = energy+beta;end
% Case d
if(label==img(i,j-1)&label==img(i-1,j)) energy = energy-beta;
else energy = energy+beta;end
if(label==img(i-1 ,j+1)&label==img(i,j+1)) energy = energy-beta;
else energy = energy+beta;end
if(label==img(i+1,j-1)&label==img(i+1 ,j)) energy = energy-beta;
else energy = energy+beta;end
%% Rectangular
if(label==img(i-1,j-1)&label==img(i,j-1)&label==img(i-1 ,j)) energy = energy-beta;
else energy = energy+beta;end
if(label==img(i,j-1)&label==img(i+1,j-1)&label==img(i+1 ,j)) energy = energy-beta;
else energy = energy+beta;end
if(label==img(i+1,j)&label==img(i +1 ,j+1)&label==img(i,j+1)) energy = energy-beta;
else energy = energy+beta;end
if(label==img(i-1,j)&label==img(i-1,j+1)&label==img(i ,j+1)) energy = energy-beta;
else energy = energy+beta;end
这是一种更快的方法。但它只适用于简单的案例(成对的邻域第一行),而我的案例包括单、三...邻域
C = double(bsxfun(@eq, Imlabel, permute(1:num_class, [1 3 2])));
C(C == 0) = 0;
C(C == 1) = beta;
%% Replace if statement
mask = zeros(3,3); mask(2,2) = 1;
Cpad = convn(C, mask);
Cpad(Cpad == 0) = 0;
mask2 = ones(3,3); mask2(2,2) = 0;
energy = convn(Cpad, mask2, 'valid');
【问题讨论】:
-
为什么不创建蒙版然后将它们相乘?
-
@AnderBiguri:你认为它会更快吗?
-
是的。 MATtrix LABoratory 旨在最快地使用矩阵
-
你能实现它吗?我想和原始代码比较一下计算时间?谢谢
-
哈哈哈哈哈哈。 没有。你看到你的代码有多长了吗?
标签: algorithm performance matlab image-processing