27
27
#include " itkEllipseSpatialObject.h"
28
28
#include " itkSpatialObjectToImageFilter.h"
29
29
#include " itkImageFileWriter.h"
30
+ #include " itkImageFileReader.h"
30
31
31
32
constexpr unsigned int Dimension = 2 ;
32
33
using PixelType = unsigned char ;
33
34
34
35
using ImageType = itk::Image<PixelType, Dimension>;
35
36
36
- static void
37
- CreateEllipseImage (ImageType::Pointer image);
38
- static void
39
- CreateCircleImage (ImageType::Pointer image);
40
-
41
37
int
42
- main (int itkNotUsed ( argc) , char * itkNotUsed( argv) [])
38
+ main (int argc, char * argv[])
43
39
{
44
- // Generate synthetic fixed and moving images
45
- ImageType::Pointer fixedImage = ImageType::New ();
46
- CreateCircleImage (fixedImage);
47
- ImageType::Pointer movingImage = ImageType::New ();
48
- CreateEllipseImage (movingImage);
49
-
50
- // Write the two synthetic inputs
51
- using WriterType = itk::ImageFileWriter<ImageType>;
40
+ using ReaderType = itk::ImageFileReader<ImageType>;
52
41
53
- WriterType::Pointer fixedWriter = WriterType::New ();
54
- fixedWriter->SetFileName (" fixed.png" );
55
- fixedWriter->SetInput (fixedImage);
56
- fixedWriter->Update ();
42
+ if (argc < 4 )
43
+ {
44
+ std::cout << " Usage: " << argv[0 ] << " imageFile1 imageFile2 outputFile" << std::endl;
45
+ return EXIT_FAILURE;
46
+ }
47
+ ReaderType::Pointer fixedReader = ReaderType::New ();
48
+ fixedReader->SetFileName (argv[1 ]);
49
+ fixedReader->Update ();
50
+ ImageType::Pointer fixedImage = fixedReader->GetOutput ();
57
51
58
- WriterType ::Pointer movingWriter = WriterType ::New ();
59
- movingWriter ->SetFileName (" moving.png " );
60
- movingWriter-> SetInput (movingImage );
61
- movingWriter-> Update ();
52
+ ReaderType ::Pointer movingReader = ReaderType ::New ();
53
+ movingReader ->SetFileName (argv[ 2 ] );
54
+ movingReader-> Update ( );
55
+ ImageType::Pointer movingImage = movingReader-> GetOutput ();
62
56
63
57
// We use floats internally
64
58
using InternalImageType = itk::Image<float , Dimension>;
@@ -113,8 +107,8 @@ main(int itkNotUsed(argc), char * itkNotUsed(argv)[])
113
107
// which have been normalized to a mean of zero and unit variance. We
114
108
// will follow this empirical rule in this example.
115
109
116
- metric->SetFixedImageStandardDeviation (0.4 );
117
- metric->SetMovingImageStandardDeviation (0.4 );
110
+ metric->SetFixedImageStandardDeviation (5.0 );
111
+ metric->SetMovingImageStandardDeviation (5.0 );
118
112
119
113
registration->SetFixedImage (fixedSmoother->GetOutput ());
120
114
registration->SetMovingImage (movingSmoother->GetOutput ());
@@ -172,11 +166,8 @@ main(int itkNotUsed(argc), char * itkNotUsed(argv)[])
172
166
173
167
metric->SetNumberOfSpatialSamples (numberOfSamples);
174
168
175
- // optimizer->SetLearningRate( 15.0 ); //"All the sampled point mapped to outside of the moving image"
176
- // optimizer->SetLearningRate( 1.0 );
177
- optimizer->SetLearningRate (0.1 );
178
- optimizer->SetNumberOfIterations (1000 );
179
- optimizer->MaximizeOn (); // We want to maximize mutual information (the default of the optimizer is to minimize)
169
+ // For consistent results when regression testing.
170
+ metric->ReinitializeSeed (121212 );
180
171
181
172
// Note that large values of the learning rate will make the optimizer
182
173
// unstable. Small values, on the other hand, may result in the optimizer
@@ -193,6 +184,30 @@ main(int itkNotUsed(argc), char * itkNotUsed(argv)[])
193
184
// optimizer step length is proportional to the Metric values themselves.
194
185
// Metrics with large values will require you to use smaller values for the
195
186
// learning rate in order to maintain a similar optimizer behavior.
187
+ optimizer->SetLearningRate (1.0 );
188
+
189
+ // Note that the only stop condition for the v3 GradientDescentOptimizer class
190
+ // is that the maximum number of iterations is reached.
191
+ // For the option to exit early on convergence use GradientDescentOptimizerv4
192
+ // with an accompanying v4 metric class.
193
+ optimizer->SetNumberOfIterations (200 );
194
+ optimizer->MaximizeOn (); // We want to maximize mutual information (the default of the optimizer is to minimize)
195
+
196
+ auto scales = optimizer->GetScales ();
197
+
198
+ // Let optimizer take
199
+ // large steps along translation parameters,
200
+ // moderate steps along rotational parameters,
201
+ // and small steps along scale parameters
202
+ scales.SetSize (6 );
203
+ scales.SetElement (0 , 100 );
204
+ scales.SetElement (1 , 0.5 );
205
+ scales.SetElement (2 , 0.5 );
206
+ scales.SetElement (3 , 100 );
207
+ scales.SetElement (4 , 0.0001 );
208
+ scales.SetElement (5 , 0.0001 );
209
+
210
+ optimizer->SetScales (scales);
196
211
197
212
try
198
213
{
@@ -240,107 +255,12 @@ main(int itkNotUsed(argc), char * itkNotUsed(argv)[])
240
255
resample->SetOutputDirection (fixedImage->GetDirection ());
241
256
resample->SetDefaultPixelValue (100 );
242
257
258
+ using WriterType = itk::ImageFileWriter<ImageType>;
259
+
243
260
WriterType::Pointer writer = WriterType::New ();
244
- writer->SetFileName (" output.png " );
261
+ writer->SetFileName (argv[ 3 ] );
245
262
writer->SetInput (resample->GetOutput ());
246
263
writer->Update ();
247
264
248
265
return EXIT_SUCCESS;
249
266
}
250
-
251
-
252
- void
253
- CreateEllipseImage (ImageType::Pointer image)
254
- {
255
- using EllipseType = itk::EllipseSpatialObject<Dimension>;
256
-
257
- using SpatialObjectToImageFilterType = itk::SpatialObjectToImageFilter<EllipseType, ImageType>;
258
-
259
- SpatialObjectToImageFilterType::Pointer imageFilter = SpatialObjectToImageFilterType::New ();
260
-
261
- ImageType::SizeType size;
262
- size[0 ] = 100 ;
263
- size[1 ] = 100 ;
264
-
265
- imageFilter->SetSize (size);
266
-
267
- ImageType::SpacingType spacing;
268
- spacing.Fill (1 );
269
- imageFilter->SetSpacing (spacing);
270
-
271
- EllipseType::Pointer ellipse = EllipseType::New ();
272
- EllipseType::ArrayType radiusArray;
273
- radiusArray[0 ] = 10 ;
274
- radiusArray[1 ] = 20 ;
275
- ellipse->SetRadiusInObjectSpace (radiusArray);
276
-
277
- using TransformType = EllipseType::TransformType;
278
- TransformType::Pointer transform = TransformType::New ();
279
- transform->SetIdentity ();
280
-
281
- TransformType::OutputVectorType translation;
282
- translation[0 ] = 65 ;
283
- translation[1 ] = 45 ;
284
- transform->Translate (translation, false );
285
-
286
- ellipse->SetObjectToParentTransform (transform);
287
-
288
- imageFilter->SetInput (ellipse);
289
-
290
- ellipse->SetDefaultInsideValue (255 );
291
- ellipse->SetDefaultOutsideValue (0 );
292
- imageFilter->SetUseObjectValue (true );
293
- imageFilter->SetOutsideValue (0 );
294
-
295
- imageFilter->Update ();
296
-
297
- image->Graft (imageFilter->GetOutput ());
298
- }
299
-
300
- void
301
- CreateCircleImage (ImageType::Pointer image)
302
- {
303
- using EllipseType = itk::EllipseSpatialObject<Dimension>;
304
-
305
- using SpatialObjectToImageFilterType = itk::SpatialObjectToImageFilter<EllipseType, ImageType>;
306
-
307
- SpatialObjectToImageFilterType::Pointer imageFilter = SpatialObjectToImageFilterType::New ();
308
-
309
- ImageType::SizeType size;
310
- size[0 ] = 100 ;
311
- size[1 ] = 100 ;
312
-
313
- imageFilter->SetSize (size);
314
-
315
- ImageType::SpacingType spacing;
316
- spacing.Fill (1 );
317
- imageFilter->SetSpacing (spacing);
318
-
319
- EllipseType::Pointer ellipse = EllipseType::New ();
320
- EllipseType::ArrayType radiusArray;
321
- radiusArray[0 ] = 10 ;
322
- radiusArray[1 ] = 10 ;
323
- ellipse->SetRadiusInObjectSpace (radiusArray);
324
-
325
- using TransformType = EllipseType::TransformType;
326
- TransformType::Pointer transform = TransformType::New ();
327
- transform->SetIdentity ();
328
-
329
- TransformType::OutputVectorType translation;
330
- translation[0 ] = 50 ;
331
- translation[1 ] = 50 ;
332
- transform->Translate (translation, false );
333
-
334
- ellipse->SetObjectToParentTransform (transform);
335
-
336
- imageFilter->SetInput (ellipse);
337
-
338
- ellipse->SetDefaultInsideValue (255 );
339
- ellipse->SetDefaultOutsideValue (0 );
340
- imageFilter->SetUseObjectValue (true );
341
- imageFilter->SetOutsideValue (0 );
342
-
343
- imageFilter->Update ();
344
-
345
- image->Graft (imageFilter->GetOutput ());
346
- }
0 commit comments