{"id":19855166,"url":"https://github.com/leggedrobotics/tree_detection","last_synced_at":"2025-05-02T01:30:43.473Z","repository":{"id":43392270,"uuid":"390706039","full_name":"leggedrobotics/tree_detection","owner":"leggedrobotics","description":"This package implements a simple tree detector from point cloud data. It makes no assumptions about the ground plane and can handle arbitrary terrains.","archived":false,"fork":false,"pushed_at":"2022-12-05T10:54:49.000Z","size":1182,"stargazers_count":77,"open_issues_count":4,"forks_count":16,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-06T20:46:29.334Z","etag":null,"topics":["cpp","detection","point-cloud","ros","tree","tree-detection"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leggedrobotics.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-29T11:47:19.000Z","updated_at":"2025-03-30T18:08:19.000Z","dependencies_parsed_at":"2023-01-24T04:32:00.097Z","dependency_job_id":null,"html_url":"https://github.com/leggedrobotics/tree_detection","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Ftree_detection","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Ftree_detection/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Ftree_detection/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Ftree_detection/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leggedrobotics","download_url":"https://codeload.github.com/leggedrobotics/tree_detection/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251969270,"owners_count":21673183,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","detection","point-cloud","ros","tree","tree-detection"],"created_at":"2024-11-12T14:11:55.013Z","updated_at":"2025-05-02T01:30:40.801Z","avatar_url":"https://github.com/leggedrobotics.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tree_detection\n\n## Overview\n\nThis package provides tree detection on pointcloud data. In particular, it is designed for detecting tree trunks which could later be used for tree grabbing and harvesting. It does not provide the full tree segmentation with the crown. The package was developed in the scope of [1] (see below).\n\nThe functionality was developed for an autonomous harvester where the goal is to detect trees in a local map. Nonetheless, it can also be used on large maps to compute tree coordinates or get an estimate of tree density.\n\nReleased under [BSD 3-Clause license](LICENSE).\n\n**Author:** Edo Jelavic\n\n**Maintainer:** Edo Jelavic, [jelavice@ethz.ch](jelavice@ethz.ch)\n\nExamples of tree detection on point clouds:\n\n| forest 2 (ground removed)| forest 3 | forest 4 |\n|:--------:|------------------|--------------|\n|[![forest2](doc/forest2.jpg)](doc/forest2.jog)|[![forest3](doc/forest3.jpg)](doc/forest3.jpg)|[![forest4](doc/forest4.jpg)](doc/forest4.jpg)|\n\n## Publications\nThe code for tree detection has been developed as a part of research on autonomous precision harvesting. If you are using this tree detector in academic context, please consider adding the following citation to your publication:\n\n[1] Jelavic, E., Jud, D., Egli, P. and Hutter, M., 2021. Towards Autonomous Robotic Precision Harvesting: Mapping, Localization, Planning and Control for a Legged Tree Harvester.\n \n    @article{jelavic2021towards,\n        title={Towards Autonomous Robotic Precision Harvesting: Mapping, Localization, Planning and Control for a Legged Tree Harvester},\n        author={Jelavic, Edo and Jud, Dominic and Egli, Pascal and Hutter, Marco},\n        journal={Field Robotics},\n        year={2021},\n        publisher={Wiley}\n    }\n   \n## Packages in this repo\nThis repository consists of following packages:\n\n* ***point_cloud_preprocessig*** is a package used to preprocess the point cloud before removing the ground plane\n* ***ground_plane_removal*** is a lightweight package for ground plane removal. \n* ***tree_detection*** implements the core algorithm for tree detection. \n* ***tree_detection_ros*** adds visualization and I/O handling for easier usage. This package is tightly integrated with ROS.\n\n\n## Algorithm description\n\nThe algorithm first attempts to remove the gound plane. This can be done using two strategies, either a simple box filter (for which the user needs to provide the cropping region) or using an elevation map. In case the elevation map strategy is used, the algorithm first computes the elevation map and then uses it to remove the ground plane. The elevaiton map computation is implemented in a different package (see the link [here](https://github.com/ANYbotics/grid_map/tree/master/grid_map_pcl)) and a more detailed description can be found in [1]. Before proceeding with the pointcloud processing the median filter is applied to the elevation map.\n\nOnce the ground plane is removed, the algorithm proceeds with Euclidean cluster extraction and performs some checks to make sure that the extracted clusters aree indeed trees. The more detailed description can be found in [1].\n\n## Installation\n\nClone the following dependencies:\n```bash\n# in your source folder `src`\ngit clone https://github.com/ANYbotics/grid_map.git\n```\nInstalling the grid map from apt might not work (you'll get compiler errors). Recommended way is to build the grid map from source. In case you built the grid map from source, but you're still getting errors, most likely the Cmake is finding the system install version of the grid map. Try cleaning your workspace and rebuilding `grid_map_pcl` from source first, as described [here](https://github.com/leggedrobotics/tree_detection/issues/7).\n\nInstall the ROS and library dependencies with:\n```bash\nsudo apt install -y ros-noetic-pcl-ros ros-noetic-pcl-conversions ros-noetic-jsk-recognition-msgs ros-noetic-tf2-geometry-msgs \n# OR, use rosdep in your source folder `src` \nsudo rosdep install -yr --from-paths .\n```\nIn case you want to use the detection boxes for visualization you will have to install the [jsk_rviz_plugins](http://wiki.ros.org/jsk_rviz_plugins).\n```bash\nsudo apt install ros-noetic-jsk-visualization\n```\nRecommended to build in release mode for performance (`catkin config -DCMAKE_BUILD_TYPE=Release`)\n\nBuild with:  \n```bash\ncatkin build tree_detection_ros\n```\nIn case you want to visualize the elevation map created by the ground plane remover, you should compile the grid_map_rviz_plugin as well:\n```bash\ncatkin build grid_map_rviz_plugin\n```\n\n\n## Usage \u0026 Examples\n\nThe example datasets can be downloaded [here](https://drive.google.com/drive/folders/1m_sRtMN5n6-ShQvnbCfedKIVpoupao5u?usp=sharing). The folder contains five forest patches.  One dataset has almost no clutter (forest3.pcd) and two have a lot of branch clutter (forest1.pcd and forest2.pcd). \n\nThis package can also work with forests on inclined surfaces and we provide two examples (forest4.pcd and forest5.pcd). The point clouds forest4.pcd and forest5.pcd were taken from the [The Montmorency dataset](https://norlab.ulaval.ca/research/montmorencydataset/) and downsampled. Note that for these datasets, we recommend to use a slightly different tuning. See `tree_detection_dataset_4_and_5.yaml`.\n\nModify the `pcd_filepath` inside the `tree_detection.launch` to point the location where the point clouds `.pcd` files are stored.  \nIf you want to use a different configuraiton file, you will have to modify the `config_filepath` as well. The ground plane removal strategy can be selected by setting the value of `ground_removal_strategy` parameter.\n\nRun with:\n```bash\nroslaunch tree_detection_ros tree_detection.launch\n```\nThe node publishes the input pointcloud, the pointcloud with the ground removed and the elevation map used to remove the ground plane. The detected trees will be marked with green cylinders and bounding boxes. The visualization should appar in the Rviz window.\n\nNote that the computation can last for up to 7-9 minutes for larger datasets (e.g. forest4.pcd and forest5.pcd). This can be shortened with different tuning, downsampling or voxelizing the point clouds.\n\nIf the choice is made to use the point cloud preprocessing package, special care needs to be taken that the voxel grid leaf size is chosen big enough. (Otherwise, there is an integer overflow in the pcl library and a warning is popping up in the terminal.) In addition, if the ground plane is removed using the elevation map approach, it is important, that the crop box of the preprocessing is not removing partially the point cloud representing the ground plane, else the elevation map will not correctly be generated. This could result to the fact that trees are not detected in the point cloud.\n\nIn general, the preprocessing should only be applied to point clouds, which either have points far away from the origin and/or which are dense. Both phemomena decrease the processing speed of the tree detection significally! The first phenomenum can be handled using the crop box in the preprocessing package. The second one can be tackled using the voxel grid filter in the same package.\n\n\n## Parameters\n\n* `ground_plane_removal/cropbox` - Limits (XYZ) for the ground plane removal. The points contained within the box specified by the user will be kept and the rest will be removed. The tree detection will proceed on the remaining points.\n* `ground_plane_removal/elevation_map` - Parameters for elevation map extraction from the pointcloud are described [here](https://github.com/ANYbotics/grid_map/tree/master/grid_map_pcl). We add a couple of new parameters which are listed below.\n* `ground_plane_removal/min_height_above_ground` - minimal height above the extracted elevation map to keep the points. Any points below this threshold will be discarded. Note that this number can also be negative.\n* `ground_plane_removal/max_height_above_ground` - maximal height above the elevation map to keep the points. Any points above this threshold will be discarded.\n* `ground_plane_removal/is_use_median_filter` - whether to apply the median filter on the elevation map.\n* `ground_plane_removal/median_filtering_radius` - median filtering radius for the elevation map. For each cell, the filter will take the data from the neighbouring cells withing specified radius and apply the median filter. The number of neighbouring points depends on the cell size and this parameter.\n* `ground_plane_removal/median_filter_points_downsample_factor` - If one wishes to have sparser coverage, you can apply downsampling. The algorithm will calculate all the points within the specified radius and divide their number by this factor. E.g., (if there are 50 neighbouring points within the radius and the downsample factor is set to 5, 10 points will be used for median filtering).\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleggedrobotics%2Ftree_detection","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleggedrobotics%2Ftree_detection","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleggedrobotics%2Ftree_detection/lists"}