当前位置:   article > 正文

单目三维运动重建(sfm算法)_单目sfm

单目sfm

算法介绍

单目相机三维重建可以使用运动重建Structure from motion(SfM)方法,即由图像生成三维点云以及相机姿态。SfM方法的主要流程如图所示1,第一步,使用同一相机的从不同位置和姿态拍摄需要重建的物体,本实例为了简化后续操作在拍摄被重建物体同时也拍摄了标准标定板,如图2所示,得到原始照片集I={I1,I2,...,In};第二步,使用MATLAB Camera Calibration Toolbox获得相机参数CameraParams,其中包括了相机的内参矩阵K,相机与标定照片的角度转移矩阵R={R1,R2,...,Rn}和位置转移矩阵T={T1,T2,...,Tn};然后,使用图像分割方法将待重建物体在照片I={I1,I2,...,In}中标记出来并二值化,得到F={F1,F2,...,Fn};接下来,选定空间中包含待重建物体的一块区域PR3,使用第二步得到的相相机参数CameraParams,将三维空间P利用成像原理s[uv1]=K[Ri,Ti][P1]重投影到I={I1,I2,...,In}照片坐标中得到重投影坐标M={M1,M2,...,Mn};最后,在M中查找与F={F1,F2,...,Fn}中标记了三维重建物体像素坐标相同的点集,这些点对应的三维点云图就是待重建物体的点云。

算法流程图

 

包含待重建物体和标准标定板的照片
待重建物体分割效果图
重投影效果图
三维重建效果图2
  1. close all;
  2. clear;
  3. clc;
  4. %% 1.Prepare Calibration Images
  5. % Create a cell array of file names of calibration images.
  6. numImages = 11;
  7. files = cell(1, numImages);
  8. for i = 1 : numImages
  9. eval(sprintf('files{%d} = ''d%d.jpg'';', i, i));
  10. end
  11. % Display one of the calibration images
  12. I = imread(files{1});
  13. %% 2.Estimate Camera Parameters
  14. % Detect the checkerboard corners in the images.
  15. [imagePoints, boardSize] = detectCheckerboardPoints(files);
  16. % Generate the world coordinates of the checkerboard corners in the
  17. % pattern-centric coordinate system, with the upper-left corner at (0,0).
  18. squareSize = 47; % in millimeters
  19. worldPoints = generateCheckerboardPoints(boardSize, squareSize);
  20. % Calibrate the camera.
  21. imageSize = [size(I, 1), size(I, 2)];
  22. cameraParams = estimateCameraParameters(imagePoints, worldPoints, ...
  23. 'ImageSize', imageSize);
  24. % load('cameraParams.mat');
  25. %% 3.待重建物体分割
  26. label_images = cell(1, numImages);
  27. for i = 1 : numImages
  28. originalImage = imread(files{i});
  29. originalImage = rgb2hsv(originalImage);
  30. originalImage = originalImage(:, :, 2) < 0.35 & ...
  31. originalImage(:, :, 3) < 0.15;
  32. undistortedImage = undistortImage(originalImage, cameraParams);
  33. label_images{i} = undistortedImage;
  34. [row, col] = size(label_images{i});
  35. % figure(), imshow(label_images{i});
  36. % pause(1);
  37. end
  38. %% 4.产生一个长方体点阵框住物体
  39. step = 3;
  40. x1 = -50; x2 = 600;
  41. y1 = -500; y2 = -50;
  42. z1 = -50; z2 = 50;
  43. [x, y, z] = meshgrid(x1: step: x2, y1: step: y2, z1: step: z2);
  44. num_points = length(x(:));
  45. object = [x(:), y(:), z(:), ones(num_points, 1)];
  46. %% 5.计算点阵在原图中的投影
  47. flag = zeros(num_points, 1);
  48. K = cameraParams.IntrinsicMatrix;
  49. for j = 1 : numImages
  50. R = cameraParams.RotationMatrices(:,:,j);
  51. T = cameraParams.TranslationVectors(j,:);
  52. p_uv1 = object * [R;T] * K;
  53. s = p_uv1(:,3);
  54. p_uv = [p_uv1(:,1)./s, p_uv1(:,2)./s];
  55. % 索引像素时,先行(y)后列(x)
  56. p_row = round(p_uv(:,2));
  57. p_col = round(p_uv(:,1));
  58. err_points = length( find( p_row <=0 ...
  59. | p_row>row | p_col <=0 | p_col > col ) );
  60. ind = p_row + (p_col-1)*row;
  61. ind(find(ind > size(label_images{j}, 1) * size(label_images{j}, 2))) = 1;
  62. ind(find(ind < 1)) = 1;
  63. flag = flag | label_images{j}(ind) > 0;
  64. % 显示投影效果
  65. if 1
  66. figure;imshow(label_images{j});
  67. hold on;
  68. indices = find(flag);
  69. p_uv_remain = p_uv(indices(1:5:end),:);
  70. plot(p_uv_remain(:,1),p_uv_remain(:,2),'r.');
  71. hold off;
  72. end
  73. end
  74. %% 6.重投影效果展示
  75. object = object(flag,:);
  76. figure;
  77. hold on;
  78. [n,~] = size(object);
  79. plot3(object(:,1), object(:,2), -object(:,3),'y.');
  80. axis square;
  81. hold off;
  82. figure; pcshow([object(:,1), object(:,2), -object(:,3)]);
  83. xlabel('x');
  84. ylabel('y');
  85. zlabel('z');
  86. beep;
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/127779
推荐阅读
相关标签
  

闽ICP备14008679号