How to merge Point Cloud Cluster of different size - c++

I am working with 3D point cloud using PCL. I am using Fast Point Feature histogram (FPFH) as a descriptors which is 33 Dimensional for a single point. In my work I want to do clustering of point cloud data using FPFH where clusters are defined this feature.
However, I am confused as if I compute the FPFH of a cluster containing say 200 points than my feature vector of each point in a cluster is 200 x 33. Since two clusters will have different size I cannot use the feature vector of size like above. My question is how can I appropriately compute the features and use it to describe the cluster using single 1 x 33 dimension vector?
I was thinking of using mean but than it mean does not capture relative information of all distinct point.

The FPFH descriptor is calculated around a point (from the points neighbouring that point - using either a k nearest neighbour or a fixed radius selection typically), not from the point. So no matter what the size of the cluster, the FPFH calculated from it will only be 33 dimensional. So for each cluster you just need to feed all the points in the cluster to the FPFH calculation routine and get the 33 dimensional feature vector out. You may also need to specify a point cloud containing the points around which to calculate the feature vector. If you do this per cluster, just send the centroid of the cluster (a single point) - and make sure the radius/k is big enough so that all points in the cluster are selected.

Related

How to visualize the result of pcl::FPFHEstimation in point cloud using PCL?

I'm using pcl::FPFHEstimation class to detect feature point like this:
pcl::FPFHEstimationOMP<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fest;
pcl::PointCloud<pcl::FPFHSignature33>::Ptr object_features(new pcl::PointCloud<pcl::FPFHSignature33>());
fest.setRadiusSearch(feature_radius);
fest.setInputCloud(source_cloud);
fest.setInputNormals(point_normal);
fest.compute(*object_features);
My question is how to visulize detected feature points in pointcloud? like detected feature points in red color and non-feature points in white color.
I have searched a lot for this, but I only find some ways to display histogram which is not what I want.
Fast point feature histogram is a point descriptor (which in pcl comes in the form of pcl::FPFHSignature33). This means that the algorithm computes a histogram for all points in the input point cloud. Once the descriptors of the points are computed, then you can classify, segment... the points. But the process of classifying or segmenting the points would be another algorithm.
In this paper I use FPFH to coarsely align point clouds. In there I use the FPFH descriptors to decide which point from cloud A corresponds to which point from cloud B (associate points). In this publication, what I do is I compute the curvature for all points before the FPFH, and then, I only compute the FPFH of the subset of points that which curvature is above a given threshold. This is how I extract key points. Then, I use the FPFH of these key points fo the rest of the things (in my case associate points from different point clouds).
The analogy that you propose in one of your comments: "So the feature descriptor computed by FPFH is more like a multi-dimentional eigenvector or something " would be a good one.
So, to answer your question: No, there is no other tool apart from histograms to visualize the FPFH data (or at least not an out-of-the-box pcl class that you can use).

Input one fixed cluster centroid, find N others (python)

I have a table of shipment destinations in lat, long. I have one fixed origination point (also lat, long). I would like to find other optimal origin locations using clustering. In other words, I want to assign one cluster centroid (keep it fixed) and find 1, 2, 3 . . . N other cluster centroids. Is this possible with the scikit learn cluster module?
Rather than recycling clustering for this, treat it as a regular optimization problem. You don't want to "discover structure", but optimize cost.
Beware that earth is not flat, and Euclidean distance (i.e. k-means) is a bad idea. 1 degree north is only at the equator approximately the same distance to 1 degree east. If your data is e.g. in New York, you have a non-neglibile distortion, and your solution will not even be a local optimum.
If you absolutely insist on abusing kmeans, it's easy to do.
Choose n-1 centers at random and the predefined one.
Then run 1 iteration of k-means only. Then replace that center with the desired center again. Repeat with the next iteration.

how to detect a bin / box in pcl?

