我正在尝试为图像创建自适应的椭圆结构元素以使其扩张或腐蚀。我编写了这段代码,但不幸的是所有结构元素都是ones(2*M+1)
。
I = input('Enter the input image: ');
M = input('Enter the maximum allowed semi-major axes length: ');
% determining ellipse parameteres from eigen value decomposition of LST
row = size(I,1);
col = size(I,2);
SE = cell(row,col);
padI = padarray(I,[M M],'replicate','both');
padrow = size(padI,1);
padcol = size(padI,2);
for m = M+1:padrow-M
for n = M+1:padcol-M
a = (l2(m-M,n-M)+eps/l1(m-M,n-M)+l2(m-M,n-M)+2*eps)*M;
b = (l1(m-M,n-M)+eps/l1(m-M,n-M)+l2(m-M,n-M)+2*eps)*M;
if e1(m-M,n-M,1)==0
phi = pi/2;
else
phi = atan(e1(m-M,n-M,2)/e1(m-M,n-M,1));
end
% defining structuring element for each pixel of image
x0 = m;
y0 = n;
se = zeros(2*M+1);
row_se = 0;
for i = x0-M:x0+M
row_se = row_se+1;
col_se = 0;
for j = y0-M:y0+M
col_se = col_se+1;
x = j-y0;
y = x0-i;
if ((x*cos(phi)+y*sin(phi))^2)/a^2+((x*sin(phi)-y*cos(phi))^2)/b^2 <= 1
se(row_se,col_se) = 1;
end
end
end
SE{m-M,n-M} = se;
end
end
a
,b
和phi
是半长轴和半短轴长度和phi之间角度a
和X轴。
我使用了2个MATLAB函数来计算图像的局部结构张量,然后计算每个像素的特征值和特征向量。这些是矩阵l1
,l2
,e1
和e2
。
这是我不明白的代码的一部分:
a = (l2(m-M,n-M)+eps/l1(m-M,n-M)+l2(m-M,n-M)+2*eps)*M; b = (l1(m-M,n-M)+eps/l1(m-M,n-M)+l2(m-M,n-M)+2*eps)*M;
我简化了b
to的表达式(只是删除了索引):
b = (l1+eps/l1+l2+2*eps)*M;
对于l1
与l2
在正常范围内,我们得到:
b =(approx)= (l1+0/l1+l2+2*0)*M = (l1+l2)*M;
因此,b
可以轻松地大于M
,我认为这不是你的意图。在eps
这种情况下也不能防止被零除,通常是增加的目的eps
:如果l1
是零,eps/l1
是Inf
。
查看此表达式,在我看来,你原本打算这样做的:
b = (l1+eps)/(l1+l2+2*eps)*M;
在这里,你要添加eps
到每个特征值,以确保它们不为零(结构张量是对称的,正半定数)。然后,你将除以l1
特征值之和,然后乘以M
,得出每个轴之间0
和之间的值M
。
因此,这似乎是括号放置错误的情况。
仅作记录,这是你代码中需要的:
a = (l2(m-M,n-M)+eps ) / ( l1(m-M,n-M)+l2(m-M,n-M)+2*eps)*M;
b = (l1(m-M,n-M)+eps ) / ( l1(m-M,n-M)+l2(m-M,n-M)+2*eps)*M;
^ ^
added parentheses
请注意,你可以通过在循环之外进行定义来简化代码:
[se_x,se_y] = meshgrid(-M:M,-M:M);
然后可以简单地将内部的两个循环overi
和j
构建se
为:
se = ((se_x.*cos(phi)+se_y.*sin(phi)).^2)./a.^2 + ...
((se_x.*sin(phi)-se_y.*cos(phi)).^2)./b.^2 <= 1;
(请注意.*
和.^
运算符,它们执行逐元素乘法和幂运算。)
进一步轻微改善来自意识到phi
首先从计算e1(m,n,1)
和e1(m,n,2)
,然后在调用中使用cos
和sin
。如果我们假设特征向量已正确归一化,则
cos(phi) == e1(m,n,1)
sin(phi) == e1(m,n,2)
但是你始终可以确保将它们标准化:
cos_phi = e1(m-M,n-M,1);
sin_phi = e1(m-M,n-M,2);
len = hypot(cos_phi,sin_phi);
cos_phi = cos_phi / len;
sin_phi = sin_phi / len;
se = ((se_x.*cos_phi+se_y.*sin_phi).^2)./a.^2 + ...
((se_x.*sin_phi-se_y.*cos_phi).^2)./b.^2 <= 1;
考虑到三角运算非常昂贵,因此应该可以稍微加快代码的速度。
好像您回答了我的问题。OP不想将
eps
自己除以数字,我认为这对计算几乎没有帮助。哦,顺便说一句,如果您使用
l1 + eps(l1)
等等会更好。eps
无输入参数默认为eps(1)
,这是最小的数被添加到1
使比的总和不同1
。现在考虑其中的情况abs(l1) < eps(1)
。例如。l1=1e-30
和l2=2e-30
和l1/l2
不除以零操作。@Yvon怎么
eps(0)
办?关键不是要创建比稍大的东西l1
,而是要确保l1
它不为0。eps(0) = 4.9407e-324
和1/eps(0) = Inf
另外如果l1 = 1e-30; l2 = 2e-30;
再l1/l2 = 0.5000
和l1/(l2+eps) = 4.5036e-15
嗯,如果他们不关心很小的值上的运算,那么这样做就可以了。最好将这件事排除在OP的问题之外。