| 
									
										
										
										
											2015-01-14 05:33:47 +08:00
										 |  |  | function [visiblePoints] = cylinderSampleProjection(K, pose, imageSize, cylinders)
 | 
					
						
							| 
									
										
										
										
											2015-01-12 12:20:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-13 05:10:49 +08:00
										 |  |  | % Input:  | 
					
						
							|  |  |  | % Output: | 
					
						
							|  |  |  | %   visiblePoints:  data{k} 3D Point in overal point clouds with index k  | 
					
						
							|  |  |  | %                   Z{k}    2D measurements in overal point clouds with index k    | 
					
						
							|  |  |  | %                   index {i}{j} | 
					
						
							|  |  |  | %                   i: the cylinder index; | 
					
						
							|  |  |  | %                   j: the point index on the cylinder; | 
					
						
							|  |  |  | %                    | 
					
						
							|  |  |  | % @Description: Project sampled points on cylinder to camera frame | 
					
						
							|  |  |  | % @Authors: Zhaoyang Lv | 
					
						
							| 
									
										
										
										
											2015-01-12 12:20:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-13 05:10:49 +08:00
										 |  |  | import gtsam.* | 
					
						
							| 
									
										
										
										
											2015-01-12 12:20:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 08:42:55 +08:00
										 |  |  | camera = PinholeCameraCal3_S2(pose, K); | 
					
						
							| 
									
										
										
										
											2015-01-14 05:33:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-13 05:10:49 +08:00
										 |  |  | %% memory allocation | 
					
						
							|  |  |  | cylinderNum = length(cylinders); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %% check visiblity of points on each cylinder | 
					
						
							|  |  |  | pointCloudIndex = 0; | 
					
						
							| 
									
										
										
										
											2015-01-14 13:08:35 +08:00
										 |  |  | visiblePointIdx = 1; | 
					
						
							| 
									
										
										
										
											2015-01-13 05:10:49 +08:00
										 |  |  | for i = 1:cylinderNum | 
					
						
							| 
									
										
										
										
											2015-01-12 12:20:37 +08:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2015-01-13 05:10:49 +08:00
										 |  |  |     pointNum = length(cylinders{i}.Points); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     % to check point visibility         | 
					
						
							|  |  |  |     for j = 1:pointNum | 
					
						
							| 
									
										
										
										
											2015-01-12 12:20:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-13 05:10:49 +08:00
										 |  |  |         pointCloudIndex  = pointCloudIndex + 1; | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:06 +08:00
										 |  |  |                  | 
					
						
							| 
									
										
										
										
											2015-01-14 12:25:44 +08:00
										 |  |  |         % Cheirality Exception | 
					
						
							| 
									
										
										
										
											2015-01-13 05:10:49 +08:00
										 |  |  |         sampledPoint3 = cylinders{i}.Points{j}; | 
					
						
							| 
									
										
										
										
											2019-05-17 02:33:58 +08:00
										 |  |  |         sampledPoint3local = pose.transformTo(sampledPoint3);         | 
					
						
							| 
									
										
										
										
											2015-01-14 12:25:44 +08:00
										 |  |  |         if sampledPoint3local.z <= 0 | 
					
						
							|  |  |  |             continue;  | 
					
						
							| 
									
										
										
										
											2015-01-13 12:27:06 +08:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2015-01-13 05:10:49 +08:00
										 |  |  |         Z2d = camera.project(sampledPoint3); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         % ignore points not visible in the scene | 
					
						
							| 
									
										
										
										
											2015-01-14 12:25:44 +08:00
										 |  |  |         if Z2d.x < 0 || Z2d.x >= imageSize.x || Z2d.y < 0 || Z2d.y >= imageSize.y  | 
					
						
							| 
									
										
										
										
											2015-01-13 05:10:49 +08:00
										 |  |  |             continue;        | 
					
						
							|  |  |  |         end             | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         % 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:25:44 +08:00
										 |  |  |         visible = true; | 
					
						
							| 
									
										
										
										
											2015-01-13 05:10:49 +08:00
										 |  |  |         for k = 1:cylinderNum | 
					
						
							| 
									
										
										
										
											2015-01-12 12:20:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 12:25:44 +08:00
										 |  |  |             rayCameraToPoint = pose.translation().between(sampledPoint3).vector(); | 
					
						
							|  |  |  |             rayCameraToCylinder = pose.translation().between(cylinders{k}.centroid).vector(); | 
					
						
							|  |  |  |             rayCylinderToPoint = cylinders{k}.centroid.between(sampledPoint3).vector(); | 
					
						
							| 
									
										
										
										
											2015-01-13 05:10:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             % Condition 1: all points in front of the cylinders' | 
					
						
							|  |  |  |             % surfaces are visible | 
					
						
							|  |  |  |             if dot(rayCylinderToPoint, rayCameraToCylinder) < 0 | 
					
						
							| 
									
										
										
										
											2015-01-14 12:25:44 +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:25:44 +08:00
										 |  |  |                        continue; | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                         visible = false; | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     end | 
					
						
							| 
									
										
										
										
											2015-01-12 12:20:37 +08:00
										 |  |  |                 end | 
					
						
							|  |  |  |             end | 
					
						
							| 
									
										
										
										
											2015-01-14 12:25:44 +08:00
										 |  |  |              | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         if visible | 
					
						
							| 
									
										
										
										
											2015-01-14 13:08:35 +08:00
										 |  |  |             visiblePoints.data{visiblePointIdx} = sampledPoint3; | 
					
						
							|  |  |  |             visiblePoints.Z{visiblePointIdx} = Z2d; | 
					
						
							|  |  |  |             visiblePoints.cylinderIdx{visiblePointIdx} = i; | 
					
						
							|  |  |  |             visiblePoints.overallIdx{visiblePointIdx} = pointCloudIndex; | 
					
						
							|  |  |  |             visiblePointIdx = visiblePointIdx + 1; | 
					
						
							| 
									
										
										
										
											2015-01-12 12:20:37 +08:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2015-01-14 13:08:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-12 12:20:37 +08:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-01-14 12:25:44 +08:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2015-01-13 05:10:49 +08:00
										 |  |  | end | 
					
						
							| 
									
										
										
										
											2015-01-12 12:20:37 +08:00
										 |  |  |      | 
					
						
							|  |  |  | end |