Usage of pcl::CropHull - point-cloud-library

Hello I am looking for a way to find out points/indices of point cloud which lie within a set of pre-defined polygon points/indices.
My Input would be either of the following.
Set of indices of the cloud forming a 2D polygon. Eg : 21480, 4491, 20399, 19034, 21322, 5240, 5870, 21480
Set of coordinates(x,y,z) which correspond to the above indices in the cloud.
enter image description here

May I politelly suggest you the documentation pcl::CropHull
In your case. the methods:
setHullCloud (PointCloudPtr points)
setCropOutside (bool crop_outside)
and then
filter (PointCloud &output)
should do the job.
If this did not answer your problem please be more specific to which problems you are exactly facing when using pcl::CropHull (with code if possible)

Related

How to implement KdTree using PCLPointCloud2 used in loadOBJfile in point cloud library?

Okay, so I have one OBJ file which I read into PCLpointcloud2. Now I want to feed it into a K-dTree. Which is not taking PCLPointCloud2 as input. I want to query any general point if it lies on the surface of my OBJ file.
I am finding it hard to understand their documentation. So how can it be done?
Plus, kindly point me to a good reference easily interpretable. And what is "PointT" BTW? Is it custom build type defined by us? please elaborate.
Look at the code in the provided tool pcl_mesh_sampling (in the PCL code directory under tools/mesh_sampling.cpp). It is relatively simple. It loads a model from PLY or OBJ then for each triangle it samples random points from the triangle. The final point cloud then undergoes a voxel-grid sample to make the points relatively uniform. Alternatively, you can just run the pcl_mesh_sampling program on your obj file to get an output PCD which you can then visualise with pcl_viewer before loading the PCD file into your own code.
Once you have the final point cloud, you can build and use a KD-Tree as per http://pointclouds.org/documentation/tutorials/kdtree_search.php
PointT is the template argument. The point cloud library can handle a variety of point types, from simple PointXYZ (having just x,y,z) to more complicated points like PointXYZRGBNormal (having x,y,z,normal_x,normal_y,normal_z, curvature, r, g, and b channels). Each algorithm is templated on the point type that you want to use. It would probably be easier if you used PointXYZ with your OBJ file, so use pcl::PointXYZ for all your template arguments. For more on templates see http://www.tutorialspoint.com/cplusplus/cpp_templates.htm and http://pointclouds.org/documentation/tutorials/adding_custom_ptype.php.
Update (reply to latest comment)
Added here because this reply is too long for a comment.
I think I see what you are getting at. So when you sample points from the point cloud & build a KD-tree of the object surface, and for each point you keep track which faces are nearby that point (probably all the faces adjacent to the face from which the point was sampled should be sufficient? Just one face is definitely insufficient). Then when the query point is given, you find the nearest point in the KD-tree and check whether the query point is on the "outside" or inside of the full list of nearby faces associated with that point in the KD-tree. If it's on the "inside" of all of them perhaps it is an interior point. But I cannot guarantee that this is true. That is my thinking on that question at the moment. But I do wonder if you want a mesh-based approach really. By the way, if you break your mesh up into convex parts then you can have nice guarantees when processing each convex part.

Create graph of distinct routes

Problem I have a binary image with traversable and blocked cells. On this map points of interest (POIs) are set. My goal is to create a graph from these POIs respecting obstacles (see images) which represents all possible and truly distinct paths. Two paths are truly distinct if they can not be joined into one path. E.g. if the outside of the building in picture 1 was accessible a path around the building could not be merged with one through the building.
Researched I have looked at maze solvers and various shortest path finding algorithms (e.g. A*, Theta*, Phi*) and while they'd be useful for this problem they only search for a path between two points and don't consider already established routes.
Best Guess I am considering using Phi* to search for all possible routes and merge afterwards using magic (ideas?), but this will not give me truly distinct alternatives.
Can someone help?
P.S.: I'm using C++ and am not really eager to do this by myself, so if there is a library which already does this... :)
I found (and decided to use) a parallel thinning algorithm (Zhan-Suen for now) to create an image skeleton. This effectively makes the assumption that the geometry shapes the common routes, which is fine I think.
By using the Rutovitz crossing number I can extract bifurcations and crossings from the resulting skeleton. Then I'll determine the shortest line of sight from my Points of Interest (using Bresenham's algorithm) to the extracted crossings to connect them to the graph.
I hope this will help someone along the road :)

How do I best map an unorganized point cloud back to it's organized ancestor?

