Используйте memcpy для сохранения точек в pcl :: PointCloud <PointT>:: ptr - PullRequest
0 голосов
/ 12 марта 2019

Я пытаюсь оптимизировать мой код, который уже работает, но включает в себя несколько глубоких копий моих данных. Я пытаюсь скопировать pointcloud с устройства, структура которого определена в struct MyPointType {...}, в pcl :: Pointcloud <> :: ptr, чтобы я мог использовать функции pcl.

Поэтому я выделяю память и запоминаю данные в массив, называемый «точками». Создание нового pcl: Pointcloud и push_back каждого элемента в этом работает отлично, но также имеет много накладных расходов. Поэтому мне было интересно, есть ли способ выделить достаточно памяти для pcl :: PointCloud, а затем напрямую скопировать мои необработанные данные с устройства в pcl :: PointCloud

В настоящее время мой код выглядит так:

// define my own point type
struct MyPointType
{
    float x;
    float y;
    float z;
    float contrast;
    uint32_t rgba;
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW   // make sure our new allocators are aligned
}   EIGEN_ALIGN16;                    // enforce SSE padding for correct memory alignment

// register it for usage in pcl functions
POINT_CLOUD_REGISTER_POINT_STRUCT(MyPointType,
(float, x, x)
(float, y, y)
(float, z, z)
(float, contrast, contrast)
(uint32_t, rgba, rgba)
)


// memcpy of data
size_t maxSize = sizeof(MyPointType)* zividCloud.size();
MyPointType * points = (MyPointType*)malloc(maxSize);
memcpy(points, zividCloud.dataPtr(), maxSize);

// push the data piecewise into my pcl::PointCloud
pcl::PointCloud<MyPointType>::Ptr cloudPCLptr(new pcl::PointCloud<MyPointType>);
for (size_t i = 0; i < zividCloud.size(); i++)
{
    cloudPCLptr->push_back(points[i]);
}       

Надеюсь, это имеет смысл, и было бы здорово, если бы кто-нибудь дал мне несколько советов по этому поводу. Спасибо:)

1 Ответ

0 голосов
/ 13 марта 2019

На случай, если кому-то будет интересно, решение оказалось довольно простым:

  • просто создайте новый pcl :: PointCloud
  • , поскольку он имеет тип boost :: shared_ptr, вы можете получить доступ к элементам, как к обычному объекту-указателю, разыменовав
  • Я неправильно понял, что pcl :: PointCloud не является std :: vector, но, напротив, это класс, в котором std :: vector имеет переменную-член для точек, которые он хранит, поэтому операция resize () должна вызываться по точкам, а не по самому элементу
  • просто memcpy к указателю первого элемента и определите размер байтов, которые вы хотите скопировать

    pcl::PointCloud<MyPointType>::Ptr cloudPCLptr2(new pcl::PointCloud<MyPointType>);
    cloudPCLptr2->points.resize(nbrOfElements);
    
    memcpy(&(cloudPCLptr2->points[0]), zividCloud.dataPtr(), nbrOfBytes);
    
...