{"id":26694942,"url":"https://github.com/csiro-robotics/raycloudtools","last_synced_at":"2025-03-26T19:01:36.603Z","repository":{"id":110049111,"uuid":"314434070","full_name":"csiro-robotics/raycloudtools","owner":"csiro-robotics","description":null,"archived":false,"fork":false,"pushed_at":"2025-02-14T00:23:27.000Z","size":9061,"stargazers_count":77,"open_issues_count":2,"forks_count":19,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-02-14T01:27:51.061Z","etag":null,"topics":["library","point-cloud","raycloud"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/csiro-robotics.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-11-20T03:15:48.000Z","updated_at":"2025-02-14T00:23:30.000Z","dependencies_parsed_at":"2023-04-13T23:03:19.466Z","dependency_job_id":"43e2d267-8c6c-4d30-a7d0-5f41b57b4fbf","html_url":"https://github.com/csiro-robotics/raycloudtools","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/csiro-robotics%2Fraycloudtools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csiro-robotics%2Fraycloudtools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csiro-robotics%2Fraycloudtools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/csiro-robotics%2Fraycloudtools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/csiro-robotics","download_url":"https://codeload.github.com/csiro-robotics/raycloudtools/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245718740,"owners_count":20661160,"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":["library","point-cloud","raycloud"],"created_at":"2025-03-26T19:01:09.615Z","updated_at":"2025-03-26T19:01:36.556Z","avatar_url":"https://github.com/csiro-robotics.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"## Ray Cloud Tools\nA set of command line tools for processing ray clouds, together with an associated C++ library.\n\n\nRay clouds are point clouds with the sensor origin stored per point (currently encoded in the 'normal' field of .ply files).\nRay clouds represent free space as well as surfaces. This allows processing that cannot be done on point cloud data alone. \n\nThis is an open-source research library, a place to release new techniques in ray cloud analysis and manipulation. So if you would like to contribute with a new or improved method, do suggest it in our discussions page: https://github.com/csiro-robotics/raycloudtools/discussions.\n\n## Install using a Pre-built Container\n\n### Docker (Linux, MacOS, Windows)\n#### Pull the Latest Image\nTo download the latest image from GitHub Packages, use the following command:\n```bash\ndocker pull ghcr.io/csiro-robotics/raycloudtools:latest\n```\n\n#### Run an Interactive Container\nTo run the container interactively and bind your home directory to a directory inside the container for accessing host files:\n\n#### On Linux/MacOS\n```bash\ndocker run -it --name raycloudtools -v /home/yourusername:/workspace ghcr.io/csiro-robotics/raycloudtools:latest /bin/bash\n```\n\n#### On Windows\n```bash\ndocker run -it --name raycloudtools -v C:/Users/YourUsername:/workspace ghcr.io/csiro-robotics/raycloudtools:latest /bin/bash\n```\nReplace `/home/yourusername` or `C:/Users/YourUsername` with the path to your home directory.\n\n#### Reusing Container\nTo restart and attach to the container in the future:\n```bash\ndocker start -ai raycloudtools\n```\n\n### Apptainer (Linux/HPC)\n```console\n# Login to GitHub Container Registry (required once)\nexport CR_PAT=YOUR_GITHUB_TOKEN\napptainer registry login -u YOUR_GITHUB_USERNAME -p $CR_PAT oras://ghcr.io\n\n# Pull and convert the container\napptainer pull docker://ghcr.io/csiro-robotics/raycloudtools:latest\n\n# Run an interactive container (binds host home directory by default)\napptainer shell raycloudtools_latest.sif\n```\n\nTo create a GitHub token:\n1. Go to GitHub Settings → Developer Settings → Personal Access Tokens → Tokens (classic)\n2. Generate new token with `read:packages` scope\n3. Copy the token and use it in the login command above\n\n## Build from Source with Docker\n```console\n# Clone the repository\ngit clone https://github.com/csiro-robotics/raycloudtools.git\ncd raycloudtools\n\n# Build the image\ndocker build -f docker/Dockerfile -t raycloudtools:local .\n```\n\n## Build from Source (tested on Linux-based systems):\n```console\nsudo apt-get install libeigen3-dev\ngit clone https://github.com/ethz-asl/libnabo.git\ncd libnabo\ngit checkout tags/1.0.7\nmkdir build\ncd build\ncmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo\nmake\nsudo make install\ncd ../..\ngit clone https://github.com/csiro-robotics/raycloudtools.git\ncd raycloudtools\nmkdir build\ncd build\ncmake ..\nmake\n```\n\nTo run the rayXXXX tools from anywhere either sudo make install, or place in your ~/.bashrc:\n```console\n  export PATH=$PATH:'source code path'/raycloudtools/build/bin\n```\n\nIf not there already, add to your ~/.bashrc:\n'''console\nexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \n'''\n\n## File format:\nRaycloud files are loaded and saved in binary .ply format, the header section is text and follows this format:\n```console\nply\nformat binary_little_endian 1.0\ncomment generated by raycloudtools library\nelement vertex 0000000000\u003cnumber of points\u003e\nproperty \u003cfloat/double\u003e x\nproperty \u003cfloat/double\u003e y\nproperty \u003cfloat/double\u003e z\nproperty \u003cfloat/double\u003e time\nproperty \u003cfloat/double\u003e nx\nproperty \u003cfloat/double\u003e ny\nproperty \u003cfloat/double\u003e nz\nproperty uchar red\nproperty uchar green\nproperty uchar blue\nproperty uchar alpha\nend_header\n```\nfollowed by the binary data. By default it uses floats for x,y,z,nx,ny,nz and doubles for time. nx,ny,nz is the vector from the end point x,y,z to the sensor's location at the time that the point was observed. It is not a surface normal, but the ray representing free space from point to source.\n\nImported .ply point cloud files have a similar format, but without the nx,ny,nz fields, and optionally an intensity field instead of the red,green,blue,alpha:\n```console\nply\nformat binary_little_endian 1.0\ncomment Any comment here\nelement vertex 0000000000\u003cnumber of points\u003e\nproperty \u003cfloat/double\u003e x\nproperty \u003cfloat/double\u003e y\nproperty \u003cfloat/double\u003e z\nproperty \u003cfloat/double\u003e time\nproperty \u003cfloat/double\u003e intensity\nend_header\n``` \nThe range of this intensity mapped onto the raycloud's 0-255 alpha value using rayimport's max_intensity optional parameter.\n\nThe imported .laz point cloud format is the 3D point, time and intensity fields. Plus the optional colour field. \n\n## Visual Guide:\n\nThis gives an example of how the command line tools could be sequenced to analyse (top down) and generate (bottom up) ray clouds. \n\n\u003cp align=\"center\"\u003e\u003cimg img width=\"480\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/raycloudtools_cheatsheet.png?at=refs%2Fheads%2Fmaster\"/\u003e\u003c/p\u003e\n\n## Individual Examples:\n\n**rayimport forest.laz forest_traj.txt** \u0026nbsp;\u0026nbsp;\u0026nbsp; Import point cloud and trajectory to a single raycloud file forest.ply. forest_traj.txt is space separated 'time x y z' per line. \n\n**raycreate room 1** \u0026nbsp;\u0026nbsp;\u0026nbsp; Generate a single room with a window and door, using random seed 1.\n\u003cp align=\"center\"\u003e\n\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room1.png?at=refs%2Fheads%2Fmaster\"/\u003e\n  \u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room3.png?at=refs%2Fheads%2Fmaster\"/\u003e\n  \u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room2.png?at=refs%2Fheads%2Fmaster\"/\u003e\n\u003c/p\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp; You can visualise the rays in meshlab with Render | Show Vertex Normals. The ray lengths need to be scaled: Tools | Options | NormalLength roughly 0.025 (smaller for larger clouds)\n\n**raydecimate room.ply 10 cm** \u0026nbsp;\u0026nbsp;\u0026nbsp; Spatially decimate cloud to one point every cubic 10 cm.\n\n\u003cp align=\"center\"\u003e\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room_decimated.png?at=refs%2Fheads%2Fmaster\"/\u003e\u003c/p\u003e\n\n**raytranslate room.ply 3 0 0** \u0026nbsp;\u0026nbsp;\u0026nbsp; Translate the ray cloud 3 metres along the x axis.\n\n\u003cp align=\"center\"\u003e\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room_translate.png?at=refs%2Fheads%2Fmaster\"/\u003e\u003c/p\u003e\n\n**rayrotate room.ply 0 0 30** \u0026nbsp;\u0026nbsp;\u0026nbsp; Rotate the ray cloud 30 degrees around the z axis.\n\n\u003cp align=\"center\"\u003e\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room_rotate.png?at=refs%2Fheads%2Fmaster\"/\u003e\u003c/p\u003e\n\n**raydenoise room.ply 10 cm** \u0026nbsp;\u0026nbsp;\u0026nbsp; Remove rays with isolated end points more than 10 cm from any other, not including unbounded rays.\n\n\u003cp align=\"center\"\u003e\n\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room_denoise1.png?at=refs%2Fheads%2Fmaster\"/\u003e\n\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room_denoise2.png?at=refs%2Fheads%2Fmaster\"/\u003e\n\n**raysmooth room.ply** \u0026nbsp;\u0026nbsp;\u0026nbsp; Move ray end points onto the nearest surface, to smooth the resulting cloud.\n\n\u003cp align=\"center\"\u003e\n\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room_smooth1.png?at=refs%2Fheads%2Fmaster\"/\u003e\n\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room_smooth2.png?at=refs%2Fheads%2Fmaster\"/\u003e\n\u003c/p\u003e\n\n**rayrender room.ply top density_rgb** \u0026nbsp;\u0026nbsp;\u0026nbsp; Render the cloud from the top, as a surface area density.\n\n\u003cp align=\"center\"\u003e\n\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/rayrender_room_top_density_rgb.png?at=refs%2Fheads%2Fmaster\"/\u003e\n\u003c/p\u003e\n\n**raytransients min room.ply 2 rays** \u0026nbsp;\u0026nbsp;\u0026nbsp; Segment out moving or moved objects during the scan, when matter has been re-observed as missing by 2 or more rays. \n\n\u0026nbsp;\u0026nbsp;\u0026nbsp; Leaving the ***minimum*** of geometry when transient.\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp; In this raycloud the table and cupboard appear only after the empty room has been scanned for several seconds, so we can isolate these transient objects.\n\n\u003cp align=\"center\"\u003e\n\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room_transients1.png?at=refs%2Fheads%2Fmaster\"/\u003e\n\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room_transients2.png?at=refs%2Fheads%2Fmaster\"/\u003e\n\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room_transients3.png?at=refs%2Fheads%2Fmaster\"/\u003e\n\u003c/p\u003e\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp; Left: original cloud. Middle: the fixed (untransient) raycloud. Right: the remaining transient rays are also saved.\n\n**raycombine room.ply room2.ply** \u0026nbsp;\u0026nbsp;\u0026nbsp; Combine room and its transformed version together, keeping ***all*** rays.\n\n\u003cp align=\"center\"\u003e\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room_combined_all.png?at=refs%2Fheads%2Fmaster\"/\u003e\u003c/p\u003e\n\n**raycombine min room.ply room2.ply 1 rays** \u0026nbsp;\u0026nbsp;\u0026nbsp; Combine the two ray clouds keeping only the ***minimum*** of geometry where there is a difference. \n\n\u0026nbsp;\u0026nbsp;\u0026nbsp; This is a form of union of the two volumes. \n\n\u003cp align=\"center\"\u003e\u003cimg img width=\"320\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/room_combined_min.png?at=refs%2Fheads%2Fmaster\"/\u003e\u003c/p\u003e\n\n**rayalign room.ply room2.ply** \u0026nbsp;\u0026nbsp;\u0026nbsp; Aligns room onto room2, allowing for a small about of non-rigidity \n\n**rayextract terrain cloud.ply** \u0026nbsp;\u0026nbsp;\u0026nbsp; extracts a ground mesh based on a conical height condition. \n\n\u003cp align=\"center\"\u003e\u003cimg img width=\"640\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/rayextract_terrain.png?at=refs%2Fheads%2Fmaster\"/\u003e\u003c/p\u003e\n\n**rayextract trees forest.ply forest_mesh.ply** \u0026nbsp;\u0026nbsp;\u0026nbsp; extracts tree structures to text file, and segments forest. \n\n\u003cp align=\"center\"\u003e\u003cimg img width=\"640\" src=\"https://raw.githubusercontent.com/csiro-robotics/raycloudtools/main/pics/rayextract_trees.png?at=refs%2Fheads%2Fmaster\"/\u003e\u003c/p\u003e\n\n\n*Optional build dependencies:*\n\nFor rayconvert to work from .laz files:\n* git clone https://github.com/LASzip/LASzip.git, then git checkout tags/2.0.1, then mkdir build, cd build, cmake .., make, sudo make install. \n* git clone https://github.com/libLAS/libLAS.git, then mkdir build, cd build, cmake .. -DWITH_LASZIP=ON, make, sudo make install (you'll need GEOTIFF to be off in libLAS, and to have installed boost)\n* in raycloudtools/build: cmake .. -DWITH_LAS=ON  (or ccmake .. to turn on/off WITH_LAS)\n* note that you may need to add the liblas path into LD_LIBRARY path, normally this can be done with the following line in your ~/.bashrc: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib\n\nFor raywrap:\n\n* git clone http://github.com/qhull/qhull.git, git checkout tags/v7.3.2\n* In qhull: mkdir build, cd build, cmake .. -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true, make, sudo make install. \n* in raycloudtools/build: cmake .. -DWITH_QHULL=ON (or ccmake .. to turn on/off WITH_QHULL)\n\nTo render clouds to geotif (.tif) images:\n\n* git clone https://github.com/OSGeo/libgeotiff.git\n* follow the build instructions in its README.md, note that the \"DCMAKE_C_FLAGS\" parameter needs a preceeding \"-\"\n* copy a FindGeoTIFF.cmake file to your cmake folder, such as from here: https://github.com/ufz/geotiff \n* in raycloudtools/build: cmake .. -DWITH_TIFF=ON (or ccmake .. to turn on/off WITH_TIFF)\n\n## Unit Tests\n\nUnit tests must be enabled at build time before running. To build with unit tests, the CMake variable `RAYCLOUD_BUILD_TESTS` must be `ON`. This can be done in the initial project configuration by running the following command from the `build` directory: `cmake  -DRAYCLOUD_BUILD_TESTS=ON ..`\n\nUnit tests may then be run directly or using `CTest`.\n\n### Running using CTest\n\nTo run using CTest:\n\n* Change into the `build` directory\n* Run `ctest .`\n\nOn some platforms it may be necessary to specify the build configuration to test. For example, the `Release` build may be tested using the modified command `ctest . -C Release`.\n\n### Directly invoking the tests\n\nWhen directly invoking the unit tests, is important that the tests are run from the directory to which the raycloud tools executables are built. To invoke the tests directly:\n\n* Change into the `build` directory\n* Change into the `bin/` directory\n* Run `./raytest`\n\n## Development Container Setup (.devcontainer)\n\nThis project provides a `.devcontainer` directory for consistent development environments. Using the devcontainer is optional, but recommended for a streamlined setup. Here's how to get started:\n\n1. **Install Docker:** You'll need Docker Desktop (or a similar Docker engine) installed on your machine.\n\n2. **Open in VS Code:**\n    * Open the project in VS Code.\n    * VS Code should automatically detect the `.devcontainer` folder and prompt you to \"Reopen in Container\". Click it.\n    * If you're not prompted, open the command palette (Ctrl+Shift+P or Cmd+Shift+P) and type \"Remote-Containers: Reopen in Container\".\n\nThat's it! VS Code will handle building and running the development container for you.  If you choose not to use the devcontainer, you will need to ensure your local environment matches the project's dependencies and requirements.\n\n## Acknowledgements\nThis research was supported by funding from CSIRO's Data61, Land and Water, Wine Australia, and the Department of Agriculture's Rural R\u0026D for Profit program. The authors gratefully acknowledge the support of these groups, which has helped in making this library possible. \n\n\nThe paper describing this software is available here: https://ieeexplore.ieee.org/abstract/document/9444433\n\nCitations:  \n```\nLowe, Thomas, and Kazys Stepanas. \"RayCloudTools: A Concise Interface for Analysis and Manipulation of Ray Clouds.\" IEEE Access (2021).\nLowe, T, Moghadam, P, Edwards, E, Williams, J. Canopy density estimation in perennial horticulture crops using 3D spinning lidar SLAM. J Field Robotics. 2021; 1– 21. https://doi.org/10.1002/rob.22006\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsiro-robotics%2Fraycloudtools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcsiro-robotics%2Fraycloudtools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcsiro-robotics%2Fraycloudtools/lists"}