hough 变换提取椭圆
任意椭圆方程表达式
x
y
a
a
cos
cos
cos
sin
b
b
sin
sin
sin
cos
p
q
步骤:1、读入图片(图片大小为
256 ),将图片二值化并提取边
256
缘(用 edge);
2、设置一个5维的参数空间并使初值为0;
3、对边缘点集中的每一点进行hough 变换,如果p、q在图像范围内,
则
hough_spac
e(p,
a,q,
b,
)
hough_spac
e(p,
a,q,
b,
)
1
;
4、在参数空间中寻找超过阈值的
5、再对椭圆参数进行求精;
,
baqp
,
,
,
,就是椭圆的参数;
(直接讲下面的程序复制到.m 文件里,再改 a、b、theta 参数 运行)
%读入要提取椭圆的图片
程序:椭圆提取(图片大小 256*256)
f1=imread('你的图片.JPG');
imshow(f1)
f2=im2bw(f1,0.72); %二值化
f3=im2uint8(f2);
figure
imshow(f3)
BW=edge (f3,'canny',[0,0.7],0.9); %提取边缘
figure
imshow(BW)
[n,m] = size(BW);
a_max=80;
a_min=70;
b_max=50;
b_min=40;
step_a=2;
step_b=2;
theta_min=-pi/18;
theta_max=pi/9;
step_theta=pi/60;
step_angle=1;
yz =0.82;
%a为椭圆长轴,范围需要自己根据图片中的椭圆形状确定
%b为椭圆短轴
%步长
%theta倾斜角
%阈值(自己定)
size_a = round((a_max-a_min)/step_a)+1;
size_b = round((b_max-b_min)/step_b)+1;
size_theta=round((theta_max-theta_min)/step_theta)+1;
size_angle = round(2*pi/step_angle);
hough_space = zeros(m,n,size_a,size_b,size_theta); %设定5维的参数空间并使
初值为0
[cols,rows] = find(BW);
ecount = size(rows);
%find—找出非零元素的索引
% Hough
%图像空间(x,y)对应到参数空间(a,b,p、q、theta)
% p = x-a*cos(angle)*cos(theta)+b*sin(angle)*sin(theta)
% q = y-a*cos(angle)*sin(theta)-b*sin(angle)*cos(theta)
%rows(i)行坐标
for i=1:ecount
for a=1:size_a
for b=1:size_b
for theta=1:size_theta
for k=1:size_angle
%hough变换
p =
q =
round(rows(i)-(a_min+(a-1)*step_a)*cos(k*step_angle)*cos(theta_min+(t
heta-1)*step_theta)+(b_min+(b-1)*step_b)*sin(k*step_angle)*sin(theta_
min+(theta-1)*step_theta));
round(cols(i)-(a_min+(a-1)*step_a)*cos(k*step_angle)*sin(theta_min+(t
heta-1)*step_theta)-(b_min+(b-1)*step_b)*sin(k*step_angle)*cos(theta_
min+(theta-1)*step_theta));
if(p>0&p<=m&q>0&q<=n)
hough_space(p,q,a,b,theta) =
hough_space(p,q,a,b,theta)+1;
end
end
end
end
end
end
% 搜索超过阈值的聚焦点
max_para = max(max(max(max(max(hough_space)))));
index = find(hough_space>max_para*yz);
值的缩引并存入 index
length = size(index);
hough_circle1=zeros(m,n);
hough_circle2=zeros(m,n);
%确定为椭圆上的点的坐标
%find—找出hough_space中大于阈
%找出峰值对应的参数空间坐标
for k=1:length
floor((index(k)-1)/(m*n*size_a*size_b))+1;
par5=theta_min+(par5-1)*step_theta;
par4 = b_min+(par4-1)*step_b;
par3 = a_min+(par3-1)*step_a;
theta(k)=par5;
b(k)=par4;
a(k)=par3;
q(k)=par2;
p(k)=par1;
end
%求出两圆参数平均值
%theta增量
%b增量
par5 =
par4 =
par3 =
par1 =
floor((index(k)-(par5-1)*(m*n*size_a*size_b))/(m*n*size_a))+1;
floor((index(k)-(par5-1)*(m*n*size_a*size_b)-(par4-1)*(m*n*size_a))/(
m*n))+1;
par2 =
%a 增量
floor((index(k)-(par5-1)*(m*n*size_a*size_b)-(par4-1)*(m*n*size_a)-(p
ar3-1)*(m*n))/m)+1; %p增量
index(k)-(par5-1)*(m*n*size_a*size_b)-(par4-1)*(m*n*size_a)-(par3-1)*
(m*n)-(par2-1)*m;
%q增量
[row1 col1]=size(p);
count=1;
theta=sort(theta);
p=sort(p);
q=sort(q);
a=sort(a);
b=sort(b);
THETA(count)=theta(1);
P(count)=p(1);
A(count)=a(1);
B(count)=b(1);
Q(count)=q(1);
for t=1:1:col1
if abs(P(count)-p(t))<=10
THETA(count)=(theta(t)+THETA(count))/2;
A(count)=(a(t)+A(count))/2;
B(count)=(b(t)+B(count))/2;
P(count)=(p(t)+P(count))/2;
Q(count)=(q(t)+Q(count))/2;
else
count=count+1;
THETA(count)=theta(t);
A(count)=a(t);
B(count)=b(t);
P(count)=p(t);
Q(count)=q(t);
end
end
THETA
A
B
P
Q
%绘制椭圆
TYZ=zeros(1,2);
TYY=zeros(1,2);
ct_z=1;
ct_y=1;
for i=1:ecount
if
round(((rows(i)-P(1))*cos(THETA(1))+(cols(i)-Q(1))*sin(THETA(1)))^2/(
A(1)^2)+(-(rows(i)-P(1))*sin(THETA(1))+(cols(i)-Q(1))*cos(THETA(1)))^
2/(B(1)^2))<1.5 ...
&round(((rows(i)-P(1))*cos(THETA(1))+(cols(i)-Q(1))*sin(THETA(1)))^2/
(A(1)^2)+(-(rows(i)-P(1))*sin(THETA(1))+(cols(i)-Q(1))*cos(THETA(1)))
^2/(B(1)^2))>0.5
TYY(ct_y,1)=rows(i);
TYY(ct_y,2)=cols(i);
hough_circle1(cols(i),rows(i))=1;
ct_y=ct_y+1;
end
if
end
round(((rows(i)-P(2))*cos(THETA(2))+(cols(i)-Q(2))*sin(THETA(2)))^2/(
A(2)^2)+(-(rows(i)-P(2))*sin(THETA(2))+(cols(i)-Q(2))*cos(THETA(2)))^
2/(B(2)^2))<1.5 ...
&round(((rows(i)-P(2))*cos(THETA(2))+(cols(i)-Q(2))*sin(THETA(2)))^2/
(A(2)^2)+(-(rows(i)-P(2))*sin(THETA(2))+(cols(i)-Q(2))*cos(THETA(2)))
^2/(B(2)^2))>0.5
TYZ(ct_z,1)=rows(i);
TYZ(ct_z,2)=cols(i);
hough_circle2(cols(i),rows(i))=1;
ct_z=ct_z+1;
end
figure
imshow(hough_circle1),title('¼ì²â½á¹û')
figure
imshow(hough_circle2),title('¼ì²â½á¹û')
WTZ(i1,:)=[TYZ(i1,1)^2 TYZ(i1,1)*TYZ(i1,2) TYZ(i1,2)^2 TYZ(i1,1)
%分别计算两个椭圆的参数
[row_TYZ,col_TYZ]=size(TYZ);
for i1=1:1:row_TYZ
TYZ(i1,2) 1; ];
end
[v_z1,d_z1]=svd(WTZ'*WTZ);
v_z1=vpa(v_z1,8)
d_z1=double(d_z1);
WTY(j1,:)=[TYY(j1,1)^2 TYY(j1,1)*TYY(j1,2) TYY(j1,2)^2 TYY(j1,1)
[row_TYY,col_TYY]=size(TYY);
for j1=1:1:row_TYY
TYY(j1,2) 1; ];
end
[v_y1,d_y1]=svd(WTY'*WTY);
v_y1=vpa(v_y1,8)
d_y1=double(d_y1);
在原图上绘制拟合椭圆,以查看拟合精度
f1=imread('你的图片.JPG');
f2=im2bw(f1,0.72);
f3=im2uint8(f2);
BW=edge (f3,'canny',[0,0.7],0.9);
%绘制左边椭圆
for i2=1:1:256
for j2=1:1:256
if
0
end
end
figure
imshow(f1)
figure
imshow(f2)
figure
imshow(BW)
最后效果