@@ -34,41 +34,24 @@ using PixelType = unsigned char;
34
34
35
35
using ImageType = itk::Image<PixelType, Dimension>;
36
36
37
- static void
38
- CreateEllipseImage (ImageType::Pointer image);
39
- static void
40
- CreateCircleImage (ImageType::Pointer image);
41
-
42
37
int
43
- main (int itkNotUsed ( argc) , char * itkNotUsed( argv) [])
38
+ main (int argc, char * argv[])
44
39
{
45
- /* ImageType::Pointer fixedImage = ImageType::New();
46
- CreateCircleImage(fixedImage);
47
- ImageType::Pointer movingImage = ImageType::New();
48
- CreateEllipseImage(movingImage);
49
- */
50
-
51
- // Write the two synthetic inputs
52
- using WriterType = itk::ImageFileWriter<ImageType>;
53
-
54
- /*
55
- WriterType::Pointer fixedWriter = WriterType::New();
56
- fixedWriter->SetFileName("fixed.png");
57
- fixedWriter->SetInput(fixedImage);
58
- fixedWriter->Update();
59
-
60
- WriterType::Pointer movingWriter = WriterType::New();
61
- movingWriter->SetFileName("moving.png");
62
- movingWriter->SetInput(movingImage);
63
- movingWriter->Update();*/
64
-
65
40
using ReaderType = itk::ImageFileReader<ImageType>;
41
+
42
+ if (argc < 4 )
43
+ {
44
+ std::cout << " Usage: " << argv[0 ] << " imageFile1 imageFile2 outputFile" << std::endl;
45
+ return EXIT_FAILURE;
46
+ }
66
47
ReaderType::Pointer fixedReader = ReaderType::New ();
67
- fixedReader->SetFileName (" apple.jpg" );
48
+ fixedReader->SetFileName (argv[1 ]);
49
+ fixedReader->Update ();
68
50
ImageType::Pointer fixedImage = fixedReader->GetOutput ();
69
51
70
52
ReaderType::Pointer movingReader = ReaderType::New ();
71
- movingReader->SetFileName (" orange.jpg" );
53
+ movingReader->SetFileName (argv[2 ]);
54
+ movingReader->Update ();
72
55
ImageType::Pointer movingImage = movingReader->GetOutput ();
73
56
74
57
// We use floats internally
@@ -124,8 +107,8 @@ main(int itkNotUsed(argc), char * itkNotUsed(argv)[])
124
107
// which have been normalized to a mean of zero and unit variance. We
125
108
// will follow this empirical rule in this example.
126
109
127
- metric->SetFixedImageStandardDeviation (0.4 );
128
- metric->SetMovingImageStandardDeviation (0.4 );
110
+ metric->SetFixedImageStandardDeviation (5.0 );
111
+ metric->SetMovingImageStandardDeviation (5.0 );
129
112
130
113
registration->SetFixedImage (fixedSmoother->GetOutput ());
131
114
registration->SetMovingImage (movingSmoother->GetOutput ());
@@ -183,11 +166,8 @@ main(int itkNotUsed(argc), char * itkNotUsed(argv)[])
183
166
184
167
metric->SetNumberOfSpatialSamples (numberOfSamples);
185
168
186
- // optimizer->SetLearningRate( 15.0 ); //"All the sampled point mapped to outside of the moving image"
187
- // optimizer->SetLearningRate( 1.0 );
188
- optimizer->SetLearningRate (0.1 );
189
- optimizer->SetNumberOfIterations (1000 );
190
- 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 );
191
171
192
172
// Note that large values of the learning rate will make the optimizer
193
173
// unstable. Small values, on the other hand, may result in the optimizer
@@ -204,6 +184,30 @@ main(int itkNotUsed(argc), char * itkNotUsed(argv)[])
204
184
// optimizer step length is proportional to the Metric values themselves.
205
185
// Metrics with large values will require you to use smaller values for the
206
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);
207
211
208
212
try
209
213
{
@@ -251,107 +255,12 @@ main(int itkNotUsed(argc), char * itkNotUsed(argv)[])
251
255
resample->SetOutputDirection (fixedImage->GetDirection ());
252
256
resample->SetDefaultPixelValue (100 );
253
257
258
+ using WriterType = itk::ImageFileWriter<ImageType>;
259
+
254
260
WriterType::Pointer writer = WriterType::New ();
255
- writer->SetFileName (" output.png " );
261
+ writer->SetFileName (argv[ 3 ] );
256
262
writer->SetInput (resample->GetOutput ());
257
263
writer->Update ();
258
264
259
265
return EXIT_SUCCESS;
260
266
}
261
-
262
-
263
- void
264
- CreateEllipseImage (ImageType::Pointer image)
265
- {
266
- using EllipseType = itk::EllipseSpatialObject<Dimension>;
267
-
268
- using SpatialObjectToImageFilterType = itk::SpatialObjectToImageFilter<EllipseType, ImageType>;
269
-
270
- SpatialObjectToImageFilterType::Pointer imageFilter = SpatialObjectToImageFilterType::New ();
271
-
272
- ImageType::SizeType size;
273
- size[0 ] = 100 ;
274
- size[1 ] = 100 ;
275
-
276
- imageFilter->SetSize (size);
277
-
278
- ImageType::SpacingType spacing;
279
- spacing.Fill (1 );
280
- imageFilter->SetSpacing (spacing);
281
-
282
- EllipseType::Pointer ellipse = EllipseType::New ();
283
- EllipseType::ArrayType radiusArray;
284
- radiusArray[0 ] = 10 ;
285
- radiusArray[1 ] = 20 ;
286
- ellipse->SetRadiusInObjectSpace (radiusArray);
287
-
288
- using TransformType = EllipseType::TransformType;
289
- TransformType::Pointer transform = TransformType::New ();
290
- transform->SetIdentity ();
291
-
292
- TransformType::OutputVectorType translation;
293
- translation[0 ] = 65 ;
294
- translation[1 ] = 45 ;
295
- transform->Translate (translation, false );
296
-
297
- ellipse->SetObjectToParentTransform (transform);
298
-
299
- imageFilter->SetInput (ellipse);
300
-
301
- ellipse->SetDefaultInsideValue (255 );
302
- ellipse->SetDefaultOutsideValue (0 );
303
- imageFilter->SetUseObjectValue (true );
304
- imageFilter->SetOutsideValue (0 );
305
-
306
- imageFilter->Update ();
307
-
308
- image->Graft (imageFilter->GetOutput ());
309
- }
310
-
311
- void
312
- CreateCircleImage (ImageType::Pointer image)
313
- {
314
- using EllipseType = itk::EllipseSpatialObject<Dimension>;
315
-
316
- using SpatialObjectToImageFilterType = itk::SpatialObjectToImageFilter<EllipseType, ImageType>;
317
-
318
- SpatialObjectToImageFilterType::Pointer imageFilter = SpatialObjectToImageFilterType::New ();
319
-
320
- ImageType::SizeType size;
321
- size[0 ] = 100 ;
322
- size[1 ] = 100 ;
323
-
324
- imageFilter->SetSize (size);
325
-
326
- ImageType::SpacingType spacing;
327
- spacing.Fill (1 );
328
- imageFilter->SetSpacing (spacing);
329
-
330
- EllipseType::Pointer ellipse = EllipseType::New ();
331
- EllipseType::ArrayType radiusArray;
332
- radiusArray[0 ] = 10 ;
333
- radiusArray[1 ] = 10 ;
334
- ellipse->SetRadiusInObjectSpace (radiusArray);
335
-
336
- using TransformType = EllipseType::TransformType;
337
- TransformType::Pointer transform = TransformType::New ();
338
- transform->SetIdentity ();
339
-
340
- TransformType::OutputVectorType translation;
341
- translation[0 ] = 50 ;
342
- translation[1 ] = 50 ;
343
- transform->Translate (translation, false );
344
-
345
- ellipse->SetObjectToParentTransform (transform);
346
-
347
- imageFilter->SetInput (ellipse);
348
-
349
- ellipse->SetDefaultInsideValue (255 );
350
- ellipse->SetDefaultOutsideValue (0 );
351
- imageFilter->SetUseObjectValue (true );
352
- imageFilter->SetOutsideValue (0 );
353
-
354
- imageFilter->Update ();
355
-
356
- image->Graft (imageFilter->GetOutput ());
357
- }
0 commit comments