| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  | function [visiblePoints] = cylinderSampleProjectionStereo(K, pose, imageSize, cylinders)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import gtsam.* | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %% memory allocation | 
					
						
							|  |  |  | cylinderNum = length(cylinders); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-15 13:20:06 +08:00
										 |  |  | visiblePoints.data = cell(1); | 
					
						
							|  |  |  | visiblePoints.Z = cell(1); | 
					
						
							|  |  |  | visiblePoints.cylinderIdx = cell(1); | 
					
						
							|  |  |  | visiblePoints.overallIdx = cell(1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  | %% check visiblity of points on each cylinder | 
					
						
							|  |  |  | pointCloudIndex = 0; | 
					
						
							| 
									
										
										
										
											2015-01-14 13:08:35 +08:00
										 |  |  | visiblePointIdx = 1; | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  | for i = 1:cylinderNum | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     pointNum = length(cylinders{i}.Points); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     % to check point visibility         | 
					
						
							|  |  |  |     for j = 1:pointNum | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         pointCloudIndex  = pointCloudIndex + 1; | 
					
						
							|  |  |  |                  | 
					
						
							|  |  |  |         % For Cheirality Exception | 
					
						
							|  |  |  |         sampledPoint3 = cylinders{i}.Points{j}; | 
					
						
							| 
									
										
										
										
											2019-05-17 02:33:58 +08:00
										 |  |  |         sampledPoint3local = pose.transformTo(sampledPoint3); | 
					
						
							| 
									
										
										
										
											2020-08-18 02:37:12 +08:00
										 |  |  |         if sampledPoint3local(3) < 0 | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  |             continue;  | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         % measurements  | 
					
						
							| 
									
										
										
										
											2020-08-18 02:37:12 +08:00
										 |  |  |         Z.du = K.fx() * K.baseline() / sampledPoint3local(3);   | 
					
						
							|  |  |  |         Z.uL = K.fx() * sampledPoint3local(1) / sampledPoint3local(3) + K.px(); | 
					
						
							| 
									
										
										
										
											2015-01-14 12:36:19 +08:00
										 |  |  |         Z.uR = Z.uL + Z.du; | 
					
						
							| 
									
										
										
										
											2020-08-18 02:37:12 +08:00
										 |  |  |         Z.v = K.fy() / sampledPoint3local(3) + K.py(); | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         % ignore points not visible in the scene | 
					
						
							| 
									
										
										
										
											2020-08-18 02:37:12 +08:00
										 |  |  |         if Z.uL < 0 || Z.uL >= imageSize(1) || ... | 
					
						
							|  |  |  |                 Z.uR < 0 || Z.uR >= imageSize(1) || ... | 
					
						
							|  |  |  |                 Z.v < 0 || Z.v >= imageSize(2)  | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  |             continue;        | 
					
						
							|  |  |  |         end             | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 04:35:28 +08:00
										 |  |  |         % too small disparity may call indeterminant system exception | 
					
						
							|  |  |  |         if Z.du < 0.6 | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  |         % ignore points occluded | 
					
						
							|  |  |  |         % use a simple math hack to check occlusion: | 
					
						
							|  |  |  |         %   1. All points in front of cylinders' surfaces are visible | 
					
						
							|  |  |  |         %   2. For points behind the cylinders' surfaces, the cylinder | 
					
						
							| 
									
										
										
										
											2015-01-14 12:36:19 +08:00
										 |  |  |         visible = true; | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  |         for k = 1:cylinderNum | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-18 02:37:12 +08:00
										 |  |  |             rayCameraToPoint = sampledPoint3 - pose.translation(); | 
					
						
							|  |  |  |             rayCameraToCylinder = cylinders{k}.centroid - pose.translation(); | 
					
						
							|  |  |  |             rayCylinderToPoint = sampledPoint3 - cylinders{k}.centroid; | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             % Condition 1: all points in front of the cylinders' | 
					
						
							|  |  |  |             % surfaces are visible | 
					
						
							|  |  |  |             if dot(rayCylinderToPoint, rayCameraToCylinder) < 0 | 
					
						
							| 
									
										
										
										
											2015-01-14 12:36:19 +08:00
										 |  |  |                continue; | 
					
						
							|  |  |  |             else  | 
					
						
							|  |  |  |                 projectedRay = dot(rayCameraToCylinder, rayCameraToPoint) / norm(rayCameraToCylinder); | 
					
						
							|  |  |  |                 if projectedRay > 0 | 
					
						
							|  |  |  |                     %rayCylinderToProjected = rayCameraToCylinder - norm(projectedRay) / norm(rayCameraToPoint) * rayCameraToPoint; | 
					
						
							| 
									
										
										
										
											2015-01-14 13:08:35 +08:00
										 |  |  |                     if rayCylinderToPoint(1) > cylinders{k}.radius && ... | 
					
						
							|  |  |  |                             rayCylinderToPoint(2) > cylinders{k}.radius | 
					
						
							| 
									
										
										
										
											2015-01-14 12:36:19 +08:00
										 |  |  |                        continue; | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                         visible = false; | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     end | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  |                 end | 
					
						
							|  |  |  |             end | 
					
						
							| 
									
										
										
										
											2015-01-14 12:36:19 +08:00
										 |  |  |              | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2015-01-14 12:36:19 +08:00
										 |  |  |          | 
					
						
							|  |  |  |         if visible | 
					
						
							| 
									
										
										
										
											2015-01-14 13:08:35 +08:00
										 |  |  |             visiblePoints.data{visiblePointIdx} = sampledPoint3; | 
					
						
							|  |  |  |             visiblePoints.Z{visiblePointIdx} = Z; | 
					
						
							|  |  |  |             visiblePoints.cylinderIdx{visiblePointIdx} = i; | 
					
						
							|  |  |  |             visiblePoints.overallIdx{visiblePointIdx} = pointCloudIndex; | 
					
						
							|  |  |  |             visiblePointIdx = visiblePointIdx + 1; | 
					
						
							| 
									
										
										
										
											2015-01-14 12:36:19 +08:00
										 |  |  |         end | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2015-01-14 10:21:48 +08:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | end |