I get an organized point cloud (using pcl and an ASUS Xtion Pro Live), which of course contains NANs and the like. I also get an RGB image of the same scene.
The first step for processing is removing those NANs, which converts the point cloud to unorganized. I then perform a few other steps, but that's not relevant to the question (I think, see P.S.1). What COULD (I'm not sure) be relevant is that I run extract multiple times, and so have quite a few intermediate point clouds. I believe this means I can no longer assume that the points are in the same order they were at the start.
For clarification, I do understand what an unorganized point cloud it and how it differs from unorganized, both theoretically and in terms of how the data is actually stored.
After chopping off various points, I now have a much smaller point cloud which consists only of points in the original point cloud (but much less of them). How do I map these points back to the matching points in the original point cloud? I probably could iterate through the entire cloud to find matches, but this seems hacked together. Is there a better way to do this?
My main aim is to be able to say that 'point A in my final point cloud is of interest to me' and furthermore to map that to pixel K in the RGB image I first obtained. It seems to me that matching the final point cloud with the initial one is the best way to do this, but alternatives are also welcome.
P.S.1 - One of the last few steps in my process is finding a convex hull and then extracting a polygonal prism from the original point cloud. If all else fails, I will just interrogate the (20-50) points on the convex hull to match them with my initial point cloud (minimizing computation) and hence to match them with the original RGB images.
P.S.2 - Random musing - since I know the original size of the RGB image, the origin of the camera relative to the point cloud (or, rather, the position of the points relative to the camera used to take them), and can trivially obtain the camera parameters, could I simply use ray-tracing through each point in my final point cloud to produce an RGB image? The image may need registration with the 'real' RGB image, or it probably won't since nothing will have actually moved except for rounding error.

How to construct a mesh from given edge points?

I have some points on the edge(left image), and I want to construct a mesh(right), Is there any good algorithm to achieve it? many thanks!
image can see here http://ww3.sinaimg.cn/large/6a2c8e2bjw1dk8jr3t7eaj.jpg
To begin with, see Delauney triangulation. Look at this project: http://people.sc.fsu.edu/~jburkardt/c_src/triangulate/triangulate.html.
Edited because my original had too few details on edge-flipping, and when I tried to provided those details I found the TRIANGULATE project.
If the region is flat or quasi-flat look for Ear Clipping approach (http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf). In the case of curved surface you need point inside the region and therefore you may need Constrained Delaunay Triangulation (otherwise some edges may not be included in the triangulation).
There is delaunayn function in geometry package for R language (see doc)
It takes an array of boundary points (as in your case) to create a Delaunay mesh on it.
You could also save your geometry into some well-known format, and use one of mesh generators.

In PostGIS, how do I find all points within a polygon?

I am using PostgreSQL with the GIS extension to store map data, together with OpenLayers, GeoServer etc. Given a polygon, e.g. of a neighborhood, I need to find all LAT/LONG points stored in some table (e.g. traffic lights, restaurants) that are within the polygon. Alternatively given a set of polygons I would like to find the set of points within each polygon (like a GROUP BY query, rather then iterating over each polygon).
Are these functions something I need to program, or is the functionality available (as extended SQL)? Please elaborate.
Also for the simple 2D data I have do I actually need the GIS extension (GPL license is a limitation) or will PostgreSQL suffice?
Thanks!
In PostGIS you can use the bounding box operator to find candidates, which is very efficient as it uses GiST indexes. Then, if strict matches are required, use the contains operator.
Something like
SELECT
points,neighborhood_name from points_table,neighborhood
WHERE
neighborhood_poly && points /* Uses GiST index with the polygon's bounding box */
AND
ST_Contains(neighborhood_poly,points); /* Uses exact matching */
About if this is needed, depends on your requirements. For the above to work you certainly need PostGIS and GEOS installed. But, if bounding box match is enough, you can code it simply in SQL not needing PostGIS.
If exact matches are required, contains algorithms are publicly available, but to implement them efficiently requires some effort implementing it in a library which would then be called from SQL (just like GEOS).
I believe ST_Contains automatically rewrites the query to use the the GiST-indexed bounding box, as it notes:
"This function call will automatically
include a bounding box comparison that
will make use of any indexes that are
available on the geometries. To avoid
index use, use the function
_ST_Contains."
http://postgis.refractions.net/docs/ST_Contains.html
ST_Contains would solve your problem.
SELECT
polygon.gid, points.x, points.y
FROM
polygons LEFT JOIN points
ON st_contains(polygon.geom, points.geom)
WHERE
polygon.gid=your_id

Resources