My goal is to remove all points from a point cloud that lie within a certain radius (from the origin).
I've discovered the pcl::CropBox and pcl::CropHull filters, but the former crops a box (obviously...) and the latter needs hull indices.
I guess I could write my own filter by calculating the distance for each point and comparing it to a threshold. But maybe there is already an implementation of this that I'm not noticing?
After segmenting out subset of a pointcloud that fitted using pcl::SACMODEL_LINE RANSAC line segmentation module.
In the next step center point of extracted point cloud is computed using
pcl::compute3DCentroid(point_cloud, centroid);
Which gives accurate center point until the camera and the extracted line model object are parallel to each other.
In the last step the corner points of the extracted point cloud i.e a fitted line are calculated by the addition of known distance on the centerpoint to calculate the corner points.
This technique will be valid until the camera and the extracted line model object are parallel to each other as soon as camera makes an angle with it, the corner point calculation technique fails.
Any suggestions what should I do to calculate the corner points using an existing reliable method in PCL library to compute the corner points of the extracted point cloud data (pcl::SACMODEL_LINE).
Thanks in advance.
If you have your subset cloud accurately extracted using RANSAC, you should be able to use getMinMax3d() to find two corner points.
http://docs.pointclouds.org/1.7.0/group__common.html#ga3166f09aafd659f69dc75e63f5e10f81
While these are not actual points of the subset cloud, they can be used to determine the boundary and the points that lie on it.
I have a bunch of points lying on a vertical plane. In reality this plane
should be exactly vertical. But, when I visualize the point cloud, there is a
slight inclination (nearly 2 degrees) from the verticality. At the moment, I can calculate
this inclination only. Concerning other errors, I assume there are no
shifts or something like that.
So, I want to update coordinates of my point data so that they lie on the vertical plane. I think, I should do some kind of transformation. It may be only via rotation along X-axis. Not sure what it would be.
I guess, you understood my question. Honestly, I am poor at
mathematics. So, please let me know how to update my point coordinates
to lie on the exact vertical plane.
Note: AS I am implementing this in c++ and there are many programmers who have sound knowledge on these things, I am posting this question under c++.
UPDATES
If I say exactly what I have done so far;
I have point cloud data representing a vertical object + its surroundings things. (The data is collected by a moving scanner and may have axes deviations from the correct world axes). The problem is, I cannot say exactly that there is an error on my data or not. Therefore, I checked this with a vertical planar object (which is the dominated object in my data as well). In reality that plane is truly vertical. But, when I fit a plane by removing outliers, then that plane is not truly vertical and has nearly 2 degree inclination. Therefore, I am suspecting that my data has some error. So I want to update all my point clouds (including points on the plane and points which represent other objects) in a way to lay that particular planar points exactly on the vertical plane. Then, I guess, all the points will be updated into their correct positions as in the reality. That is all (x,y,z) coordinates should be updated.
As an example please refer the below figure.
left-represents original point cloud (as you can see, points themselves are not vertical) and back line tells the vertical plane which I fitted and red is the zenith line. as you can see, there is an inclination of the vertical plane.
So, I want to update whole my data in the right figure. then, after updating if i fit a plane again (removing outliers), then it is exactly parallel to the zenith line. please help me.
I may be able to help you out, considering I worked with planes recently. First of all, how come the points aren't coplanar from the get go? I'd make the points coplanar in the first place instead of them being at an inclination (from what origin?), and then having to fix them. Also, having the points be coplanar on your first go would increase efficiency.
Sorry if this is the answer you're not looking for, but I need more information before I can help you out. Also, 3D math is hard. If you work with it enough, it starts to get pounded into your head, where you will NEVER forget it, especially if you went through the headaches I had to go through.
I did a bit of thinking on it, and since you want to rotate along the x-axis, your rotation will be done on the xz-plane, which means we can make this a 2D problem. After doing a bit of research on Wikipedia, this may be your solution.
new z = ((x - intended x) * sin(angle)) + (z * cos(angle)) + intended x
What I'm doing here is subtracting our intended x value from our current x value, so that we make (intended x, 0) our point of origin to rotate around. After the point is rotated, I add (intended x, 0) back to our coordinate so that we get the correct result.
Depending on where you got your points from (some kind of measurement, I guess) and what you want to do with them, there are several different things you could do with your data.
The search keyword "regression plane" might help - there are several ways of finding planes approximating point clouds, and several ways to "snap" points to planes.
Edit: You want to apply a rotation around the axis defined by the cross product of the normal vector on your regression plane and the normal of your desired plane, and a point your choice. From your illustration I take it that you probably want the bottom of your vertical planar object to be the point of reference for the rotation.
So you've got your point of reference, you now the axis around which you want to rotate, and the angle. All you need to do is:
Translation (to get to your point of reference)
Rotation
I read your question again, and hopefully this answer will help you out. If there's anything else I need to know, please tell me.
Now, In order to rotate anything, there must be a center point to rotate around. Now you've already been able to detect the angle of inclination, so now we need a formula for rotating a point a certain angle around an origin. In addition, since this problem only occurs on a 2D plane, we can use this basic formula to readjust the points. For any two axis x and y:
Theta is the angle that you will rotate around in a counter-clockwise direction. x' and y' are your new points. x.origin and y.origin are the coordinates for the point you will be going around. Now I don't know if my math is 100% correct on this but if it's not, hopefully you can change a thing or two and it will work.
I have N number of points (x_N,y_N,z_N) in a point cloud. The point cloud forms the shape of a spherical shaped object. My problem is that I have points in my cloud that stick out noticeably along the z-axis (This is due to pin object inserted in my object during a scan). I would like to remove these points.
One approach I have taken is finding the change in slope for a set of points in my cloud compared to the immediate next set of points. (for example, I take my first 10 points, compute the change in slope and compare it to the change in slope for the next ten points). But this is not working so well. Any suggestions?
Any help would be greatly appreciated. Any confusion towards my problem, just let me know.
If it's sure to be a sphere like object and points are equally spread (no side has more points than other side), take the average X, Y and Z of all points.
This will be next to the center of the sphere. If that pin is not very thick or very long (if it have few points compared to the total), you can assume this as the center.
Then, measure the distance of each point to the center.
Take off those having distances higher than the average distance.
If you know the radii of the sphere and its center, simply calculate the distance of each point to the center and compare to the radii.
I have an observation and a corresponding suggestion:
First, the observation: You appear to be building a custom solution for a one-off case. This will not work when you scan a different object (with the pin sticking out again).
Now, the suggestion: Use something like meshlab, where you can load up a point cloud, select points and delete them.
Of course, if you're ken on writing code to solve this problem, then this is not helpful.
Find the highest point in z, which is 100% sure to be a pin or apart of one.
Set point to be center of sphere and remove all points within chosen radius
Iterate twice more for other pins
I have a 3d points world. I have point in it a [x,y,z] and direction (azimuthal angle θ, and polar angle ) I want to get point b [x2,y2,z2] where my ray (sent from my point a into direction) would stop. (only from one point and only for one direction). How to do such thing in pcl, is it possible (I see a ray caster class but it seems to work on whole world not point to point)?
I think that the OctreePointCloudSearch class might help you a little bit more. Have a quick look at the OctreePointCloudSearch::getIntersectedVoxelIndices method: once your point cloud is organized in an octree, it allows you to specify the origin and a direction for the ray to be used for raycasting. In your case, the origin would be the point a and the direction would be obtained from the azimuthal and polar angles (see this)
The function returns the indices to the point within the intersected voxels.
If you google for that class name you can easily find a good number of working examples (this example casts a ray from each point of the cloud toward the camera and checks for occlusions).