TSAI相机标定(matlab)
在做一维测量、三维测量之前,必须先对视觉系统进行标定;这里给出由matlab实现的TSAI标定方法,当然matlab里面也有自带的张正友标定法模块。
直接上代码:
%清空变量,关闭窗口
clear;close all;
%读取图像
img=imread('1.bmp');
I1=imread('1.bmp');
[M,N]=size(I1);
%使用最大类间方差法找到图片的一个合适的阈值
level=graythresh(I1);
%设level为阈值,将图片二值化
I1=im2bw(I1,level);
%开操作一般应用在二值图像分析处理的基础上,使对象的轮廓变得光滑,断开狭窄的间断和消除细的突出物。
%主要用来保留某种结构操作,消除其他不符合结构区域的前景区域像素。
%创建半径为2的圆盘结构元素
se=strel('disk',1);
%用创建好的结构元素对图形开操作
openI1=imopen(I1,se);
%把连通域面积小于4个像素的都删掉
L=bwareaopen(I1,4);
% 获得图像99个联通域的属性(面积大小,重心位置,包围该区域的最小矩形),生成一个结构体stats
stats = regionprops(L, 'basic');
% 用CAT函数将stats结构体中的重心数据提取出来
zhongxin=cat(1,stats.Centroid);
[M,N]=size(zhongxin);
figure(1)
imshow(L),title('二值化后图像中心坐标'),hold on
for i=1:M
plot(zhongxin(i,1),zhongxin(i,2),'r*');
end
%%图片的重心数据保存在一个矩阵里,由于regionprops函数的原因,此函数会将连通域按从小到大的顺序排列,所以得到的重心数据并不是一一对应的,需要使用排序算法对这些数据进行重新排列。排序算法如下:
% 冒泡排序,将顺序未知的坐标按位置排序
for a=0:10
for i=1+9*a:9+9*a
X(i,1)=zhongxin(i,1);
X(i,2)=zhongxin(i,2);
end
for j=1:8
for k=1+9*a:9+9*a-1
if X(k+1,2)<X(k,2)
temp1=X(k,1);
temp2=X(k,2);
X(k,1)=X(k+1,1);
X(k,2)=X(k+1,2);
X(k+1,1)=temp1;
X(k+1,2)=temp2;
end
end
end
end
% 得到所有重心的坐标
for i=1:11
u(:,i) =X(1+9*(i-1):9*i,1);
v(:,i) = X(1+9*(i-1):9*i,2);
end
%%由我编写的冒泡排序算法将各个连通域的重心坐标按照从左到右,从上到下的顺序排列好,方便对应相应的世界坐标。排序好的重心坐标的横纵坐标需要按找每一列或每一行的顺序使用最小二乘法拟合直线,方法如下(使用polyfit函数):
% 9条水平直线的斜率和截距
for i=1:9
Y1(i,:)=polyfit(u(i,:),v(i,:),1);
end
% 11条竖线的斜率和截距
for i=1:11
Y2(i,:)=polyfit(u(:,i),v(:,i),1);
end
% 得到两直线相交的坐标
for i=1:9
for j=1:11
a1=Y1(i,1);
a2=Y2(j,1);
b1=Y1(i,2);
b2=Y2(j,2);
x=(b2-b1)/(a1-a2); %solve( ( a1-a2)*x==b2-b1 );
M1(i,j)=x; %交点的X坐标(像素)
M2(i,j)=Y1(i,1)*x+Y1(i,2); %交点的Y坐标(像素)
end
end
%检验
figure(2)
imshow(L),title('所有直线在图像中的位置和交点'),hold on
for i=1:9
for j=1:11
plot(M1(i,j),M2(i,j),'b*');
end
end
for i=1:9
pxi=linspace(1,2100);
pyi=Y1(i,1)*pxi+Y1(i,2);
plot(pxi,pyi,'g');
end
for j=1:11
pxi=linspace(1,2800);
pyi=Y2(j,1)*pxi+Y2(j,2);
plot(pxi,pyi,'r');
end
%以中间圆点为原点建立世界坐标系
for i=1:9
for j=1:11
XW(i,j)=10*(i-4); %以中心圆点为世界坐标中心计算下其它圆点的世界坐标(横坐标)
YW(i,j)=10*(j-5); %以中心圆点为世界坐标中心计算下其它圆点的世界坐标(纵坐标)
end
end
% 将9X11的像素坐标矩阵转化为99X1的像素坐标矩阵,保证符合TSAI函数的要求
k=1;
for i=1:9
for j=1:11
Xf(k,1)=M1(i,j); %每个点的横坐标(像素)
Yf(k,1)=M2(i,j); %每个点的纵坐标(像素)
k=k+1;
end
end
% 将9X11的世界坐标矩阵转化为99X1的世界坐标矩阵,保证符合TSAI函数的要求
k=1;
for i=1:9
for j=1:11
xw(k,1)=XW(i,j); %每个点的横坐标(世界)
yw(k,1)=YW(i,j); %每个点的纵坐标(世界)
k=k+1;
end
end
zw=zeros(99,1); %由于选择标定板中心圆点为世界坐标系原点,所以z的世界坐标都为0
Ncx=1; %图像的缩放比都为1
Nfx=1;
Cx=512;
Cy=640; %获得的1024X1280大小的图片的中心点(512,640)
dx=0.0048; %相元尺寸
dy=0.0048;
sx=1; %固定为1
%%使用TSAI算法计算相机的相应参数:
%%[R, T, f, k1] = Tsai(Xf, Yf, xw, yw, zw, Ncx, Nfx, dx, dy, Cx, Cy, sx);
%%TSAI算法需要的参数为各个重心的像素坐标,对应的世界坐标,图像的横纵拉伸比,相机的相元尺寸,相机拍出图像的中心坐标(分辨率的一半),和一个常数se=1;
[R, T, f, k1] = Tsai(Xf, Yf, xw, yw, zw, Ncx, Nfx, dx, dy, Cx, Cy, sx);
disp('相机焦距是:' );
f
disp('旋转矩阵是:');
R
disp('平移矩阵是:');
T
disp('畸变参数是:');
k1
其中最后所需要的TSAI函数可下载!!配套使用
转载自原文链接, 如需删除请联系管理员。
原文链接:TSAI法相机标定(matlab),转载请注明来源!