1.VTK中的图像重采样实现

图像重采样是指对采样后形成的由离散数据组成的数字图像按所需的像元位置或像元问距重新采样,以构成几何变换后的新图像。重采样过程本质上是图像恢复过程,它用输入的离散数字图像重建代表原始图像二维连续函数,再按新的像元间距和像元位置进行采样。其数学过程是根据重建的连续函数(曲面),用周围若干像元点的值估计或内插出新采样点的值。图像重采样在图像处理中应用非常广泛,如SIFT特征提取
图像重采样后图像的维数会发生改变。当重采样图像小于原图像维数时,称为降采样;当重采样图像维数大于原图像时,称为升采样。VTK中可以方便的对图像进行重采样。vtkImageShrink3D类实现图像降采样。降采样需要设置每个方向的采样率,降采样率越大,图像越模糊。升采样的原理与降采样原理一致,只是增加采样点数来增加图像的维数。VTK中vtkImageMagnify来实现图像的升采样
实验代码如下所示:
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);#include <vtkSmartPointer.h>
#include <vtkBMPReader.h>
#include <vtkImageData.h>
#include <vtkImageShrink3D.h> //降采样头文件
#include <vtkImageMagnify.h>  //升采样头文件
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h> //交互样式int main()
{vtkSmartPointer<vtkBMPReader> reader =vtkSmartPointer<vtkBMPReader>::New();reader->SetFileName("lena.bmp");reader->Update();vtkSmartPointer<vtkImageShrink3D> shrinkFilter =vtkSmartPointer<vtkImageShrink3D>::New();shrinkFilter->SetInputConnection(reader->GetOutputPort());//建立管道shrinkFilter->SetShrinkFactors(16, 16, 1);//设置降采样率shrinkFilter->Update();vtkSmartPointer<vtkImageMagnify> magnifyFilter =vtkSmartPointer<vtkImageMagnify>::New();magnifyFilter->SetInputConnection(reader->GetOutputPort());magnifyFilter->SetMagnificationFactors(10, 10, 1);magnifyFilter->Update();int originalDims[3];reader->GetOutput()->GetDimensions(originalDims);double originalSpacing[3];reader->GetOutput()->GetSpacing(originalSpacing);int shrinkDims[3];shrinkFilter->GetOutput()->GetDimensions(shrinkDims);double shrinkSpacing[3];shrinkFilter->GetOutput()->GetSpacing(shrinkSpacing);int magnifyDims[3];magnifyFilter->GetOutput()->GetDimensions(magnifyDims);double magnifuSpacing[3];magnifyFilter->GetOutput()->GetSpacing(magnifuSpacing);std::cout << "原始维度:      " << originalDims[0] << "*" << originalDims[1] << "*" << originalDims[2] << std::endl;std::cout << "原始像素间距:  " << originalSpacing[0] << " " << originalSpacing[1] << " " << originalSpacing[2] << std::endl;std::cout << "降采样维度:    " << shrinkDims[0] << "*" << shrinkDims[1] << "*" << shrinkDims[2] << std::endl;std::cout << "降采样像素间距:" << shrinkSpacing[0] << " " << shrinkSpacing[1] << " " << shrinkSpacing[2] << std::endl;std::cout << "升采样维度:    " << magnifyDims[0] << "*" << magnifyDims[1] << "*" << magnifyDims[2] << std::endl;std::cout << "升采样像素间距:" << magnifuSpacing[0] << " " << magnifuSpacing[1] << " " << magnifuSpacing[2] << std::endl;vtkSmartPointer<vtkImageActor> origActor =vtkSmartPointer<vtkImageActor>::New();origActor->SetInputData(reader->GetOutput());vtkSmartPointer<vtkImageActor> shrinkActor =vtkSmartPointer<vtkImageActor>::New();shrinkActor->SetInputData(shrinkFilter->GetOutput());vtkSmartPointer<vtkImageActor> magnifyActor =vtkSmartPointer<vtkImageActor>::New();magnifyActor->SetInputData(magnifyFilter->GetOutput());///double origView[4] = { 0, 0, 0.3, 1.0 };double shrinkView[4] = { 0.3, 0, 0.6, 1.0 };double magnifyView[4] = { 0.6, 0, 1, 1 };vtkSmartPointer<vtkRenderer> origRender =vtkSmartPointer<vtkRenderer>::New();origRender->SetViewport(origView);origRender->AddActor(origActor);origRender->ResetCamera();origRender->SetBackground(1, 0, 0);vtkSmartPointer<vtkRenderer> shrinkRender =vtkSmartPointer<vtkRenderer>::New();shrinkRender->SetViewport(shrinkView);shrinkRender->AddActor(shrinkActor);shrinkRender->ResetCamera();shrinkRender->SetBackground(0, 1, 0);vtkSmartPointer<vtkRenderer> magnifyRender =vtkSmartPointer<vtkRenderer>::New();magnifyRender->SetViewport(magnifyView);magnifyRender->AddActor(magnifyActor);magnifyRender->ResetCamera();magnifyRender->SetBackground(0, 0, 1);/vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(origRender);rw->AddRenderer(shrinkRender);rw->AddRenderer(magnifyRender);rw->SetSize(720, 240);rw->SetWindowName("Image-Shrink-Magnify");rw->Render();vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();vtkSmartPointer<vtkInteractorStyleImage> style =vtkSmartPointer<vtkInteractorStyleImage>::New();rwi->SetInteractorStyle(style);rwi->SetRenderWindow(rw);rwi->Initialize();rwi->Start();return 0;
}

vtkImageShrink3D通过SetShrinkFactors()设置X、Y和Z方向的采样率,参数为三个int类型数据。vtkImageMagnify通过SetMagnificationFactors设置相应的放大采样率。上

面例子中分别对原图像维数缩小原来的1/16和放大为原来的10倍,执行结果如下:

从图中可以看成,重采样图像已经变得十分模糊了。而升采样图像则变化不大。程序中输出了原图和重采样图像的维数和像素间隔,从输出来看,原图像的维数为512x512,缩小16倍后,图像维数变为32x32。需要注意的是,原图的像素间隔为(1,1,1),而重采样后像素间隔变为(16, 16, 1),这是因为采样是在世界坐标系下进行的,当采样图像的维数减小时,采样的像素间隔也相应的变大,这样保持图像的区域不会发生改变。同样的道理,当升采样后图像的维数变为原来的10倍,而像素间隔变为原来的十分之一。
另外,图像的重采样类有:vtkImageResample。

2.参看资料

1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3.《The Visualization Toolkit – AnObject-Oriented Approach To 3D Graphics (4th Edition)》
4.  张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.

VTK修炼之道30:图像重采样_降采样和升采样技术相关推荐

  1. VTK修炼之道60:体绘制_体绘制管线图形渲染管线

    1.几何渲染与体绘制 1.1 几何渲染 前面练习的渲染技术都是几何渲染技术.所谓的几何渲染技术,就是通过绘制几何图元(顶点.线段.面片等)来渲染数据,例如:绘制图像需要在空间中建立一个四边形图元,然后 ...

  2. VTK修炼之道61:体绘制_光线投影+最大密度投影+等值面法

    1.vtkVolumeMapper vtkVolumeMapper是所有体绘制Mapper类的虚基类,提供接口函数,并由其子类实现具体功能.该类的继承关系如下图所示: 应该掌握一些常用的体绘制类. 2 ...

  3. VTK修炼之道14:图像处理_创建

    1.引言:图像数据结构 数字图像文件内容由两个部分组成:图像头信息和数据.图像头信息定义了图像的基本信息,主要包括起点位置(Origin),像素间隔(space)和维数(dimension).通过这三 ...

  4. VTK修炼之道32:边缘检测_梯度算子

    1.梯度算子提取图像边缘 图像中不连续的灰度值会产生边缘,图像的边缘检测是基于边界的图像分割方法,如分水岭算法,通常是分割原图的梯度图像,梯度实际上也是反应的图像边缘信息.图像边缘一般常用图像一阶导数 ...

  5. VTK修炼之道16:图像处理_窗口分割和图像融合(ViewportvtkImageBlend)

    1.前言 前面演示的例子都是在一个窗口中显示一个图像.但是在常见的图像处理软件中,经常会遇到在一个窗口中显示多个图像,这就会用到图像融合技术.图像融合利用图像的alpha通道和不透明度来实现.VTK中 ...

  6. VTK修炼之道62:体绘制_固定点光线投影体绘制与GPU加速光线投影体绘制

    1.固定点光线投影算法 vtkFixedPointVolumeRayCastMapper是一个较好的vtkVolumeRayCastMapper的替代者.该类能够实现基于Alpha合成的体绘制方法和最 ...

  7. VTK修炼之道39:图像平滑_各向异性滤波

    1.各向异性扩散滤波 高斯平滑方法在平滑噪声的同时,模糊了图像的重要边缘图像. 各向异性滤波是一种基于偏微分方程的滤波技术,建立于热量的各向异性扩散理论. 各向异性滤波在图像的平坦区域选择大尺度平滑, ...

  8. VTK修炼之道38:图像平滑_中值滤波器

    1.中值滤波 vtkImageHybridMedian2D实现了对二维图像的中值滤波.其实现原理是,采用一个5x5的模板,逐次将模板中心对应于图像的每个像素上,将模板图像覆盖的像素的中值作为当前像素的 ...

  9. VTK修炼之道37:图像平滑_高斯滤波器

    1.高斯滤波 高斯平滑的原理类似于均值滤波.均值滤波模板的系数都是一样的,而高斯平滑则是需要根据像素与模板中心的距离来定义权重.权重的计算方法是采用高斯分布,离中心越远,权重越小. 下面是一个利用Ga ...

最新文章

  1. 《Science》重磅:终于完成了!迄今为止最完整的人类基因组
  2. react-dnd中context丢失解决方法
  3. nginx反向代理(proxy_pass)tomcat的过程中,session失效的问题解决
  4. AdvancedEAST笔记
  5. hibernate二级缓存理解
  6. mysql avg 时间_MySQL或Rails在特定日期范围内每天获得AVG的最佳方式
  7. css为什么要清除浮动
  8. iOS开发 UILabel实现自适应高宽
  9. C语言 semaphore
  10. yii2 html编辑器,浅析Yii2集成富文本编辑器redactor实例教程
  11. kotlin_Kotlin print(),println(),readLine(),Scanner,REPL
  12. python实现在线答题_python实现用户答题功能
  13. 机场VIP会员管理系统
  14. 【vue】使用手机app扫描二维码登录
  15. 一个IOS音乐播放器源码
  16. stick棍子by Ye
  17. 商城小程序的一些功能介绍以及搭建教程
  18. Cisco ASA防火墙——远程控制与多安全区域
  19. 泛泰A900 刷4.4专用中文TWRP2.7.1.1版 支持自己主动识别手机版本号(全球首创)...
  20. mysql日期以及字符串相关格式化转换

热门文章

  1. Sweet.js 用 Readtables 编译 JSX
  2. 计算点、线、面等元素之间的交点、交线、封闭区域面积和闭合集(续7)
  3. dubbo的学习使用,第一章
  4. PHP中预定义的超全局数组
  5. foreach的工作原理和深拷贝、浅拷贝
  6. C#基础第七天-作业-利用面向对象的思想去实现名片-动态添加
  7. WebService 的创建,部署和使用
  8. Array.prototype.slice.call(arguments)对象转成数组
  9. 一个初学者困惑的Oracle的认证问题
  10. FIR IIR滤波器的设计