{"id":230,"date":"2017-11-18T00:01:50","date_gmt":"2017-11-18T00:01:50","guid":{"rendered":"http:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/?page_id=230"},"modified":"2018-05-08T20:55:45","modified_gmt":"2018-05-08T20:55:45","slug":"perception","status":"publish","type":"page","link":"https:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/perception\/","title":{"rendered":"Detection"},"content":{"rendered":"<h2>Implementation Details<\/h2>\n<h3>Background Subtraction<\/h3>\n<p>The steps to achieve background subtraction with static LiDAR setup are listed below:<\/p>\n<ol>\n<li>Load the pre-recorded background point cloud which contains a static environment without moving objects.<\/li>\n<li>Within a callback function, initialize octree object.<\/li>\n<li>Add background points into octree.<\/li>\n<li>Switch octree buffer to receive new point cloud later.<\/li>\n<li>Add current frame points into octree.<\/li>\n<li>Execute comparing algorithm which extracts vector of points indices from octree voxels that did not exist in previous buffer.<\/li>\n<li>Add and format the resulting points; publish the result via certain ROS topic.<\/li>\n<\/ol>\n<p>One thing to note that I used a pre-recorded background point cloud as a reference. In the future, it should be dynamically generated by monitoring the real environment and taking consecutive frames of data.<\/p>\n<p>Octree is an efficient data structure to store point cloud. The reason why I use octree to store the information is that by manually adjusting octree\u2019s resolution, we can find similar-position points between background and current frame. As shown below, it achieves satisfying result even though LiDAR point cloud is effected by noises.<\/p>\n<h3>Euclidean Clustering &amp; Centroid Computation<\/h3>\n<p>The steps to implement Euclidean Clustering with LiDAR point cloud are described below:<\/p>\n<ol>\n<li>Load point cloud after background subtraction.<\/li>\n<li>Duplicate the point cloud and modify all points to the same height.<\/li>\n<li>Set Euclidean tolerance, minimum and maximum clustering size.<\/li>\n<li>Perform the Euclidean clustering operation (Exhaustively and recursively search<br \/>\nneighboring points within tolerance; save clusters fitting min\/max threshold).<\/li>\n<li>Iterate every founded cluster, compute the 2D centroid of all the points within that<br \/>\ncluster (since heights are fixed in step 2).<\/li>\n<li>Publish both clusters and centroids information to certain ROS topics.<\/li>\n<\/ol>\n<p>One trick I used to gain a better result in clustering points was ignoring their height<br \/>\ninformation. Since LiDAR beams diverge in certain angles, the further the object is, the<br \/>\nsparser points will be in z-axis. As such, distance between two beams on the same object will<br \/>\nbe inversely proportional to the distance from the LiDAR to the object. Since we only cared<br \/>\nabout object on the ground, their centroids could be estimated based on 2D plane without<br \/>\nconsidering height information.<\/p>\n<h3 class=\"p1\"><span class=\"s1\">2D Detection:<\/span><\/h3>\n<p class=\"p2\"><span class=\"s1\">We use Single Shot MultiBox Detector (SSD) to detect pedestrians. It runs 20 frames per second in average!<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-255\" src=\"http:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/wp-content\/uploads\/sites\/26\/2017\/11\/ILR41.png\" alt=\"\" width=\"648\" height=\"191\" \/><\/p>\n<p class=\"p2\"><span class=\"s1\">This is the architecture of the Single This is the Single Shot Multibox Detector. It has multi-scale feature maps which decrease in size progressively and allow predictions of detections at multiple scales. Each added feature layer can produce a fixed set of detection predictions using a set of convolutional filters.<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\">The following pictures are the results for the real-time detection.<\/span><\/p>\n<h3><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-256\" src=\"http:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/wp-content\/uploads\/sites\/26\/2017\/11\/ILR42.png\" alt=\"\" width=\"531\" height=\"283\" \/><\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-257\" src=\"http:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/wp-content\/uploads\/sites\/26\/2017\/11\/ILR43.png\" alt=\"\" width=\"528\" height=\"277\" \/><\/p>\n<h3 class=\"p4\"><span class=\"s1\">Camera-Lidar Calibration:<\/span><\/h3>\n<p class=\"p2\"><span class=\"s1\">I recored several bag files using the camera and velodyne with \/zed\/rgb\/raw_image topic and \/raw_points topic.<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\">Setup the Autoware Calibration toolkit which looks like this.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-258\" src=\"http:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/wp-content\/uploads\/sites\/26\/2017\/11\/ILR44.png\" alt=\"\" width=\"523\" height=\"367\" \/><\/p>\n<p class=\"p2\"><span class=\"s1\">Grab some frames from the toolkits and manually label the corresponding location of the point cloud given the images. However, the result is not impressive (See the following picture).<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\">The reason why the distortion is so bad is because I didn\u2019t grad enough frames. It requires 60 camera-velodyne frames in different angles, locations to reach better performance. Our calibration board is too heavy to move so that I decide to use other calibration tool kit to proceed the task.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-259\" src=\"http:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/wp-content\/uploads\/sites\/26\/2017\/11\/ILR45.png\" alt=\"\" width=\"526\" height=\"300\" \/><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Implementation Details Background Subtraction The steps to achieve background subtraction with static LiDAR setup are listed below: Load the pre-recorded background point cloud which contains a static environment without moving objects. Within a callback function, initialize octree object. Add background points into octree. Switch octree buffer to receive new point cloud later. Add current frame<br \/><a class=\"moretag\" href=\"https:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/perception\/\">+ Read More<\/a><\/p>\n","protected":false},"author":116,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-230","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/wp-json\/wp\/v2\/pages\/230","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/wp-json\/wp\/v2\/users\/116"}],"replies":[{"embeddable":true,"href":"https:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/wp-json\/wp\/v2\/comments?post=230"}],"version-history":[{"count":7,"href":"https:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/wp-json\/wp\/v2\/pages\/230\/revisions"}],"predecessor-version":[{"id":517,"href":"https:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/wp-json\/wp\/v2\/pages\/230\/revisions\/517"}],"wp:attachment":[{"href":"https:\/\/mrsdprojects.ri.cmu.edu\/2017teame\/wp-json\/wp\/v2\/media?parent=230"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}