VTK笔记-裁剪分割-几何裁剪-vtkClipPolyData
什么是裁剪分割
VTK加载二维数据和三维数据,我们通常观察到的是三视图图像,或者是vtkImageReslice获取到的转换矩阵对应的观察点三视图或者是斜平面图像,想要看到图像中间部分的渲染结果就要借助“手术刀”工具对图像数据进行分割裁剪,去掉不重要数据,将重要的脏器或者病灶暴露出来;
与抽取轮廓类似,裁剪也是指获取数据集中的部分数据。不过裁剪是从一个完全不同的角度来处理的。裁剪可以控制数据获取的区域,而抽取轮廓做不到这一点。
裁剪操作需要的一把“刀”——隐函数,用来完成切割的操作,并且要指定裁剪的位置——裁剪值。给定这个两个参数后,就确定了切面——隐函数对应的的函数曲面。裁剪的处理过程是首先将数据集中的点坐标带入隐函数中进行计算,然后将计算出的函数值等于裁剪值得部分(包括属性数据)取出来,即已知函数值,求自变量。可以看出裁剪是基于坐标的操作。注意:数据被“刀”分成了两部分:裁下的部分和裁掉的部分。默认只产生裁下的部分这一个输出。
vtkClipPolyData
vtkClipPolyData使用用户指定的隐式函数(user-specified implicit function)或输入标量数据(input scalar data)剪裁多边形数据;
vtkClipPolyData是一种Filter,接受vtkImplicitFunction派生出的任何子类或者标量数据集,vtkClipPolyData实现的剪切功能实际上“剪切”数据集的单元格,返回指定隐式函数(或大于标量值)内的所有内容,包括单元格的“片段”(将此与vtkExtractGeometry进行比较,该几何图形将拉出整个未切割单元格。)此筛选器的输出为多边形数据(vtkPolyData)。
要使用此Filter,必须决定是否使用隐式函数剪裁,还是使用输入标量数据。
如果要使用隐式函数进行剪裁,必须:
1)定义隐式函数
2)使用SetClipFunction方法设置它
3)如果未指定ClipFunction,则使用方法GenerateClipScalarsOn开启,或者是GenerateClipScalars关闭(默认值),则将使用输入的标量数据来剪裁多数据。
可以指定标量值,该值用于决定隐式函数的内部和外部是什么。
可以通过设置不同输出,选择那部分数据是被裁剪下的(切割算法通过计算隐式函数值或使用数据集中每个点的输入标量数据来进行。这与用于确定内部/外部的标量值进行比较。),对外显示出的效果就截然不同;
vtkClipPolyData可以配置为计算第二个输出。第二个输出是被剪裁的多边形数据。如果要访问此输出数据,需要将布尔值GenerateClippedData设置为on。
注意:为了在多边形数据中剪切所有类型的单元格,vtkClipPolyData将一些单元格三角化,然后剪切结果的简化(即点、线和三角形)。这意味着,结果输出可能包含不同于输入数据的单元格类型。在之前VTK版本中,需要手动添加vtkTriangleFilter来忽略多边形始末端重复的点,并对其三角化;
接口
裁剪隐函数
SetClipFunction方法接收vtkImplicitFunction类型的派生子类指针;如果未定义隐式函数,则将使用输入的标量数据进行剪裁。
vtkImplicitFunction* ClipFunction;
virtual void SetClipFunction(vtkImplicitFunction*);
vtkGetObjectMacro(ClipFunction, vtkImplicitFunction);
剪裁值
隐式函数的剪裁值(如果使用隐式函数剪裁时,该值为剪裁值)或标量值(如果使用标量剪裁,该值为标量值)。默认值为0.0。
double Value;
vtkSetMacro(Value, double);
vtkGetMacro(Value, double);
内部输出标志
该值被设置为禁用时,如果隐式函数的值大于值ivar,则会在隐式函数中考虑顶点。启用“内部输出”时,如果隐式函数的隐式函数值小于或等于值ivar,则会在隐式函数中考虑顶点。默认情况下,InsideOut处于关闭状态。
vtkTypeBool InsideOut;
vtkSetMacro(InsideOut, vtkTypeBool);
vtkGetMacro(InsideOut, vtkTypeBool);
vtkBooleanMacro(InsideOut, vtkTypeBool);
GenerateClipScalars标志
如果启用此标志,则输出标量值将从隐式函数值中插值,而不是从输入标量数据中插值。
如果启用此标志但不提供隐式函数,则会报告错误。默认情况下,GenerateClipScalars处于禁用状态。
vtkTypeBool GenerateClipScalars;
vtkSetMacro(GenerateClipScalars, vtkTypeBool);
vtkGetMacro(GenerateClipScalars, vtkTypeBool);
vtkBooleanMacro(GenerateClipScalars, vtkTypeBool);
对外输出
GenerateClippedOutput用于控制是否生成第二个输出。第二个输出包含被剪裁掉的多边形数据。默认情况下,GenerateClippedOutput处于禁用状态。
GetClippedOutputPort和GetClippedOutput用来输出第二个输出,是被剪裁掉的多边形数据。
GetOutput方法和GetOutputPort方法用来输出裁剪后剩余的多边形数据,是第一个输出。
vtkTypeBool GenerateClippedOutput;
vtkSetMacro(GenerateClippedOutput, vtkTypeBool);
vtkGetMacro(GenerateClippedOutput, vtkTypeBool);
vtkBooleanMacro(GenerateClippedOutput, vtkTypeBool);
vtkPolyData* GetClippedOutput();
vtkAlgorithmOutput* GetClippedOutputPort() { return this->GetOutputPort(1); }
对外输出数据精度
OutputPointsPrecision记录了对外输出数据精度类型,对应vtkAlgorithm::DesiredOutputPrecision中的SINGLE_PRECISION、
DOUBLE_PRECISION以及DEFAULT_PRECISION。
int OutputPointsPrecision;
vtkSetMacro(OutputPointsPrecision, int);
vtkGetMacro(OutputPointsPrecision, int);
示例
裁剪牛-官方示例
场景中有三个Actor,分别是裁剪后牛剩余部分,裁剪掉的部分以及裁剪隐式函数的刨面部分;
这里使用的是一个裁剪平面,是vtkPlane,vtkPlane继承自vtkImplicitFunction,定义了一个平面;
使用vtkClipPolyData类的SetClipFunction方法设定裁剪平面。
#pragma once
#include "vtk_include.h"
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkClipPolyData.h>
#include <vtkDataSetMapper.h>
#include <vtkFeatureEdges.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPlane.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkStripper.h>
#include <vtkXMLPolyDataReader.h>// Readers
#include <vtkBYUReader.h>
#include <vtkOBJReader.h>
#include <vtkPLYReader.h>
#include <vtkPolyDataReader.h>
#include <vtkSTLReader.h>
#include <vtkXMLPolyDataReader.h>
namespace {vtkSmartPointer<vtkPolyData> ReadPolyData(std::string const& fileName){vtkSmartPointer<vtkPolyData> polyData;std::string extension = "";if (fileName.find_last_of(".") != std::string::npos){extension = fileName.substr(fileName.find_last_of("."));}// Make the extension lowercasestd::transform(extension.begin(), extension.end(), extension.begin(),::tolower);if (extension == ".ply"){vtkNew<vtkPLYReader> reader;reader->SetFileName(fileName.c_str());reader->Update();polyData = reader->GetOutput();}else if (extension == ".vtp"){vtkNew<vtkXMLPolyDataReader> reader;reader->SetFileName(fileName.c_str());reader->Update();polyData = reader->GetOutput();}else if (extension == ".obj"){vtkNew<vtkOBJReader> reader;reader->SetFileName(fileName.c_str());reader->Update();polyData = reader->GetOutput();}else if (extension == ".stl"){vtkNew<vtkSTLReader> reader;reader->SetFileName(fileName.c_str());reader->Update();polyData = reader->GetOutput();}else if (extension == ".vtk"){vtkNew<vtkPolyDataReader> reader;reader->SetFileName(fileName.c_str());reader->Update();polyData = reader->GetOutput();}else if (extension == ".g"){vtkNew<vtkBYUReader> reader;reader->SetGeometryFileName(fileName.c_str());reader->Update();polyData = reader->GetOutput();}else{// Return a polydata sphere if the extension is unknown.vtkNew<vtkSphereSource> source;source->SetThetaResolution(20);source->SetPhiResolution(11);source->Update();polyData = source->GetOutput();}return polyData;}
} // namespace
class Test_Clip_cow {public:static void Test() {vtkNew<vtkNamedColors> colors;auto backgroundColor = colors->GetColor3d("steel_blue");auto boundaryColor = colors->GetColor3d("banana");auto clipColor = colors->GetColor3d("tomato");// PolyData to processauto polyData = ReadPolyData("G:\\Data\\cow.g");vtkNew<vtkPlane> plane;plane->SetOrigin(polyData->GetCenter());plane->SetNormal(1.0, -1.0, -1.0);vtkNew<vtkClipPolyData> clipper;clipper->SetInputData(polyData);clipper->SetClipFunction(plane);clipper->GenerateClipScalarsOn();clipper->GenerateClippedOutputOn();clipper->SetValue(0.5);clipper->Update();polyData = clipper->GetOutput();vtkNew<vtkDataSetMapper> clipMapper;clipMapper->SetInputData(polyData);clipMapper->ScalarVisibilityOff();vtkNew<vtkActor> clipActor;clipActor->SetMapper(clipMapper);clipActor->GetProperty()->SetDiffuseColor(clipColor.GetData());clipActor->GetProperty()->SetInterpolationToFlat();clipActor->GetProperty()->EdgeVisibilityOn();// Now extract feature edgesvtkNew<vtkFeatureEdges> boundaryEdges;boundaryEdges->SetInputData(polyData);boundaryEdges->BoundaryEdgesOn();boundaryEdges->FeatureEdgesOff();boundaryEdges->NonManifoldEdgesOff();boundaryEdges->ManifoldEdgesOff();vtkNew<vtkStripper> boundaryStrips;boundaryStrips->SetInputConnection(boundaryEdges->GetOutputPort());boundaryStrips->Update();// Change the polylines into polygonsvtkNew<vtkPolyData> boundaryPoly;boundaryPoly->SetPoints(boundaryStrips->GetOutput()->GetPoints());boundaryPoly->SetPolys(boundaryStrips->GetOutput()->GetLines());vtkNew<vtkPolyDataMapper> boundaryMapper;boundaryMapper->SetInputData(boundaryPoly);vtkNew<vtkActor> boundaryActor;boundaryActor->SetMapper(boundaryMapper);boundaryActor->GetProperty()->SetDiffuseColor(boundaryColor.GetData());vtkNew<vtkPolyDataMapper> restMapper;restMapper->SetInputConnection(clipper->GetClippedOutputPort());restMapper->ScalarVisibilityOff();vtkNew<vtkActor> restActor;restActor->SetMapper(restMapper);restActor->GetProperty()->SetRepresentationToWireframe();// Create graphics stuffvtkNew<vtkRenderer> renderer;renderer->SetBackground(backgroundColor.GetData());renderer->UseHiddenLineRemovalOn();vtkNew<vtkRenderWindow> renderWindow;renderWindow->AddRenderer(renderer);renderWindow->SetSize(640, 480);vtkNew<vtkRenderWindowInteractor> interactor;interactor->SetRenderWindow(renderWindow);// Add the actors to the renderer, set the background and sizerenderer->AddActor(clipActor);renderer->AddActor(boundaryActor);renderer->AddActor(restActor);// Generate an interesting viewrenderer->ResetCamera();renderer->GetActiveCamera()->Azimuth(30);renderer->GetActiveCamera()->Elevation(30);renderer->GetActiveCamera()->Dolly(1.2);renderer->ResetCameraClippingRange();renderWindow->Render();renderWindow->SetWindowName("CapClip");renderWindow->Render();interactor->Start();}
};
参考资料
1.《医学图像编程技术》
2.CapClip
3.VTK体切割动画
VTK笔记-裁剪分割-几何裁剪-vtkClipPolyData相关推荐
- VTK笔记-相机vtkCamera-投影方式与裁剪范围
投影方式中物体在View上的投影位置 在之前对多边形数据进行裁剪时<VTK笔记-裁剪分割-不规则闭合圈选裁剪-vtkImplicitSelectionLoop类>,显示的下图的效果:在 ...
- 矢量数据shp七个文件介绍_Arcmap入门(五)——矢量数据的提取分析(裁剪+分割)...
多边形的提取分析 1. 矢量数据的裁剪 提取与裁剪要素相重叠的输入要素. 此工具用于以其他要素类中的一个或多个要素作为模具来剪切掉要素类的一部分.在您想要创建一个包含另一较大要素类的地理要素子集的新要 ...
- 【pyqt】自制的图片裁剪分割器
前半个月左右,因为需要,要对一些图片进行裁剪.其实主要是因为要对一些瓦片素材进行处理,例如一堆瓦片里我只想要那么几块瓦片,所以需要裁剪一下.然后网上下载了十几个裁剪器,不是垃圾就是收费,或者就是垃圾+ ...
- Halcon 学习笔记五:几何定位+仿射变换+测量
Halcon 学习笔记五:几何定位+仿射变换+测量 定位流程 例子一 例子二(药片的定位) 例子三(充电宝定位) 例子四(车牌定位) 其他 定位流程 blob分析 模板匹配 (仿射变换成标准的形状) ...
- ios 图片居中裁剪_IOS图片裁剪和小图看大图动画
IOS的UIImagePickerController可以让用户通过相机或者相册获取想要的图片,并且通过设置allowsEditing属性允许用户在选择了图片以后对图片进行裁剪.不过在某些时候会出现正 ...
- HALCON 21.11:深度学习笔记---语义分割/边缘提取(12)
HALCON 21.11:深度学习笔记---语义分割/边缘提取(12) HALCON 21.11.0.0中,实现了深度学习方法. 本章介绍了如何使用基于深度学习的语义分割,包括训练和推理阶段. 通过语 ...
- Android 针对华为手机调用裁剪出现圆形裁剪框的处理
Android 针对华为手机调用裁剪出现圆形裁剪框的处理 if (Build.MANUFACTURER.equals("HUAWEI")) {intent.putExtra(&qu ...
- 如何裁剪图片,裁剪图片的几个方法
如何裁剪图片,裁剪图片的几个方法你知道吗?在日常生活中,当浏览图片时,常会想要对某些图片进行裁剪,或从生活照片中裁剪自己的部分.如何处理这种情况?裁剪图片可去除图像不必要的部分,让其更美观.专业.此外 ...
- 全志Tina Linux 系统裁剪 boot0裁剪 uboot裁剪 内核裁剪 文件系统裁剪 C库裁剪 文件系统压缩
文章目录 1 概述 2 Tina系统裁剪简介 2.1 boot0裁剪 2.2 uboot裁剪 2.3 内核裁剪 2.3.1 删除不使用的功能 2.3.2 删除不使用的驱动 2.3.3 修改内核源代码 ...
最新文章
- 蓝桥杯C/C++ 带分数
- Flink SQL 在字节跳动的优化与实践
- 42.Android之ListView中ArrayAdapter简单学习
- nagios系列(七)nagios通过自定义脚本的方式监控mysql主从同步
- Cortex M3 NVIC与中断控制
- Vue(八)发送跨域请求
- 小程序是否转发群还是个人(转发功能)
- 从零开始实现 AlphaGo(一)
- 马哥python培训学校怎么样
- 软件工程之软件工程管理
- iPhone 开发分辨率 持续更新
- 笔记本电脑无线网络连接不上怎么办
- UVA1589 象棋 Xiangqi
- LCS (动态规划)
- 关于Spark的部署yarn模式
- 如何彻底的卸载干净Oracle 11g
- Python数据可视化学习(初学中...)
- GD32F130之GPIO
- 最优化算法的简单基础介绍(主要侧重于二次规划(QP)的问题优化)
- 信息学奥赛一本通1356:计算(calc) (栈)
热门文章
- CSS3-选择器+文字+边框+背景+颜色+渐变
- 18、基于STM32的自动浇花系统
- 嵌入式开发第20、21、22、23天(触摸屏电子相册)
- linux升级失败无法启动应用程序,Ubuntu升级后无法启动 kernel panic - not syncing
- 计算机默认应用程序怎么取消,如何取消默认打开的QQ浏览器
- 创建一个node 项目,node 知识点
- 288.软件开发过程与软件测试
- 计算机视觉入门(一)
- 220817笔试(速腾聚创)
- 自动控制原理matlab pdf下载,第五章-matlab在自动控制原理中的应用.pdf