模拟保留颜色信息的虚拟相机
Simulate virtual camera which preserves color information
我有一个虚拟扫描仪,它根据相机位置生成点云的 2.5-D 视图(即 3D 点云的 2D 投影)。我正在使用 vtkCamera.GetProjectionTransformMatrix()
获取从 world/global 到相机坐标的变换矩阵。
但是,如果输入点云具有点的颜色信息,我想保留它。
以下是相关行:
boost::shared_ptr<pcl::visualization::PCLVisualizer> vis; // camera location, viewpoint and up direction for vis were already defined before
vtkSmartPointer<vtkRendererCollection> rens = vis->getRendererCollection();
vtkSmartPointer<vtkRenderWindow> win = vis->getRenderWindow();
win->SetSize(xres, yres); // xres and yres are predefined resolutions
win->Render();
float dwidth = 2.0f / float(xres),
dheight = 2.0f / float(yres);
float *depth = new float[xres * yres];
win->GetZbufferData(0, 0, xres - 1, yres - 1, &(depth[0]));
vtkRenderer *ren = rens->GetFirstRenderer();
vtkCamera *camera = ren->GetActiveCamera();
vtkSmartPointer<vtkMatrix4x4> projection_transform = camera->GetProjectionTransformMatrix(ren->GetTiledAspectRatio(), 0, 1);
Eigen::Matrix4f mat1;
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
mat1(i, j) = static_cast<float> (projection_transform->Element[i][j]);
mat1 = mat1.inverse().eval();
现在,mat1 用于将坐标转换为相机视图:
pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud;
int ptr = 0;
for (int y = 0; y < yres; ++y)
{
for (int x = 0; x < xres; ++x, ++ptr)
{
pcl::PointXYZ &pt = (*cloud)[ptr];
if (depth[ptr] == 1.0)
{
pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN();
continue;
}
Eigen::Vector4f world_coords(dwidth * float(x) - 1.0f,
dheight * float(y) - 1.0f,
depth[ptr],
1.0f);
world_coords = mat1 * world_coords;
float w3 = 1.0f / world_coords[3];
world_coords[0] *= w3;
world_coords[1] *= w3;
world_coords[2] *= w3;
pt.x = static_cast<float> (world_coords[0]);
pt.y = static_cast<float> (world_coords[1]);
pt.z = static_cast<float> (world_coords[2]);
}
}
我想要虚拟扫描仪 return pcl::PointXYZRGB
带有颜色信息的点云。
任何有 VTK 经验的人提供的有关如何实现此功能的帮助都会节省我的一些时间。
我可能漏掉了这里已经提出的相关问题 - 如果是这样,请指点一下。谢谢。
如果我理解正确,你想获得点渲染到 win
RenderWindow 的颜色,你应该能够通过调用
从渲染缓冲区中获取数据
float* pixels = win->GetRGBAPixelData(0, 0, xres - 1, yres - 1, 0/1)
.
这应该以 [R0, G0, B0, A0, R1, G1, B1, A1, R2....]
格式的数组形式为您提供渲染缓冲区的每个像素。我写为 0/1
的最后一个参数是数据应该从前端还是后端 opengl 缓冲区中获取。我假设默认情况下双缓冲应该打开,所以你想从后台缓冲区读取(使用'1'),但我不确定。
一旦你有了它,你就可以在你的第二个循环中获得属于点 (depth[ptr] != 1.0
) 的所有像素的颜色:
pt.R = pixels[4*ptr];
pt.G = pixels[4*ptr + 1];
pt.B = pixels[4*ptr + 2];
你应该在完成后调用 win->ReleaseRGBAPixelData(pixels)
。
我有一个虚拟扫描仪,它根据相机位置生成点云的 2.5-D 视图(即 3D 点云的 2D 投影)。我正在使用 vtkCamera.GetProjectionTransformMatrix()
获取从 world/global 到相机坐标的变换矩阵。
但是,如果输入点云具有点的颜色信息,我想保留它。
以下是相关行:
boost::shared_ptr<pcl::visualization::PCLVisualizer> vis; // camera location, viewpoint and up direction for vis were already defined before
vtkSmartPointer<vtkRendererCollection> rens = vis->getRendererCollection();
vtkSmartPointer<vtkRenderWindow> win = vis->getRenderWindow();
win->SetSize(xres, yres); // xres and yres are predefined resolutions
win->Render();
float dwidth = 2.0f / float(xres),
dheight = 2.0f / float(yres);
float *depth = new float[xres * yres];
win->GetZbufferData(0, 0, xres - 1, yres - 1, &(depth[0]));
vtkRenderer *ren = rens->GetFirstRenderer();
vtkCamera *camera = ren->GetActiveCamera();
vtkSmartPointer<vtkMatrix4x4> projection_transform = camera->GetProjectionTransformMatrix(ren->GetTiledAspectRatio(), 0, 1);
Eigen::Matrix4f mat1;
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
mat1(i, j) = static_cast<float> (projection_transform->Element[i][j]);
mat1 = mat1.inverse().eval();
现在,mat1 用于将坐标转换为相机视图:
pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud;
int ptr = 0;
for (int y = 0; y < yres; ++y)
{
for (int x = 0; x < xres; ++x, ++ptr)
{
pcl::PointXYZ &pt = (*cloud)[ptr];
if (depth[ptr] == 1.0)
{
pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN();
continue;
}
Eigen::Vector4f world_coords(dwidth * float(x) - 1.0f,
dheight * float(y) - 1.0f,
depth[ptr],
1.0f);
world_coords = mat1 * world_coords;
float w3 = 1.0f / world_coords[3];
world_coords[0] *= w3;
world_coords[1] *= w3;
world_coords[2] *= w3;
pt.x = static_cast<float> (world_coords[0]);
pt.y = static_cast<float> (world_coords[1]);
pt.z = static_cast<float> (world_coords[2]);
}
}
我想要虚拟扫描仪 return pcl::PointXYZRGB
带有颜色信息的点云。
任何有 VTK 经验的人提供的有关如何实现此功能的帮助都会节省我的一些时间。
我可能漏掉了这里已经提出的相关问题 - 如果是这样,请指点一下。谢谢。
如果我理解正确,你想获得点渲染到 win
RenderWindow 的颜色,你应该能够通过调用
float* pixels = win->GetRGBAPixelData(0, 0, xres - 1, yres - 1, 0/1)
.
这应该以 [R0, G0, B0, A0, R1, G1, B1, A1, R2....]
格式的数组形式为您提供渲染缓冲区的每个像素。我写为 0/1
的最后一个参数是数据应该从前端还是后端 opengl 缓冲区中获取。我假设默认情况下双缓冲应该打开,所以你想从后台缓冲区读取(使用'1'),但我不确定。
一旦你有了它,你就可以在你的第二个循环中获得属于点 (depth[ptr] != 1.0
) 的所有像素的颜色:
pt.R = pixels[4*ptr];
pt.G = pixels[4*ptr + 1];
pt.B = pixels[4*ptr + 2];
你应该在完成后调用 win->ReleaseRGBAPixelData(pixels)
。