Hello I am new to PCL (point cloud library) and my task is to detect 3d objects in a box / bin using surflet pairs using kinect. I am able to segment and cluster some of the objects but my algorithm also detects the box as a segment. I want to know how can I detect and remove only the box in the scene ?
should I use PCA or SIFT ?
Thank you,
Saransh Vora
You could run a planar ransac and subtract all points that belong to planes of sufficiently large sizes. An additional specification would be to only subtract out planes that have a normal vector at nearly 90 degrees from unit-z. This would allow you to search for smaller planes without fearing cutting your objects in your box too badly as it would make your filter highly specific to vertical planes.
Another note, if your box doesn't move... you could just save your (empty) point cloud ie the cloud when there are no objects in the box and then when you get a new cloud use that saved cloud as a proximity filter to cut out all points which are sufficiently close to what was labeled as background.

How Bag of Features works?

I'm not sure that this is the right forum for this question, I'm sorry otherwise.
I'm quite new to the Bag of Features model and I'm trying to implement in order to represent an image through a vector (for a CBIR project).
From what I've understood, given a training set S of n images and supposing that we want to represent an image through a vector of size k, these are the steps for implementing BoF:
For each image i, compute the set of keypoints and from that compute the set of descriptor i-D.
Put all together the set of descriptor from all the images, so now we have D.
Run the k means (where k is defined above) algorithm on D, so now we have k clusters and each descriptor vector belongs exactly to one cluster.
Define iv as the resulting BoF vector (of size k) relative to image i. Each dimension is initialized to 0.
For each image i, and for each descriptor d belonging to i-D, find out which cluster d belongs between all the k clusters. Supposing that d belongs to the j-th cluster, then vi[j]++.
What is not clear to me is how to implement point 5., so how do we understand to which cluster a descriptor belongs to, in particular if the image that we are trying to compute the BoF vector is a query image (and so didn't belong to the initial dataset)? Should we find the nearest neighbor (1-NN) in order to understand to which cluster the query descriptor belongs to?
WHY I NEED THIS - THE APPLICATION:
I'm implementing the BoF model in order to implement a CBIR: given a query image q, find the most similar image i of q in a dataset of images. In order to do this, we need to solve the 1-approximate nearest neighbor problem, for example using LSH. The problem is that the input in LSH each image is represented as a vector, so we need the BoF in order to do that! I hope that now it's clearer why I need it :)
Please, let me know also if I did some mistake in the procedure described above.
What your algorithm is doing is generating the equivalent of words for a image. The set of "words" is not meant to be a final result, but just something that makes it simple to use with other machine learning techniques.
In this setup, you generate a set of k clusters from the initial feature (the keypoints from point 1).
Then you describe each image by the number of keypoints that fall in each cluster (just like you have a text composed of words from a dictionary of length k).
Point 3 says that you take all the keypoints from the traing set images, and run k-means algorithm, to figure out some reasonable separation between the points. This basically establishes what the words are.
So for a new image you need to compute the keypoints like you did for the training set and then using the clusters you have already computed in training you figure out the feature vector for your new image. That is you convert your image into words from the dictionary you've built.
This is all a way to generate a reasonable feature vector from images (a partial result if you want). This is not a complete machine learning algorithm. To complete it you need to know what you want to do. If you just want to find the most similar image(s), then yes a nearest neighbor search should do that. If you want to label images, then you need to train a classifier (like naive-bayes) from the feature vector and use it to figure out the label for the query.

Finding the spread of each cluster from Kmeans

I'm trying to detect how well an input vector fits a given cluster centre. I can find the best match quite easily (the centre with the minimum euclidean distance to the input vector is the best), however, I now need to work how good a match that is.
To do this I need to find the spread (standard deviation?) of the vectors which build up the centroid, then see if the distance from my input vector to the centre is less than the spread. If it's more than the spread than I should be able to say that I have no clusters to fit it (given that the best doesn't fit the input vector well).
I'm not sure how to find the spread per cluster. I have all the centre vectors, and all the training vectors are labelled with their closest cluster, I just can't quite fathom exactly what I need to do to get the spread.
I hope that's clear? If not I'll try to reword it!
TIA
Ian
Use the distance function and calculate the distance from your center point to each labeled point, then figure out the mean of those distances. That should give you the standard deviation.
If you switch to using a different algorithm, such as Mixture of Gaussians, you get the spread (e.g., std. deviation) as part of the model (clustering result).
http://home.deib.polimi.it/matteucc/Clustering/tutorial_html/mixture.html
http://en.wikipedia.org/wiki/Mixture_model