// 切割介绍
// 对于一个模型的切割需要怎么办呢,想想切西瓜就知道,首先需要有一个模型、然后有一个切割平面
// 接着对于每个切割操作来更新模型,这样就可以得到切割的效果了
#include "vtkPlanes.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkVolume.h"
#include "vtkVolumeProperty.h"
#include "vtkXMLImageDataReader.h"
#include "vtkContourFilter.h"
#include "vtkSmartPointer.h"
#include "vtkPolyDataNormals.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkOutlineFilter.h"
#include "vtkStripper.h"
#include "vtkSmoothPolyDataFilter.h"
#include <vtkSphereSource.h>
#include <vtkImagePlaneWidget.h>
#include <vtkInteractorStyleTrackballActor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include "vtkActor.h"
#include "vtkImageFlip.h"
#include "vtkImageResample.h"
#include "vtkImageViewer.h"
#include "vtkConeSource.h"
#include "vtkBoxWidget.h"
#include "vtkTransform.h"
#include "VTKReBuild.h"
#include <vtkLineSource.h>
#include <vtkDataSetMapper.h>
#include <vector>
#include <OpenCV243.h>
#include "vtkPolyDataWriter.h"
#include "vtkPolyDataReader.h"
using namespace std;
using namespace cv;
class BuildVTKWidgetCall : public vtkCommand
{
public:
static BuildVTKWidgetCall *New()
{
return new BuildVTKWidgetCall;
}
public:
virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData)
{
vtkImplicitPlaneWidget *pWidget = reinterpret_cast<vtkImplicitPlaneWidget*>(caller);
if (pWidget)
{
vtkSmartPointer<vtkPlane> planeNew = vtkPlane::New();
pWidget->GetPlane(planeNew);
cliper->SetClipFunction(planeNew);
cliper->Update();
vtkSmartPointer<vtkPolyData> clipedData = vtkPolyData::New();
clipedData->DeepCopy(cliper->GetOutput());
vtkSmartPointer<vtkPolyDataMapper> coneMapper = vtkPolyDataMapper::New();
coneMapper->SetInput(clipedData);
coneMapper->ScalarVisibilityOff();
actor->SetMapper(coneMapper);
}
}
void setCliper(vtkSmartPointer<vtkClipPolyData> other){cliper = other;}
void setPlane(vtkSmartPointer<vtkPlane> other){pPlane = other;}
void setActor(vtkSmartPointer<vtkActor> other){actor = other;}
private:
vtkSmartPointer<vtkPlane> pPlane;
vtkSmartPointer<vtkActor> actor;
vtkSmartPointer<vtkClipPolyData> cliper;
};
void build3DView()
{
vtkSmartPointer<vtkRenderer> aRenderer =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renWin =
vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer(aRenderer);
vtkSmartPointer<vtkRenderWindowInteractor> iren =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
vtkSmartPointer<vtkJPEGReader> dicomReader =
vtkSmartPointer<vtkJPEGReader>::New();
dicomReader->SetFilePrefix("C:/Users/DawnWind/Desktop/000/");
dicomReader->SetFilePattern("%s%d.jpg");
dicomReader->SetDataByteOrderToLittleEndian();
dicomReader->SetDataSpacing(1, 1, 1.4);
dicomReader->SetFileNameSliceSpacing(1);
dicomReader->SetDataExtent(0, 209, 0, 209, 0, 29);
dicomReader->Update();
vtkSmartPointer<vtkContourFilter> skinExtractor =
vtkSmartPointer<vtkContourFilter>::New();
skinExtractor->SetInputConnection(dicomReader->GetOutputPort());
skinExtractor->SetValue(0, 100); //值越大,保留的部分越少。
#ifdef TEST
// 这里有用到OpenCV 如果用户没有安装OpenCV那么请将与之有关的删除
// 这里一定要update不然下面的getpoints之类是无法取得数据的
jpegReader->Update()
skinExtractor->Update();
auto data = skinExtractor->GetOutput();
auto points = data->GetPoints();
auto pSize = points->GetNumberOfPoints();
vector<Point3d> pointsGroup;
Mat newMat = Mat::zeros(210, 210, CV_8UC1);
int matStep = newMat.step;
auto matData = newMat.data;
Point2d center;
for (int i = 0; i < pSize; i++)
{
double point[3];
points->GetPoint(i, point);
Point3d p1;
p1.x = (point[0]);
p1.y = (point[1]);
p1.z = (point[2]);
*(matData + (int)point[0] + (int)point[1] * matStep) = 255;
pointsGroup.push_back(p1);
center.x += (int)point[0];
center.y += (int)point[1];
}
center.x /= pSize;
center.y /= pSize;
imshow("mat", newMat);
//Mat dst0;
//flip(newMat, dst0, 0);
//imshow("dst0", dst0);
//Mat dst1;
//flip(newMat, dst1, 1);
//imshow("dst1", dst1);
//Mat dstn1;
//flip(newMat, dstn1, -1);
//imshow("dstn1", dstn1);
//imwrite("a.jpg", newMat);
// 图像本身是与原始图像成某轴对称因此不能在原图中找中心点
waitKey();
#endif
/**做平滑处理**/
vtkSmartPointer<vtkSmoothPolyDataFilter> smooth = vtkSmoothPolyDataFilter::New();
smooth->SetInput( skinExtractor->GetOutput());
smooth->SetNumberOfIterations( 100 );
//重新计算法向量
vtkSmartPointer<vtkPolyDataNormals> skinNormals =
vtkSmartPointer<vtkPolyDataNormals>::New();
skinNormals->SetInputConnection(smooth->GetOutputPort());
skinNormals->SetFeatureAngle(60.0);
vtkSmartPointer<vtkStripper> skinStripper = //create triangle strips and/or poly-lines 为了更快的显示速度
vtkSmartPointer<vtkStripper>::New();
skinStripper->SetInputConnection(skinNormals->GetOutputPort());
vtkSmartPointer<vtkPolyDataMapper> skinMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
skinMapper->SetInputConnection(skinStripper->GetOutputPort());
skinMapper->ScalarVisibilityOff(); //这样不会带颜色
vtkSmartPointer<vtkActor> skin =
vtkSmartPointer<vtkActor>::New();
skin->SetMapper(skinMapper);
vtkSmartPointer<vtkOutlineFilter> outlineData =
vtkSmartPointer<vtkOutlineFilter>::New();
outlineData->SetInputConnection(dicomReader->GetOutputPort());
vtkSmartPointer<vtkPolyDataMapper> mapOutline =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapOutline->SetInputConnection(outlineData->GetOutputPort());
vtkSmartPointer<vtkActor> outline =
vtkSmartPointer<vtkActor>::New();
outline->SetMapper(mapOutline);
outline->GetProperty()->SetColor(0, 0, 0);
vtkSmartPointer<vtkCamera> aCamera =
vtkSmartPointer<vtkCamera>::New();
aCamera->SetViewUp (0, 0, -1);
aCamera->SetPosition (0, 1, 0);
aCamera->SetFocalPoint (0, 0, 0);
aCamera->ComputeViewPlaneNormal();
aCamera->Azimuth(30.0);
aCamera->Elevation(30.0);
aCamera->Dolly(1.5);
aRenderer->AddActor(outline);
aRenderer->AddActor(skin);
aRenderer->SetActiveCamera(aCamera);
aRenderer->ResetCamera ();
aRenderer->SetBackground(.2, .3, .4);
aRenderer->ResetCameraClippingRange ();
renWin->SetSize(640, 480);
vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
iren->SetInteractorStyle( style );
/////////设置截面
vtkSmartPointer<vtkClipPolyData> cliper = vtkClipPolyData::New();
cliper->SetInput(skinStripper->GetOutput());
// 此平面box可以通过右键来进行放大缩小处理(只有当鼠标控制区域只有切割体才单一有效)
vtkSmartPointer<vtkImplicitPlaneWidget> implicitPlaneWidget = vtkImplicitPlaneWidget::New();
implicitPlaneWidget->SetInteractor(iren);
implicitPlaneWidget->SetPlaceFactor(1.25);
//initially position the widget
implicitPlaneWidget->SetInput(skinStripper->GetOutput());
implicitPlaneWidget->PlaceWidget();
//////Render2
vtkSmartPointer<vtkActor> coneSkinActor = vtkActor::New();
coneSkinActor->SetMapper( skinMapper );
vtkSmartPointer<vtkRenderer> rRenderer =
vtkSmartPointer<vtkRenderer>::New();
rRenderer->SetBackground( 0.2, 0.3, 0.5 );
rRenderer->SetViewport(0.5, 0.0, 1.0, 1.0);
rRenderer->AddActor(coneSkinActor);
vtkSmartPointer<BuildVTKWidgetCall> pCall = BuildVTKWidgetCall::New();
pCall->setActor(coneSkinActor);
pCall->setCliper(cliper);
renWin->AddRenderer(rRenderer);
///////
implicitPlaneWidget->AddObserver(vtkCommand::EndInteractionEvent, pCall);
implicitPlaneWidget->On();
// Render
renWin->Render();
// Initialize the event loop and then start it.
iren->Initialize();
iren->Start();
}
分享到:
相关推荐
VC6下vtk编程,用vtkImplicitPlaneWidget实现任意平面切割
体数据裁切功能
基于 VTK 的交互式切割的研究与实现.pdf
VC6下vtk编程,用vtkImplicitPlaneWidget实现任意平面切割
基于VTK光线投射法的CT图像三维重建,一篇不错的文献。
为提高模型切割的效率与自然性,利用VTK提供的接口,采用射线拾取方法实现了对表面模型的标记点方式切割,结合四元数的方法...实验表明,通过扩展VTK来实现对三维模型的任意切割是可行的,并可达到较为理想的切割效果。
可视化算法实现医学图像的三维模型重建,针对不同重建模型分别实现虚拟任意切割:面切 割和体切割,并讨论了虚拟切割的交互操作实现方法。用VTK(Visualization Toolkit)if)7步实 现了模拟手术系统中的虚拟切割脊柱体...
基于vtk的三维重构与裁切: 1.16位非压缩位图的读取与设置. 2.图像数据载入映射器 3.裁切平面的设置 4.边界的设置与显示 5.三维重构 注:需安装vtk4.0以上版本-">功能: 1、图像的三位重构 2、骨骼组织的显示 效果: 1...
基于VTK的三维地质结构模型切割算法,杨洪军,王占刚,地质工作者为了更好的研究地质体的结构,需要切割三维地质结构模型并对剖面进行分析。一般切割算法在切割质量不高的模型时得到的
基于VTK的医学图像三维重建及其可视化 图像处理参考资料
基于VTK实现旋转功能,实现效果见博客:https://blog.csdn.net/qq_40041064/article/details/130636319 已按VTK中Widget和Representation进行封装,简单易用!
很好的基于VTK开发库的医学图像三维重建,这里用了VTK里的面绘制方法就行了三维重建,对初学者很有益,望交流学习!
一个简单的基于VTK软件开发包的零件三维实体分割系统,支持读入.g和.stl文件、分割实体、合并实体、保存分割后独立实体、着色导入实体、保存导入实体的点坐标。附件中包含源代码、演示视频、和可执行程序,适合帮助...
基于VTK库的医学图像处理子系统设计和实现
c++开发基于VTK封装的三维点云模型分析库+sln解决方案.zipc++开发基于VTK封装的三维点云模型分析库+sln解决方案.zipc++开发基于VTK封装的三维点云模型分析库+sln解决方案.zipc++开发基于VTK封装的三维点云模型分析库...
基于VTK的医学图像三维重建系统的设计与实现,使用"CAJViewer"软件打开使用。
利用MC算法 基于VTK平台的面绘制实现代码
vtk切片切块各种程序综合 体绘制 切片 切块 汇总
科学计算可视化(Visualization in Scientific Computing)是基于日趋成熟的图形学的图像处理技术,它充分发挥人的视觉潜力,以图形、图像及动画等视觉表现形式展现计算与数据的本质,并允许与计算和数据进行交互。...