MATLAB实现双目校准
2017-10-22 20:32
204 查看
MATLAB实现双目图像校准
在网上见的大多数双目图像校准都是MATLAB与OpenCV结合来实现的,经过两个月断断续续的学习,总算用纯MATLAB实现的图像校准算法。下面对这一段时间的成果进行总结和防止以后重新学习。
不废话,直接开始吧。。。。。。
说到双目系统首先必须要说一下双目模型。
首先我们要先只要三个坐标系:图像坐标系、相机坐标系、世界坐标系。
可参考http://www.cnblogs.com/dverdon/p/5609124.html
其中相机坐标转换为图像坐标:
其中u0、v0为图像平面的主点,dx、dy为相机的像元尺寸大小,u、v为图像坐标点、x、y为相机坐标点。
其中,Xc、Yc、Zc代表相机坐标系,X、Y、Z为世界坐标系。R为旋转矩阵,T为平移矩阵。
以上为理想状态下的双目视觉模型,但在实际中,相机的或多或少都存在畸变。因此在实际应用中要将畸变图像进行矫正。
世界坐标转换为相机坐标畸变矫正
相机的畸变模型公式:
可参考http://blog.csdn.net/wangxiaokun671903/article/details/37973365
http://blog.csdn.net/humanking7/article/details/45037239
上面两篇文章讲的很详细,我在这里就复制粘贴了。
综合以上内容,可以总结为一下内容(我很懒,就直接粘贴过来了)
该过程为世界坐标系转换为图像坐标系的过程
该过程为相机畸变处理过程
以上对原理进行了简单介绍,网上资料比我讲的详细,我这里只是防止忘记,做一个备份。
下面开始相机标定过程:这里我直接参考http://blog.csdn.net/dreamharding/article/details/53700166
这里我将最终的标定结果贴出来
开始上代码:
公式法:
主要参考http://blog.csdn.net/wangxiaokun671903/article/details/38017055和工具箱代码
该过程是直接根据公式进行编写。执行效率很慢。
直接法:
主要参考工具箱代码
这里首先我们需要对工具箱源代码进行修改。
在工具箱中找到rectify_stereo_pair.m,添加如在代码。
添加如图:
点击Rectifu the calibration images
最终会多出两个文件
这两个文件就是将原始图像直接转换为平行校准后图像。
该方法可以提高算法的执行效率。
今天先写到这里,下一步利用C++来实现双目校准过程。
在网上见的大多数双目图像校准都是MATLAB与OpenCV结合来实现的,经过两个月断断续续的学习,总算用纯MATLAB实现的图像校准算法。下面对这一段时间的成果进行总结和防止以后重新学习。
不废话,直接开始吧。。。。。。
说到双目系统首先必须要说一下双目模型。
首先我们要先只要三个坐标系:图像坐标系、相机坐标系、世界坐标系。
可参考http://www.cnblogs.com/dverdon/p/5609124.html
其中相机坐标转换为图像坐标:
其中u0、v0为图像平面的主点,dx、dy为相机的像元尺寸大小,u、v为图像坐标点、x、y为相机坐标点。
其中,Xc、Yc、Zc代表相机坐标系,X、Y、Z为世界坐标系。R为旋转矩阵,T为平移矩阵。
以上为理想状态下的双目视觉模型,但在实际中,相机的或多或少都存在畸变。因此在实际应用中要将畸变图像进行矫正。
世界坐标转换为相机坐标畸变矫正
相机的畸变模型公式:
可参考http://blog.csdn.net/wangxiaokun671903/article/details/37973365
http://blog.csdn.net/humanking7/article/details/45037239
上面两篇文章讲的很详细,我在这里就复制粘贴了。
综合以上内容,可以总结为一下内容(我很懒,就直接粘贴过来了)
该过程为世界坐标系转换为图像坐标系的过程
该过程为相机畸变处理过程
以上对原理进行了简单介绍,网上资料比我讲的详细,我这里只是防止忘记,做一个备份。
下面开始相机标定过程:这里我直接参考http://blog.csdn.net/dreamharding/article/details/53700166
这里我将最终的标定结果贴出来
开始上代码:
公式法:
主要参考http://blog.csdn.net/wangxiaokun671903/article/details/38017055和工具箱代码
clc;clear; I1 = rgb2gray(imread('右图片路径')); I2 = rgb2gray(imread('左图片路径')); [m,n] = size(I1); I11 = zeros(m,n)+255; [m,n] = size(I2); I22 = zeros(m,n)+255; A1 = [665.32773 0 345.54178;... 0 660.17940 249.92143;... 0 0 1]; D1 = [0.22386 -0.93591 0.00725 0.00018 0.00000]; A2 = [688.30717 0 315.31975;... 0 683.13738 264.40537;... 0 0 1]; D2 = [0.27153 -1.00396 0.01107 0.00364 0.00000 ]; fx1 = A1(1,1); fy1 = A1(2,2); cx1 = A1(1,3); cy1 = A1(2,3); k11 = D1(1); k12 = D1(2); p11 = D1(3); p12 = D1(4); k13 = D1(5); fx2 = A2(1,1); fy2 = A2(2,2); cx2 = A2(1,3); cy2 = A2(2,3); k21 = D2(1); k22 = D2(2); p21 = D2(3); p22 = D2(4); k23 = D2(5); fx = (fx1 + fx2)/2; fy = (fy1 + fy2)/2; cx = (cx1 + cx2)/2; cy = (cy1 + cy2)/2; T = [-39.78384 1.21230 -40.44029]; om = [-0.02302 -0.00735 0.00089]; % 以下部分为直接拷贝工具箱源码内容 start r_r = rodrigues(-om/2); r_l = r_r'; t = r_r * T; % Rotate both cameras so as to bring the translation vector in alignment with the (1;0;0) axis: if abs(t(1)) > abs(t(2)), type_stereo = 0; uu = [1;0;0]; % Horizontal epipolar lines else type_stereo = 1; uu = [0;1;0]; % Vertical epipolar lines end; if dot(uu,t)<0, uu = -uu; % Swtich side of the vector end; ww = cross(t,uu); ww = ww/norm(ww); ww = acos(abs(dot(t,uu))/(norm(t)*norm(uu)))*ww; R = rodrigues(ww); % Global rotations to be applied to both views: R1 = R * r_r; R2 = R * r_l; T_new = R1*T; % 以上部分为直接拷贝工具箱源码内容 end for v=1:m %640 for u=1:n %480 x = (v - cx1)/fx1; y = (u - cy)/fy1; pos=[x;y;1]; %3x1 pos=inv(R1)*pos; %旋转相机坐标系,3x1 x1=pos(1,:)/pos(3,:);%归一化 y1=pos(2,:)/pos(3,:); r=x1^2+y1^2; x2 = x1*(1+k11*r+k12*r^2+k13*r^3) + 2*p11*x1*y1+p12*(r+2*x1^2); y2 = y1*(1+k11*r+k12*r^2+k13*r^3) + 2*p12*x1*y1+p11*(r+2*y1^2); x3 = x2*fx1 +cx1; y3 = y2*fy1 +cy; if (x3>1 && x3<=n && y3>1 && y3<=m) h=y3; w=x3; I11(v,u)=(floor(w+1)-w)*(floor(h+1)-h)*I1(floor(h),floor(w))+(floor(w+1)-w)*(h-floor(h))*I1(floor(h+1),floor(w))+(w-floor(w))*(floor(h+1)-h)*I1(floor(h),floor(w+1))+(w-floor(w))*(h-floor(h))*I1(floor(h+1),floor(w+1)); end if mod(v,50) == 0 I11(v,u) = 255; end end end for v=1:m %640 for u=1:n %480 x = (v - cx2)/fx2; y = (u - cy)/fy2; pos=[x;y;1]; %3x1 pos=inv(R2)*pos; %旋转相机坐标系,3x1 x1=pos(1,:)/pos(3,:);%归一化 y1=pos(2,:)/pos(3,:); r=x1^2+y1^2; x2 = x1*(1+k21*r+k22*r^2+k23*r^3) + 2*p21*x1*y1+p22*(r+2*x1^2); y2 = y1*(1+k21*r+k22*r^2+k23*r^3) + 2*p22*x1*y1+p21*(r+2*y1^2); x3 = x2*fx2 +cx2; y3 = y2*fy2 +cy; if (x3>1 && x3<=n && y3>1 && y3<=m) h=y3; w=x3; I22(v,u)=(floor(w+1)-w)*(floor(h+1)-h)*I1(floor(h),floor(w))+(floor(w+1)-w)*(h-floor(h))*I1(floor(h+1),floor(w))+(w-floor(w))*(floor(h+1)-h)*I1(floor(h),floor(w+1))+(w-floor(w))*(h-floor(h))*I1(floor(h+1),floor(w+1)); end if mod(v,50) == 0 % 画线 I22(v,u) = 255; end end end figure;imshow(I11,[]); figure;imshow(I22,[]);
该过程是直接根据公式进行编写。执行效率很慢。
直接法:
主要参考工具箱代码
这里首先我们需要对工具箱源代码进行修改。
在工具箱中找到rectify_stereo_pair.m,添加如在代码。
save result_left ind_new_left ind_1_left ind_2_left ind_3_left ind_4_left a1_left a2_left a3_left a4_left ; save result_right ind_new_right ind_1_right ind_2_right ind_3_right ind_4_right a1_right a2_right a3_right a4_right ;
添加如图:
点击Rectifu the calibration images
最终会多出两个文件
这两个文件就是将原始图像直接转换为平行校准后图像。
clc;clear; I = double(rgb2gray(imread('左图像路径'))); re = load('result_left.mat'); ind_new_left = re.ind_new_left; a1_left = re.a1_left; ind_1_left = re.ind_1_left; a2_left = re.a2_left; ind_2_left = re.ind_2_left; a3_left = re.a3_left; ind_3_left = re.ind_3_left; a4_left = re.a4_left; ind_4_left= re.ind_4_left; Il = 255*ones(480,640); Il(ind_new_left) = uint8(a1_left .* I(ind_1_left) + a2_left .* I(ind_2_left) + a3_left .* I(ind_3_left) + a4_left .* I(ind_4_left)); I = double(rgb2gray(imread('右图像路径'))); re = load('result_right.mat'); ind_new_right = re.ind_new_right; a1_right = re.a1_right; ind_1_right = re.ind_1_right; a2_right = re.a2_right; ind_2_right = re.ind_2_right; a3_right = re.a3_right; ind_3_right = re.ind_3_right; a4_right = re.a4_right; ind_4_right = re.ind_4_right; Ir = 255*ones(480,640); Ir(ind_new_left) = uint8(a1_left .* I(ind_1_left) + a2_left .* I(ind_2_left) + a3_left .* I(ind_3_left) + a4_left .* I(ind_4_left)); for i = 1:480 for j = 1:640 if mod(i,20)==0 Il(i,j) = 255; Ir(i,j) = 255; end end end figure;imshow(Il,[]); figure;imshow(Ir,[]);
该方法可以提高算法的执行效率。
今天先写到这里,下一步利用C++来实现双目校准过程。
相关文章推荐
- 基于matlab标定数据,使用opencv实现双目立体摄像头的标定(源代码)
- Gamma correction 伽马校准及 matlab 实现
- C++实现双目校准
- 基于matlab标定数据,使用opencv实现双目立体摄像头的标定(源代码)
- matlab实现之线性规划
- RPCL(Rival Penalized Competitive Learning)在matlab下的实现
- logistic regression 逻辑回归 matlab实现
- 伽马滤波实现(Matlab源码)
- 分枝定界的matlab实现
- 双目测距与三维重建的OpenCV实现问题集锦(四)三维重建与OpenGL显示
- 高斯分布中均值,方差,协方差的计算及matlab实现
- 粒子群算法的matlab实现
- 数据挖掘——线性神经网络的Matlab实现
- 击中击不中变换Matlab实现
- MATLAB实现PFFM算法
- Matlab VC 联合编程 控制台以及MFC中实现(二)
- 朴素贝叶斯算法实现分类问题(三类)matlab代码
- 统计相关系数(1)——Pearson(皮尔逊)相关系数及MATLAB实现
- matlab实现SMOTE
- 压缩感知中的常见测量矩阵及其MATLAB实现代码