vtk points from display to world

本文介绍如何将图像中的像素坐标从显示坐标系转换到世界坐标系,包括获取深度图、利用VTK库进行坐标变换的过程及关键步骤。文中详细解释了通过VTK窗口获取深度图、像素坐标到视图坐标的转换以及最终视图坐标到世界坐标的转换方法。

points from display to world

目的

  • 已知条件
    • 相机的位置 compose
    • 相机的perspective transformation Matrix proj_mat
    • 该视角下的一张深度图zbuffer
    • 该视角下的关于mesh的shoot img
  • 所求
    • img中的每一个像素的显示坐标系的坐标 ⇒ 世界坐标系下的坐标

过程(前提:mesh归一化)

  • init display position
# i,j为img的某个像素的位置,pixel_d是zbuffer的i,j位置对应的值
  display_pt_[0] = i;
  display_pt_[1] = j;
  display_pt_[2] =double(*pixel_d)/ -255.0 ;
## 深度图 z_buffer
    vtkSmartPointer<vtkWindowToImageFilter> filter = vtkSmartPointer<vtkWindowToImageFilter>::New();
    vtkSmartPointer<vtkXMLImageDataWriter> imageWriter = vtkSmartPointer<vtkXMLImageDataWriter>::New();
    vtkSmartPointer<vtkImageShiftScale> scale = vtkSmartPointer<vtkImageShiftScale>::New();
    filter->SetInput(renWin_);
    filter->SetMagnification(magnitude);
    filter->SetInputBufferTypeToZBuffer();        //Extract z buffer value
    double range[2];
    filter->GetOutput()->GetScalarRange(range);

    scale->SetOutputScalarTypeToDouble();
    scale->SetInputConnection(filter->GetOutputPort());
    scale->SetShift(0);
    scale->SetScale(-255);

    // Write depth map as a .vti image
    imageWriter->SetFileName(file_path.c_str());
    imageWriter->SetInputConnection(scale->GetOutputPort());
    imageWriter->Write();
void vtkViewport::DisplayToView()
{
  if ( this->VTKWindow )
  {
    double vx,vy,vz;
    int sizex,sizey;

    /* get physical window dimensions */
    const int *size = this->VTKWindow->GetSize();
    if (size == nullptr)
    {
      return;
    }
    sizex = size[0];
    sizey = size[1];

    vx = 0.0;
    if (sizex != 0.0)
    {
      vx = 2.0 * (this->DisplayPoint[0] - sizex*this->Viewport[0])/
        (sizex*(this->Viewport[2]-this->Viewport[0])) - 1.0;
    }

    vy = 0.0;
    if (sizey != 0.0)
    {
      vy = 2.0 * (this->DisplayPoint[1] - sizey*this->Viewport[1])/
        (sizey*(this->Viewport[3]-this->Viewport[1])) - 1.0;
    }

    vz = this->DisplayPoint[2];

    this->SetViewPoint(vx,vy,vz);
  }
}

void vtkRenderer::ViewToWorld()
{
  double result[4];
  result[0] = this->ViewPoint[0];
  result[1] = this->ViewPoint[1];
  result[2] = this->ViewPoint[2];
  result[3] = 1.0;
  this->ViewToWorld(result[0],result[1],result[2]);
  this->SetWorldPoint(result);
}

void vtkRenderer::ViewToWorld(double &x, double &y, double &z)
{
  double mat[16];
  double result[4];

  if (this->ActiveCamera == nullptr)
  {
    vtkErrorMacro("ViewToWorld: no active camera, cannot compute view to world, returning 0,0,0");
    x = y = z = 0.0;
    return;
  }

  // get the perspective transformation from the active camera
  vtkMatrix4x4 *matrix = this->ActiveCamera->
                GetCompositeProjectionTransformMatrix(
                  this->GetTiledAspectRatio(),0,1);

  // use the inverse matrix
  vtkMatrix4x4::Invert(*matrix->Element, mat);

  // Transform point to world coordinates
  result[0] = x;
  result[1] = y;
  result[2] = z;
  result[3] = 1.0;

  vtkMatrix4x4::MultiplyPoint(mat,result,result);

  // Get the transformed vector & set WorldPoint
  // while we are at it try to keep w at one
  if (result[3])
  {
    x = result[0] / result[3];
    y = result[1] / result[3];
    z = result[2] / result[3];
  }
}

参考

vtk中使用查找点集中离目标点最近的k个点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sda42342342423

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值