| 
									
										
										
										
											2015-01-20 12:56:04 +08:00
										 |  |  | function [pts2dTracksStereo, initialEstimate] = points2DTrackStereo(K, cameraPoses, options, cylinders)
 | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  | % Assess how accurately we can reconstruct points from a particular monocular camera setup.  | 
					
						
							|  |  |  | % After creation of the factor graph for each track, linearize it around ground truth.  | 
					
						
							|  |  |  | % There is no optimization | 
					
						
							| 
									
										
										
										
											2015-01-23 00:24:43 +08:00
										 |  |  | % | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  | % @author: Zhaoyang Lv | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import gtsam.* | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %% create graph | 
					
						
							|  |  |  | graph = NonlinearFactorGraph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %% create the noise factors | 
					
						
							|  |  |  | poseNoiseSigmas = [0.001 0.001 0.001 0.1 0.1 0.1]'; | 
					
						
							|  |  |  | posePriorNoise  = noiseModel.Diagonal.Sigmas(poseNoiseSigmas); | 
					
						
							| 
									
										
										
										
											2015-01-21 13:14:37 +08:00
										 |  |  | stereoNoise = noiseModel.Isotropic.Sigma(3, 0.05); | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  | cameraPosesNum = length(cameraPoses); | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | %% add measurements and initial camera & points values | 
					
						
							|  |  |  | pointsNum = 0; | 
					
						
							|  |  |  | cylinderNum = length(cylinders); | 
					
						
							| 
									
										
										
										
											2015-01-15 14:19:21 +08:00
										 |  |  | points3d = cell(0); | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  | for i = 1:cylinderNum | 
					
						
							| 
									
										
										
										
											2015-01-15 14:19:21 +08:00
										 |  |  |     cylinderPointsNum = length(cylinders{i}.Points); | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  |     pointsNum = pointsNum + length(cylinders{i}.Points); | 
					
						
							| 
									
										
										
										
											2015-01-15 14:19:21 +08:00
										 |  |  |     for j = 1:cylinderPointsNum | 
					
						
							|  |  |  |         points3d{end+1}.data = cylinders{i}.Points{j}; | 
					
						
							|  |  |  |         points3d{end}.Z = cell(0); | 
					
						
							|  |  |  |         points3d{end}.cameraConstraint = cell(0); | 
					
						
							|  |  |  |         points3d{end}.visiblity = false; | 
					
						
							| 
									
										
										
										
											2015-01-21 13:14:37 +08:00
										 |  |  |         points3d{end}.cov = cell(cameraPosesNum); | 
					
						
							| 
									
										
										
										
											2015-01-15 14:19:21 +08:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-15 14:19:21 +08:00
										 |  |  | graph.add(PriorFactorPose3(symbol('x', 1), cameraPoses{1}, posePriorNoise)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 13:14:37 +08:00
										 |  |  | %% initialize graph and values | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  | initialEstimate = Values; | 
					
						
							| 
									
										
										
										
											2015-01-21 13:14:37 +08:00
										 |  |  | for i = 1:pointsNum | 
					
						
							|  |  |  |     point_j = points3d{i}.data.retract(0.05*randn(3,1)); | 
					
						
							|  |  |  |     initialEstimate.insert(symbol('p', i), point_j);     | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pts3d = cell(cameraPosesNum, 1); | 
					
						
							|  |  |  | cameraPosesCov = cell(cameraPosesNum, 1); | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  | for i = 1:cameraPosesNum  | 
					
						
							| 
									
										
										
										
											2015-01-20 12:56:04 +08:00
										 |  |  |     pts3d{i} = cylinderSampleProjectionStereo(K, cameraPoses{i}, options.camera.resolution, cylinders); | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2015-01-15 14:19:21 +08:00
										 |  |  |     if isempty(pts3d{i}.Z) | 
					
						
							|  |  |  |         continue; | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  |     end | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2015-01-14 13:08:35 +08:00
										 |  |  |     measurementNum = length(pts3d{i}.Z); | 
					
						
							|  |  |  |     for j = 1:measurementNum | 
					
						
							| 
									
										
										
										
											2015-01-15 14:19:21 +08:00
										 |  |  |         index = pts3d{i}.overallIdx{j}; | 
					
						
							|  |  |  |         points3d{index}.Z{end+1} = pts3d{i}.Z{j}; | 
					
						
							|  |  |  |         points3d{index}.cameraConstraint{end+1} = i; | 
					
						
							|  |  |  |         points3d{index}.visiblity = true; | 
					
						
							| 
									
										
										
										
											2015-01-20 12:56:04 +08:00
										 |  |  |    | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  |         graph.add(GenericStereoFactor3D(StereoPoint2(pts3d{i}.Z{j}.uL, pts3d{i}.Z{j}.uR, pts3d{i}.Z{j}.v), ... | 
					
						
							| 
									
										
										
										
											2015-01-20 12:56:04 +08:00
										 |  |  |             stereoNoise, symbol('x', i), symbol('p', index), K));     | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 13:14:37 +08:00
										 |  |  |     pose_i = cameraPoses{i}.retract(poseNoiseSigmas); | 
					
						
							|  |  |  |     initialEstimate.insert(symbol('x', i), pose_i); | 
					
						
							| 
									
										
										
										
											2015-01-15 14:19:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 13:14:37 +08:00
										 |  |  |     %% linearize the graph | 
					
						
							|  |  |  |     marginals = Marginals(graph, initialEstimate); | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 13:14:37 +08:00
										 |  |  |     for j = 1:pointsNum | 
					
						
							|  |  |  |         if points3d{j}.visiblity | 
					
						
							|  |  |  |             points3d{j}.cov{i} = marginals.marginalCovariance(symbol('p', j)); | 
					
						
							|  |  |  |         end        | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     cameraPosesCov{i} = marginals.marginalCovariance(symbol('x', i));     | 
					
						
							|  |  |  | end | 
					
						
							| 
									
										
										
										
											2015-01-15 14:19:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 13:14:37 +08:00
										 |  |  | %% Plot the result | 
					
						
							|  |  |  | plotFlyingResults(points3d, cameraPoses, cameraPosesCov, cylinders, options); | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | %% get all the 2d points track information | 
					
						
							| 
									
										
										
										
											2015-01-15 14:19:21 +08:00
										 |  |  | pts2dTracksStereo.pt3d = cell(0); | 
					
						
							|  |  |  | pts2dTracksStereo.Z = cell(0); | 
					
						
							|  |  |  | pts2dTracksStereo.cov = cell(0); | 
					
						
							|  |  |  | for i = 1:pointsNum | 
					
						
							|  |  |  |     if ~points3d{i}.visiblity | 
					
						
							| 
									
										
										
										
											2015-01-15 13:20:06 +08:00
										 |  |  |         continue; | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-01-15 14:19:21 +08:00
										 |  |  |      | 
					
						
							|  |  |  |     pts2dTracksStereo.pt3d{end+1} = points3d{i}.data; | 
					
						
							|  |  |  |     pts2dTracksStereo.Z{end+1} = points3d{i}.Z; | 
					
						
							| 
									
										
										
										
											2015-01-20 12:56:04 +08:00
										 |  |  |     pts2dTracksStereo.cov{end+1} = marginals.marginalCovariance(symbol('p', i));        | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 13:14:37 +08:00
										 |  |  | %  | 
					
						
							|  |  |  | % %% plot the result with covariance ellipses | 
					
						
							|  |  |  | % plotFlyingResults(pts2dTracksStereo.pt3d, pts2dTracksStereo.cov, cameraPoses, cameraPosesCov, cylinders, options); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:19:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:21 +08:00
										 |  |  | end |