1.保存图片
在工程应用中,需要对三维场景进行抓拍,形成图片,采用vtkWindowToImageFilter
和vtkJPEGWriter
即可完成该功能。核心代码如下:
_renderWindow->Render();//对当前场景进行渲染
vtkSmartPointer<vtkWindowToImageFilter> wti = vtkSmartPointer<vtkWindowToImageFilter>::New();
wti->SetInput(_renderWindow);
vtkSmartPointer<vtkWindowToImageFilter> jpegWriter = vtkSmartPointer<vtkJPEGWriter>::New();
jpegWriter->SetFileName(filename);//设置图片保存路径
jpegWriter->SetInputConnection(wti->GetOutputPort());
jpegWriter->Write();//执行保存
_renderWindow->Finalize();
运行结果就是将三维场景存储为图片,如下图:
2.坐标系转换(World->View)
在工程应用中,会需要对保存的二维图片进行标注操作,即在图片上标注特定的三维点。此时需要拥倒坐标系转换。由于相机处于世界坐标系下,因此首先需要将Model坐标系转化为World坐标系。当得到目标点的World三维坐标之后,通过WorldToView()
变换可将坐标系转化到View。代码如下:
double view[3];
_render->SetWorldPoint(x, y, z, 1);//输入待换算三维点坐标
_render->WorldToView();//执行坐标变换
_render->GetViewPoint(view);//读取变换结果,u=view[0] v=view[1]
实际应用中,如果需要对大量点进行变换,可以采用读取变换矩阵,自行操作图像变换。代码如下:
//当场景不变化时,通过render对应的camera读取到变换矩阵
double mat[16];
vtkMatrix4x4::DeepCopy(mat, _camera->GetCompositeProjectionTransformMatrix(_render->GetTiledAspectRatio(), 0, 1));
//下边对单独的点(x,y,z)进行转换
double view[4];
view[0] = x * mat[0] + y * mat[1] + z * mat[2] + mat[3];
view[1] = x * mat[4] + y * mat[5] + z * mat[6] + mat[7];
view[2] = x * mat[8] + y * mat[9] + z * mat[10] + mat[11];
view[3] = x * mat[12] + y * mat[13] + z * mat[14] + mat[15];
if (view[3] != 0)
{
view[0] /= view[3];
view[1] /= view[3];
view[2] /= view[3];
}
int u = (view[0] + 1.0)*_windowWidth / 2;//_windowWidth为RenderWindow的宽度
int v = _windowHeight - (view[1] + 1.0)*_windowHeight / 2;
测试的三维映射到二维图片的结果如下: