How to create a point cloud manually from 3D points?

I can so far only do this from a range map

Hi @Adam, how do you have your points available?

I don’t have any particular points, I want to write some code that once I have 3D points it will convert this to a point cloud.

Hi @parsd,

I believe @Adam was asking this on my behalf; to give a little more context we’re performing line scans with a Genie Nano, which requires a little processing to determine depth values. So the data we end up with after our processing is direct x, y, z values for each individual point rather than being able to use the camera image directly as a range map. I was hoping it’d be possible for us to write these values directly into a PointCloud object rather than having to generate an intermediate range map image first, but I’m afraid I couldn’t see from the docs if/how this is possible?

Thanks,
Mike

1 Like

Okay so the following code would assume that you already calculated your xyz coordinates and removed invalid points.

#include <cvb/point_cloud.hpp>
#include <cvb/point_cloud_factory.hpp>

// ... std::vector<float> x,y,z if size numberOfElements
auto densePc = Cvb::PointCloudFactory::CreateSparse(numberOfElements, 
                 Cvb::PointCloudFlags::Float| Cvb::PointCloudFlags::XYZ);
Cvb::Point3D<float> *points;
auto numOfPoints = densePc->Points(points);
for (int i = 0; i < numberOfElements; ++i)
{
  points[i].SetX(x.at(i));
  points[i].SetY(y.at(i));
  points[i].SetZ(z.at(i));
}

For a direct memory access similar to LinearAccessData you could also use Cvb::PointCloud::PointComponents

I hope that helps

2 Likes

That looks great, thanks very much!

Recently I had the same problem. Here is a quick sample on how to do that in C#:

public class fillPointcloud
{
     SparsePointCloud cvbSparsePointcloud = new SparsePointCloud(rows * cols);
      long xInc = cvbSparsePointcloud.PointComponents.X.Increment.ToInt64();//Pointer
      long yInc = cvbSparsePointcloud.PointComponents.Y.Increment.ToInt64();
      long zInc = cvbSparsePointcloud.PointComponents.Z.Increment.ToInt64();     
      unsafe
      {
        var ptrX = (byte*)(cvbSparsePointcloud.PointComponents.X.BasePtr);
        var ptrY = (byte*)(cvbSparsePointcloud.PointComponents.Y.BasePtr);
        var ptrZ = (byte*)(cvbSparsePointcloud.PointComponents.Z.BasePtr);
        for (int j = 0; j < rows; j++)
        {
          Parallel.For(0, cols, i =>
          {
            *(float*)(ptrX + (i + (j * cols) ) * xInc) = array[j, i, 0];//Assigne X,Y,Z-Value to Pointcloud
            *(float*)(ptrY + (i + (j * cols) ) * yInc) = array[j, i, 1];
            *(float*)(ptrZ + (i + (j * cols) ) * zInc) = array[j, i, 2];
          });
        }
      }
}
2 Likes