(33)VTK C++开发示例 ---图片转3D
文章目录
- 1. 概述
- 2. CMake链接VTK
- 3. main.cpp文件
- 4. 演示效果
更多精彩内容 |
---|
👉内容导航 👈 |
👉VTK开发 👈 |
1. 概述
这是 VTK 测试 clipArt.tcl 的改编版本。
提供带有 2D 剪贴画的 jpg 文件,该示例将创建 3D 多边形数据模型。这些示例说明了许多 VTK 类,包括 vtkImageThreshold、vtkImageSeedConnectivity、vtkDecimatePro 和 vtkClipPolyData。
该示例假定图像具有白色背景。试试这个 .
src/Testing/Data/stormy.jpg
;程序流程如下:
- 准备数据
- 读取图片:使用
vtkJPEGReader
读取指定路径的图片。- RGB转HSV:将读取的RGB图像转换为HSV格式。
- 提取通道:从HSV图像中提取指定的通道(此处为亮度通道)。
- 阈值处理:对提取的通道进行阈值处理,将亮度值高于指定阈值的像素设置为白色,低于阈值的像素设置为黑色。
- 获取阈值范围:获取阈值处理后的图像范围。
- 种子连接:基于种子点进行区域生长分割,连接相似的像素。
- 高斯平滑:对图像进行高斯平滑处理,滤除高频噪声。
- 3D缩小:对图像进行3D缩小处理,减少数据量。
- 转换为多边形数据
- 几何过滤:将图像数据转换为多边形数据。
- 纹理映射:将纹理映射到多边形数据上。
- 裁剪多边形数据:根据指定的值裁剪多边形数据。
- 三角形过滤:将多边形数据中的所有多边形单元分解为三角形单元。
- 降采样:通过减少三角形数量来降低网格复杂度。
- 3D渲染
- 线性挤压:将2D多边形数据沿指定方向拉伸为3D结构。
- 设置映射器和演员:创建映射器和演员,将挤压后的3D数据映射给演员。
- 设置纹理:为演员设置纹理。
- 创建渲染器和渲染窗口:创建渲染器和渲染窗口,将演员添加到渲染器中,并设置渲染窗口的大小。
- 设置交互器:创建渲染窗口交互器,并设置其与渲染窗口的关联。
- 调整相机和渲染:重置相机,调整其方位、仰角和缩放比例,然后渲染场景。
- 开始交互
- 启动渲染窗口交互器,允许用户与渲染场景进行交互。
环境 | 说明 |
---|---|
系统 | ubuntu22.04、windows11 |
cmake | 3.22、3.25 |
Qt | 5.14.2 |
编译器 | g++11.4、msvc2017 |
VTK | 9.4.1 |
2. CMake链接VTK
cmake_minimum_required(VERSION 3.20 FATAL_ERROR) # 设置CMake最低版本
project(vtk2) # 设置项目名称
# 查找VTK库
find_package(VTK COMPONENTS
CommonCore
CommonExecutionModel
FiltersCore
FiltersGeometry
FiltersModeling
FiltersTexture
IOImage
ImagingColor
ImagingCore
ImagingGeneral
ImagingMorphological
InteractionStyle
RenderingContextOpenGL2
RenderingCore
RenderingFreeType
RenderingGL2PSOpenGL2
RenderingOpenGL2
)if(NOT VTK_FOUND)
message("VTK not found")
return()
endif()add_executable(vtk2 main.cpp) # 添加可执行文件target_link_libraries(vtk2 PRIVATE ${VTK_LIBRARIES}) # 链接VTK库
vtk_module_autoinit(TARGETS vtk2 MODULES ${VTK_LIBRARIES}) # 初始化VTK模块
3. main.cpp文件
/********************************************************************************
* 文件名: main.cpp
* 创建时间: 2025-03-22 15:34:01
* 开发者: MHF
* 邮箱: 1603291350@qq.com
* 功能:
*********************************************************************************/
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkClipPolyData.h>
#include <vtkDecimatePro.h>
#include <vtkImageDataGeometryFilter.h>
#include <vtkImageExtractComponents.h>
#include <vtkImageGaussianSmooth.h>
#include <vtkImageRGBToHSV.h>
#include <vtkImageSeedConnectivity.h>
#include <vtkImageShrink3D.h>
#include <vtkImageThreshold.h>
#include <vtkJPEGReader.h>
#include <vtkLinearExtrusionFilter.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkTexture.h>
#include <vtkTextureMapToPlane.h>
#include <vtkTriangleFilter.h>#include <vtkInformation.h>
#include <vtkStreamingDemandDrivenPipeline.h>#include <iostream>
#include <string>using namespace std;int main()
{/********************准备数据************/vtkNew<vtkJPEGReader> reader; // 读取图片reader->SetFileName("e:/lib/VTK/vtk-data/Data/stormy.jpg");// 将图像转换为hsv,以便我们可以对值进行阈值。vtkNew<vtkImageRGBToHSV> rgbToHsv; // RGB转HSVrgbToHsv->SetInputConnection(reader->GetOutputPort());vtkNew<vtkImageExtractComponents> extractImage; extractImage->SetInputConnection(rgbToHsv->GetOutputPort());extractImage->SetComponents(2); // 通道索引从0开始(0=R通道,1=G通道,2=B通道,对于RGB图像)// 黑白图像的阈值。vtkNew<vtkImageThreshold> threshold; // 阈值threshold->SetInputConnection(extractImage->GetOutputPort());threshold->ThresholdByUpper(230); // 设置阈值threshold->SetInValue(255); // 设置阈值内的值threshold->SetOutValue(0); // 设置阈值外的值threshold->Update(); // 更新threshold->UpdateInformation(); // 更新信息// 获取阈值的范围,extent[0]和extent[1]为x方向的范围,extent[2]和extent[3]为y方向的范围。int* extent = threshold->GetOutputInformation(0)->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT());// 基于种子点进行区域生长分割,从指定种子点扩展并连接相似像素/体素。vtkNew<vtkImageSeedConnectivity> seedConnectivity; // 种子连接seedConnectivity->SetInputConnection(threshold->GetOutputPort());seedConnectivity->SetOutputConnectedValue(255); // 设置连接值seedConnectivity->SetOutputUnconnectedValue(0); // 设置未连接值seedConnectivity->AddSeed(extent[0], extent[2]); seedConnectivity->AddSeed(extent[1], extent[2]); seedConnectivity->AddSeed(extent[1], extent[2]); seedConnectivity->AddSeed(extent[0], extent[3]); // 对图像进行高斯平滑(模糊)处理,通过高斯卷积核滤除高频噪声,常用于图像预处理。vtkNew<vtkImageGaussianSmooth> gaussianSmooth; // 高斯平滑gaussianSmooth->SetInputConnection(seedConnectivity->GetOutputPort());gaussianSmooth->SetStandardDeviations(1.0, 1.0, 1.0);gaussianSmooth->SetDimensionality(2); // 设置维度vtkNew<vtkImageShrink3D> shrink; // 3D缩小shrink->SetInputConnection(gaussianSmooth->GetOutputPort());shrink->SetShrinkFactors(1, 1, 1); // 设置缩小因子,参数为x,y,z方向上的缩小因子,默认为1,1,1。shrink->AveragingOn(); // 打开平均// 几何过滤器,将图像数据转换为多边形数据。vtkNew<vtkImageDataGeometryFilter> geometryFilter; // 几何过滤器geometryFilter->SetInputConnection(shrink->GetOutputPort());vtkNew<vtkTextureMapToPlane> textureMapToPlane; // 纹理映射到平面textureMapToPlane->SetInputConnection(geometryFilter->GetOutputPort());textureMapToPlane->SetOrigin(0, 0, 0); // 设置原点textureMapToPlane->SetPoint1(extent[1], 0, 0); // 设置点1,extent[1]为图像的宽度,参数为x,y,z方向上的点坐标,默认为0,0,0。textureMapToPlane->SetPoint2(0, extent[3], 0); // 设置点2vtkNew<vtkClipPolyData> clip; // 裁剪多边形数据clip->SetInputConnection(textureMapToPlane->GetOutputPort());clip->SetValue(5.5); // 裁剪多边形数据的值,参数范围为0-255,默认为0。clip->GenerateClipScalarsOff(); // 关闭生成裁剪标量clip->InsideOutOff(); // 关闭内部clip->InsideOutOn(); // 打开内部// 主要用于将输入的多边形数据(PolyData)中的所有多边形单元(如四边形、多边形等)分解为三角形单元vtkNew<vtkTriangleFilter> triangleFilter; // 三角形过滤器triangleFilter->SetInputConnection(clip->GetOutputPort());// 通过减少多边形数量(特别是三角形)来降低网格复杂度,同时尽可能保留原始模型的几何特征。适用于需要优化渲染性能或减小数据量的场景。vtkNew<vtkDecimatePro> decimate; // 降采样decimate->SetInputConnection(triangleFilter->GetOutputPort());decimate->BoundaryVertexDeletionOn(); // 开启边界顶点删除decimate->SetDegree(100); // 设置度数,参数为0-180,默认为15。decimate->PreserveTopologyOn(); // 保持拓扑结构decimate->SetTargetReduction(0.99); // 设置目标缩减,参数为0-1,默认为0.9。// 用于 线性拉伸 2D 几何图形生成 3D 体 的过滤器。它通过将输入的 2D 多边形(如线条、多边形、轮廓)沿指定方向拉伸,生成具有厚度的 3D 结构(如棱柱、管道等)。vtkNew<vtkLinearExtrusionFilter> extrusion; // 线性挤压extrusion->SetInputConnection(decimate->GetOutputPort());extrusion->SetExtrusionTypeToNormalExtrusion(); // 设置挤压类型为正常挤压extrusion->SetScaleFactor(50); // 用于将 2D 几何图形沿指定方向拉伸生成 3D 体。取值/********************* 开始绘制************************/vtkNew<vtkPolyDataMapper> mapper; // 映射器mapper->SetInputConnection(extrusion->GetOutputPort());mapper->ScalarVisibilityOff(); // 标量可见性关闭,让 vtkMapper 忽略输入数据中的标量值,转而使用 vtkProperty 中定义的颜色或材质属性进行渲染。vtkNew<vtkTexture> texture; // 纹理texture->InterpolateOn(); // 插值,设置为true时,将使用插值算法对纹理进行插值。texture->SetInputConnection(reader->GetOutputPort()); // 设置输入连接vtkNew<vtkActor> actor; // 演员actor->SetMapper(mapper);actor->SetTexture(texture); // 设置纹理vtkNew<vtkRenderer> renderer; // 渲染器renderer->AddActor(actor);renderer->SetBackground(0.1, 0.2, 0.4); // 设置背景颜色,参数为红、绿、蓝三个通道的颜色值,取值范围为0-1vtkNew<vtkRenderWindow> renderWindow; // 渲染窗口renderWindow->AddRenderer(renderer);renderWindow->SetSize(800, 800); // 设置窗口大小vtkNew<vtkRenderWindowInteractor> renderWindowInteractor; // 渲染窗口交互器renderWindowInteractor->SetRenderWindow(renderWindow);renderer->ResetCamera(); // 重置相机renderer->GetActiveCamera()->Azimuth(30);renderer->GetActiveCamera()->Elevation(30);renderer->GetActiveCamera()->Dolly(1.5);renderer->ResetCameraClippingRange(); // 重置相机裁剪范围renderWindow->Render(); // 渲染renderWindowInteractor->Start(); // 开始return 0;
}