光电视觉测量系统.docx
《光电视觉测量系统.docx》由会员分享,可在线阅读,更多相关《光电视觉测量系统.docx(15页珍藏版)》请在冰豆网上搜索。
光电视觉测量系统
一.实验名称:
光电视觉测量系统
二.实验目的
1.利用专业照明光源、工业CCD图像采集系统、计算机或图像工作站、图像处理软件包搭建完整的光电测量机器视觉系统。
2.利用搭建的光电测量系统对零件的几何形状参数进行测量。
3.掌握测量典型几何图形的直线、圆孔的基本计算方法。
三.实验原理
1、Hough直线检测
Hough变换是一种特殊的在不同空间之间进行的变换。
设在图像空间有一个目标,其轮廓可用代数方程表示,代数方程中既有图像空间坐标的变量也有属于参数空间的参数。
Hough变换就是图像空间和参数空间之间的一种变换。
对于边界上的n个点的点集,找出共线的点集和直线方程。
设任意两点的直线方程:
y=ax+b,构造一个参数a,b的平面。
则可以得到以下结论:
●xy平面上的任意一条直线y=ax+b,对应在参数ab平面上都有一个点。
●过xy平面一个点(x,y)的所有直线,构成参数ab平面上的一条直线。
●如果点(x1,y1)与点(x2,y2)共线,那么这两点在参数ab平面上的直线将有
一个交点。
●在参数ab平面上相交直线最多的点,对应的xy平面上的直线就是我们
的解。
然而,当图像空间中有直线为竖直线时,斜率a为无穷大,此时,参数空间可采用极坐标。
1.对于边界上的n个点的点集,找出共线的点集和直线方程。
2.对于直角坐标系中的一条直线l,可用
、
来表示该直线,且直线方程
为:
其中,
为原点到该直线的垂直距离,
为垂线与x轴的夹角,这条直线是唯一的。
类比xy平面到ab平面,也可以得到一些性质:
●
域中的一点对应于变换域
中的一条正弦曲线
●变换域
中的一点对应于
域中的一条直线
●
域中一条直线上的n个点对应于变换域
中经过一个公共点的
n条正弦曲线。
●变换域
中一条曲线上的n个点对应于
域中过一个公共点的n
条直线。
综上所述,由图像空间的一点可以在参数空间做一曲线,如果由多个间断点所做的多条曲线交于一点,则这些间断点共线。
2、Hough圆检测
由hough变换直线检测可推导知,图像空间中的一条已知的曲线方程也可以建立相应的参数空间。
所以图形空间的一点,可经过变换运算在参数空间中产生相应的轨迹曲线或曲面。
如果,对应各个间断点的曲线或曲面能够相交,则表明图像空间的诸间断点的连线符合已知曲线。
最后寻找参数空间的极大值,便可检测出来。
如果曲线或曲面不相交,则表明图像空间的诸间断点的连线不符合某已知曲线。
圆就相当于曲线,所以也可以用Hough变换检测出来。
圆的图像空间方程为:
通过Hough变换,可以将
图像空间对应到参数空间
,然后对其进行累加完成检测。
对应的公式为:
四.实验步骤
1、Hough直线检测
a)图像预处理
b)在
、
的极值范围内对其分别进行m,n等分,形成一个二维数组,设一个二维数组的下标(即每一个元素)对应空间
中的一个网格(与
、
值对应);
c)数组中每个元素置初值0。
d)对空间
中的每个间断点作Hough变换,在对应的空间
中产生一条曲线,曲线所经过的每个网格的对应数组元素,其值增加1。
e)如果这些图像空间点共线,则参数空间中的曲线必有交点,那么找出数组中的极大元素,该元素坐标
所对应的空间
中的直线就是所要检测的少数间断点形成的直线。
f)检测出
平面上n点后,将交点坐标
带入
得到逼近n点的直线方程。
2、Hough圆检测
a)图像预处理
b)找出处理后图像中想要的点
,求出这些点对应的
空间中的圆锥曲线。
c)通过预分配内存设计
空间的累计器,计算
空间中每一个网格中累计的个数。
d)由于在
空间中共圆的点,对应与
空间的圆锥曲线会有共同的交点,只需找出满足一定阈值范围内的点,这些点所对应的坐标就对应于
空间的圆心坐标和半径大小,这样就可以在原图中找到圆。
五.实验结果及分析
1、
Hough直线检测
从上述结果可以看出,利用Hough极坐标直线变换可以很清楚的标注出原图中的直线;而对于显示场景中的图,由于噪声的干扰,只能识别比较明显的直线,而且运算时间加长。
2、
Hough圆检测
对于上述两个图,用hough圆变换可以很明显的标出原图中的圆,但是不足之处在于需要设定合理的阈值、步长以及初始搜索半径,这样可以提高效率,并且免去很多干扰,从而大大缩短程序的运行时间。
六.实验心得体会和建议
●心得体会:
通过这次实验让我掌握Hough变换的基本原理,并能够用其进行直线和圆的检测。
●建议:
可以要求同学们用多种方式进行直线和圆的检测。
七.程序源代码
1、Hough直线检测
%%读取并显示原图
clc,clearall,closeall
f=imread('malu.jpg');%读入彩色图像,注意不能使用灰度图像
f=imread('line.jpg');
o=f;%保留彩色原图
f=rgb2gray(f);%将彩色图像转换为灰度图像,
f=im2double(f);
figure();
subplot(2,2,1);imshow(o);title('原图');
%%提取图像边缘
[m,n]=size(f);%得到图像矩阵行数m,列数n
fori=3:
m-2
forj=3:
n-2%处理领域较大,所以从图像(3,3)开始,在(m-2,n-2)结束
l(i,j)=-f(i-2,j)-f(i-1,j-1)-2*f(i-1,j)-f(i-1,j+1)-f(i,j-2)-2*f(i,j-1)+16*f(i,j)-2*f(i,j+1)-f(i,j+2)-f(i+1,j-1)-2*f(i+1,j)-f(i+1,j+1)-f(i+2,j);%LoG算子
end
end
subplot(2,2,2);imshow(l);title('LoG算子提取图像边缘');
%%滤波
[m,n]=size(l);
fori=2:
m-1
forj=2:
n-1y(i,j)=l(i-1,j-1)+l(i-1,j)+l(i-1,j+1)+l(i,j-1)+l(i,j)+l(i,j+1)+l(i+1,j-1)+l(i+1,j)+l(i+1,j+1);
y(i,j)=y(i,j)/9;%LoG算子提取边缘后,对结果进行均值滤波以去除噪声,为下一步hough变换提取直线作准备
end
end
subplot(2,2,3);imshow(y);title('均值滤波器处理后')
%%二值化
q=im2uint8(y);
[m,n]=size(q);
fori=1:
m
forj=1:
n
ifq(i,j)>80;%设置二值化的阈值为80
q(i,j)=255;%对图像进行二值化处理,使图像边缘更加突出清晰
else
q(i,j)=0;
end
end
end
subplot(2,2,4);imshow(q);title('二值化处理后');
%%检测直线(快速查找)
%Hough变换检测直线,使用(a,p)参数空间,a∈[0,180],p∈[0,2d]
a=180;%角度的值为0到180度
d=round(sqrt(m^2+n^2));%图像对角线长度为p的最大值
s=zeros(a,2*d);%存储每个(a,p)个数
z=cell(a,2*d);%用元胞存储每个被检测的点的坐标
fori=1:
m
forj=1:
n%遍历图像每个点
if(q(i,j)==255)%只检测图像边缘的白点,其余点不检测
fork=1:
a
p=round(i*cos(pi*k/180)+j*sin(pi*k/180));%对每个点从1到180度遍历一遍,取得经过该点的所有直线的p值(取整)
if(p>0)%若p大于0,则将点存储在(d,2d)空间
s(k,d+p)=s(k,d+p)+1;%(a,p)相应的累加器单元加一
z{k,d+p}=[z{k,d+p},[i,j]'];%存储点坐标
else
ap=abs(p)+1;%若p小于0,则将点存储在(0,d)空间
s(k,ap)=s(k,ap)+1;%(a,p)相应的累加器单元加一
z{k,ap}=[z{k,ap},[i,j]'];%存储点坐标
end
end
end
end
end
%%显示直线
fori=1:
a
forj=1:
d*2%检查每个累加器单元中存储数量
if(s(i,j)>70)%将提取直线的阈值设为70
lp=z{i,j};%提取对应点坐标
fork=1:
s(i,j)%对满足阈值条件的累加器单元中(a,p)对应的所有点进行操作
o(lp(1,k),lp(2,k),1)=255;%每个点R分量=255,G分量=0,B分量=0
o(lp(1,k),lp(2,k),2)=0;
o(lp(1,k),lp(2,k),3)=0;%结果为在原图上对满足阈值要求的直线上的点赋红色
end
end
end
end
figure,imshow(o);title('hough变换提取直线');
2、Hough圆检测
clc,clearall
f=imread('yingbi.jpg');%读入彩色图像,注意不能使用灰度图像
o=f;%保留彩色原图
f=rgb2gray(f);%将彩色图像转换为灰度图像,
f=im2double(f);
figure();
subplot(2,2,1);imshow(o);title('原图');
%%提取图像边缘
[m,n]=size(f);%得到图像矩阵行数m,列数n
fori=3:
m-2
forj=3:
n-2%处理领域较大,所以从图像(3,3)开始,在(m-2,n-2)结束
l(i,j)=-f(i-2,j)-f(i-1,j-1)-2*f(i-1,j)-f(i-1,j+1)-f(i,j-2)-2*f(i,j-1)+16*f(i,j)-2*f(i,j+1)-f(i,j+2)-f(i+1,j-1)-2*f(i+1,j)-f(i+1,j+1)-f(i+2,j);%LoG算子
end
end
%subplot(2,2,2);imshow(l);title('LoG算子提取图像边缘');
%%滤波
[m,n]=size(l);
fori=2:
m-1
forj=2:
n-1y(i,j)=l(i-1,j-1)+l(i-1,j)+l(i-1,j+1)+l(i,j-1)+l(i,j)+l(i,j+1)+l(i+1,j-1)+l(i+1,j)+l(i+1,j+1);
y(i,j)=y(i,j)/9;%LoG算子提取边缘后,对结果进行均值滤波以去除噪声,为下一步hough变换提取直线作准备
end
end
%subplot(2,2,3);imshow(y);title('均值滤波器处理后')
%%二值化
q=im2uint8(y);
[m,n]=size(q);
fori=1:
m
forj=1:
n
ifq(i,j)>80;%设置二值化的阈值为80
q(i,j)=255;%对图像进行二值化处理,使图像边缘更加突出清晰
else
q(i,j)=0;
end
end
end
subplot(2,2,2);imshow(q);title('二值化处理后');
%%***************hough圆变换*********************************
BW=q;
step_r=10;%设定半径搜索步长
r_min=50;%最小半径和最大半径,确定搜索范围
r_max=150;
[m,n]=size(BW);
r=round((r_max-r_min)/step_r)+1;%半径最大搜索次数
adder=zeros(m,n,r);
[x,y]=find(BW);%找出矩阵中的非零值
count=size(x);%计算非零值的个数
forN=1:
count
forR=1:
r
forA=1:
360
A=(A/360)*2*pi;
a=round(x(N)-(r_min+step_r*(R-1))*cos(A));
b=round(y(N)-(r_min+step_r*(R-1))*sin(A));
if(a>0&&a<=m&&b>0&&b<=n)
adder(a,b,R)=adder(a,b,R)+1;%参数空间累加器加1
end
end
end
end
%%画出原图中的圆,并找出圆心
max_adder=max(max(max(adder)));%找出空间累计器中储存最多的点数
thre=0.85;%根据经验设定阈值比重
index=find(adder>=max_adder*thre);%找出满足阈值范围内点的序数
l=length(index);
a1=zeros(l,1);
b1=zeros(l,1);
r1=zeros(l,1);
subplot(2,2,3),imshow(o),holdon,title('圆形检测结果');
fori=1:
l
[a1(i),b1(i),r1(i)]=ind2sub(size(adder),index(i));%根据序数找出其所对应的坐标
r1(i)=r_min+step_r*(r1(i)-1);%算出半径(之前的r(i)代表的是步长的个数而不是半径)
plot(b1(i),a1(i),'.red');%标注圆心
%根据坐标画出圆
rectangle('position',[b1(i)-r1(i),a1(i)-r1(i),2*r1(i),2*r1(i)],'curvature',[1,1],'edgecolor','r');
end
报告评分:
指导教师签字: