当前位置:
k262电脑网 >
网络知识 > 发布时间:2025-06-15 09:09 文章来源于网友投稿,仅供参考!
ITK 简单使用
第一个ITK程序
1、CMakeLists.txt
1 # This is the root ITK CMakeLists file.
2 cmake_minimum_required(VERSION 3.10)
3
4 # This project is designed to be built outside the Insight source tree.
5 project(ITK_demo)
6
7 # Find VTK
8 set(ITK_DIR D:/ProgramFiles/ITK5.1.1/lib/cmake/ITK5.1) # add wmz
9 find_package(ITK REQUIRED)
10 include_directories($)
11 message("ITK dir = $")
12 message("ITK lib = $")
13
14 include($)
15 #aux_source_directory(src SRC_LIST)
16 set(SRC_LIST
17 ./itk_demopp)
18
19 add_executable(itk_demo $ )
20 target_link_libraries(itk_demo $)
关于 include($) 的说明可以在 UseITKmake 中找到:
1 #
2 #
3 # This file is not part of the ITK API. It exists purely as an
4 # implementation detail. This CMake module may change fr version to
5 # version without notice, or even be removed.
6 #
7 # We mean it.
8 #
9
10 # This file sets up include directories, link directories, IO settings and
11 # cpiler settings for a project to use ITK. It should not be
12 # included directly, but rather through the ITK_USE_FILE setting
13 # obtained fr ITKConfigmake.
2、 测试数据
测试数据下载路径:github/InsightSoftwareConsortium/ITK/tree/master/Examples/Data
其实编译ITK时的目录下就有需要的测试数据,比如我的ITK5.1.1目录下。
\ITK5.1.1\Examples\Data
3、代码
作为第一个示例程序本来应该写一个很简单的像HelloWorld的程序,但是一些比较简单的官网的程序 要么依赖VTK,要么版本高于ITK5.1.1.
所以就找了一个比较长的程序,是一个配准的程序。
代码来自:github/InsightSoftwareConsortium/ITK/blob/master/Examples/RegistrationITKv4/MultiResImageRegistration1xx
我找了一个其他人做过的中文注释版
1 #include "itkImageRegistrationMethodv4.h"
2 #include "itkTranslationTransform.h"
3 #include "itkMeanSquaresImageToImageMetricv4.h"
4 #include "itkRegularStepGradientDescentOptimizerv4.h"
5 #include "itkImageFileReader.h"
6 #include "itkImageFileWriter.h"
7 #include "itkPNGImageIOFactory.h"
8 #include "itkResampleImageFilter.h"
9 #include "itkCastImageFilter.h"
10 #include "itkRescaleIntensityImageFilter.h"
11 #include "itkSubtractImageFilter.h"
12 /*****************************************************************************************************************
13 * 本例子是一个图像配准的Demo
14 * 0、创建了一个Cmand对象,用于监控配准的过程,被后面的对象调用
15 * 1、首先要定义像素的维度以及像素类型:进进而链接参考图像以及浮动图像
16 * 2、定义框架的基本组件:
17 * 确定变换种类:TransformType:二维变换
18 * 确定优化方法:OptimizerType:梯度下降
19 * 确定相似度度量:MetricType:链接两个图像:浮动图像以及参考图像
20 * 3、创建图像组件,并且通过创建上述框架,进而进行设置(链接)
21 * 4、设置插值方法:LinearInterpolateImageFunction并且链接在一起
22 * 5、6:通过ImageFileReader方法进行读取,链接到 registration并更新
23 * 7、针对前面的TransformType进行实例化:平移变换用于配准SetInitialTransformParameters:用于设置初始值
24 * 8、针对优化方法的设置:OptimizerType:前面在创建的时候已经设置了其梯度下降方法,此步骤用于对其微调:初始步长,收敛公差,最大迭代次数
25 * 9、通过RegistrationParameterScalesFrPhysicalShift:将每一个配准要素链接到配准方法中执行,
26 * 10、实例化Cmon对象,监控配准过程的执行,触发配准过程迭代
27 * 11、通过update函数触发配准的执行
28 * 12、配准结果定义空间变换的参数序列:其结果由GetLastTransformParameters( )获得并且输出
29 * X、Y的变换:TranslationAlongX;TranslationAlongY
30 * 迭代次数:numberOfIterations
31 * 最后的结果:bestValue
32 * 通过CpositeTransform:AddTransform将转换添加到堆栈的背面,并且拥有可优化的参数。
33 * 也就是说:添加堆栈,副本??
34 * 13、14、15、16、ResampleFilterType方法:
35 * 用变换参数将两幅图像进行叠加比较,并设置重采样滤波器:输入两幅图像
36 * 输出的是一个变换
37 * 对滤波器进行相关参数的设置:大小、原点、间距、位置
38 * 并通过CastFilterType:setInput:weiter进行相关的输出
39 * 此时:这个图象就是配准结束后的图像
40 * 17、通过itk::SubtractImageFilter对两幅图像进行比较:
41 * fixedImageReader;resampler
42 * 18、对图像进行处理 itk::RescaleIntensityImageFilter:调节一下亮度;并进行输出
43 * 19、一致性转发计算参考图像与正在移动图像之间的不同,输出图片5
44 ******************************************************************************************************************/
45 /*CmandIterationUpdate 类:
46 继承Cmand,监视配准过程的执行。每调用一次,输出相应参数
47 object类指向事件的观察者
48 Execute方法,类似cellbake,回转
49 observer方法:
50
51 */
52 class CmandIterationUpdate : public itk::Cmand
53 ;
61
62 public:
64 typedef itk::RegularStepGradientDescentOptimizerv4<double> OptimizerType;
65 typedef const OptimizerType* OptimizerPointer;
66
67 void Execute(itk::Object* caller, const itk::EventObject& event) ITK_OVERRIDE
68
71 //Object表示激活事件的对象,event表示被激活的事件
72 void Execute(const itk::Object* object, const itk::EventObject& event) ITK_OVERRIDE
73
80
81 std::cout << optimizer>GetCurrentIteration() << " = ";
82 std::cout << optimizer>GetValue() << " : ";
83 std::cout << optimizer>GetCurrentPosition() << std::endl;
84 }
85
86 };
87
88
89 int main()
90
198 optimizer>SetNumberOfIterations(200);//最大迭代次数
199
200
201 //10、实例化cmend对象,监视配准过程的执行,并处触发配准过程
202 CmandIterationUpdate::Pointer observer = CmandIterationUpdate::New();
203 optimizer>AddObserver(itk::IterationEvent(), observer);
204
205
206 const unsigned int numberOfLevels = 1;
207
208 RegistrationType::ShrinkFactorsArrayType shrinkFactorsPerLevel;
209 shrinkFactorsPerLevel.SetSize(1);
210 shrinkFactorsPerLevel[0] = 1;
211
212 RegistrationType::SmoothingSigmasArrayType smoothingSigmasPerLevel;
213 smoothingSigmasPerLevel.SetSize(1);
214 smoothingSigmasPerLevel[0] = 0;
215
216 registration>SetNumberOfLevels(numberOfLevels);
217 registration>SetSmoothingSigmasPerLevel(smoothingSigmasPerLevel);
218 registration>SetShrinkFactorsPerLevel(shrinkFactorsPerLevel);
219
220
221
222 //11、通过调用Update函数触发配准执行
223 try
224
230 catch (itk::ExceptionObject& err)
231
236
237 //12、配准结果是一系列定义空间变换的参数序列,结果由get获得
238 TransformType::ConstPointer transform = registration>GetTransform();
239 TransformType::ParametersType finalParameters = transform>GetParameters();
240 const double TranslationAlongX = finalParameters[0];//队列中每个元素对应着沿着一个空间维度的平移
241 const double TranslationAlongY = finalParameters[1];
242
243 //优化器能够询问抵达收敛的迭代的实际次数并通过GetCurrentIteration()返回出来
244 const unsigned int numberOfIterations = optimizer>GetCurrentIteration();//迭代次数
245 //最终参数集合的图像量规值通过优化器的GetValue();
246 const double bestValue = optimizer>GetValue();//最优化的度量
247
248 //将上述输出
249 std::cout << "Result = " << std::endl;
250 std::cout << " Translation X = " << TranslationAlongX << std::endl;//输出移动X的值
251 std::cout << " Translation Y = " << TranslationAlongY << std::endl;//输出移动Y的值
252 std::cout << " Iterations = " << numberOfIterations << std::endl;//输出迭代次数
253 std::cout << " Metric value = " << bestValue << std::endl;//输出优化的度量
254
255 typedef itk::CpositeTransform<
256 double,
257 Dimension > CpositeTransformType;
258 CpositeTransformType::Pointer outputCpositeTransform =
259 CpositeTransformType::New();
260 outputCpositeTransform>AddTransform(movingInitialTransform);
261 outputCpositeTransform>AddTransform(
262 registration>GetModifiableTransform());
2
264
265 //13、用变换结果将待配准图映射到参考图像中
266 typedef itk::ResampleImageFilter<
267 MovingImageType,
268 FixedImageType > ResampleFilterType;
269
270 //14、创建一个重采样滤波器,输入待配准图像
271 ResampleFilterType::Pointer resampler = ResampleFilterType::New();
272 resampler>SetInput(movingImageReader>GetOutput());
273 //配准函数生成的变换也作为重采样滤波器的输入被传递
274 resampler>SetTransform(outputCpositeTransform);
275
276 //15、ResampleImageFilter要求指定额外的参数,特别是输出图像的间 距、原点和大小
277 FixedImageType::Pointer fixedImage = fixedImageReader>GetOutput();
278 resampler>SetSize(fixedImage>GetLargestPossibleRegion().GetSize());//尺寸
279 resampler>SetOutputOrigin(fixedImage>GetOrigin());//原点
280 resampler>SetOutputSpacing(fixedImage>GetSpacing());//间距
281 resampler>SetOutputDirection(fixedImage>GetDirection());//位置
282 resampler>SetDefaultPixelValue(100);
283
284 //16、滤波器的输出被传递给一个在文件中存储图像的writer
285 typedef unsigned char OutputPixelType;
286
287 typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
288
289 typedef itk::CastImageFilter<//转化重采样的像素类型到最终的writer类型
290 FixedImageType,
291 OutputImageType > CastFilterType;
292 typedef itk::ImageFileWriter< OutputImageType > WriterType;
293 //调用new函数创建新的滤波器
294 WriterType::Pointer writer = WriterType::New();
295 CastFilterType::Pointer caster = CastFilterType::New();
296 writer>SetFileName("E:\\documents\\vs2019\\itk_demo\\build\\RelWithDebInfo\\output\\RegistrationITKv4Moving13x17yInputType.png");//写到文件夹位置
297 caster>SetInput(resampler>GetOutput());
298 writer>SetInput(caster>GetOutput());
299 writer>Update();//触发更新
300
301 //17、参照图像和被变换的待配准图像很容易用itk::SubtractImageFilter比较
302 //pixelwise滤波器 计算两幅输入的同源像素的不同:
303 typedef itk::SubtractImageFilter<
304 FixedImageType,
305 FixedImageType,
306 FixedImageType > DifferenceFilterType;
307
308 DifferenceFilterType::Pointer difference = DifferenceFilterType::New();
309
310 difference>SetInput1(fixedImageReader>GetOutput());//不同
311 difference>SetInput2(resampler>GetOutput());
312
313 //18、两幅图像的不同也许比较暗,我们用下面方法对其进行调节亮度,使之更加的明显
314 typedef itk::RescaleIntensityImageFilter<
315 FixedImageType,
316 OutputImageType > RescalerType;
317
318 RescalerType::Pointer intensityRescaler = RescalerType::New();
319
320 intensityRescaler>SetInput(difference>GetOutput());
321 intensityRescaler>SetOutputMinimum(0);
322 intensityRescaler>SetOutputMaximum(255);
323
324 resampler>SetDefaultPixelValue(1);
325
326
327 //输出到另外一个位置(调亮)
328 WriterType::Pointer writer2 = WriterType::New();
329 writer2>SetInput(intensityRescaler>GetOutput());
330
331 writer2>SetFileName("E:\\documents\\vs2019\\itk_demo\\build\\RelWithDebInfo\\output\\Moving13x17yInputType.png");
332 writer2>Update();
333
334 //设置了一致性转换,计算参考图像的不同
335
336 resampler>SetTransform(identityTransform);
337
338 writer2>SetFileName("E:\\documents\\vs2019\\itk_demo\\build\\RelWithDebInfo\\output\\DifferenceBeforeRegistration.png");
339 writer2>Update();
340
341 return EXIT_SUCCESS;
342
343 }
4、结果
输入图像
输出图像
上一篇:SimpleITK 读取医学影像文件
下一篇:NRRD批量转换成NIFTI
ITK