ITK  5.4.0
Insight Toolkit
itkIOTestHelper.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18#ifndef itkIOTestHelper_h
19#define itkIOTestHelper_h
20#include "ITKIOImageBaseExport.h"
21#include <string>
22
23#include "itksys/SystemTools.hxx"
24#include "itkImageFileWriter.h"
25#include "itkImageFileReader.h"
26#include "vnl/vnl_random.h"
27namespace itk
28{
30{
31public:
32 template <typename TImage>
33 static typename TImage::Pointer
34 ReadImage(const std::string & fileName,
35 const bool zeroOrigin = false,
36 typename ImageIOBase::Pointer imageio = nullptr)
37 {
38 using ReaderType = itk::ImageFileReader<TImage>;
39
40 auto reader = ReaderType::New();
41 {
42 if (imageio)
43 {
44 reader->SetImageIO(imageio);
45 }
46 reader->SetFileName(fileName.c_str());
47 try
48 {
49 reader->Update();
50 }
51 catch (const itk::ExceptionObject & err)
52 {
53 std::cout << "Caught an exception: " << std::endl;
54 std::cout << err << ' ' << __FILE__ << ' ' << __LINE__ << std::endl;
55 throw;
56 }
57 catch (...)
58 {
59 std::cout << "Error while reading in image for patient " << fileName << std::endl;
60 throw;
61 }
62 }
63 typename TImage::Pointer image = reader->GetOutput();
64 if (zeroOrigin)
65 {
66 double origin[TImage::ImageDimension];
67 for (unsigned int i = 0; i < TImage::ImageDimension; ++i)
68 {
69 origin[i] = 0;
70 }
71 image->SetOrigin(origin);
72 }
73 return image;
74 }
75
76 template <typename ImageType, typename ImageIOType>
77 static void
79 const std::string & filename,
80 typename ImageIOType::Pointer imageio = nullptr)
81 {
82 const bool create_local_io_object{ imageio.IsNull() };
83 using WriterType = itk::ImageFileWriter<ImageType>;
84 { // Test valid filename writing
85 if (create_local_io_object)
86 {
87 imageio = ImageIOType::New();
88 }
89 auto writer = WriterType::New();
90 writer->SetImageIO(imageio);
91 writer->SetFileName(filename);
92 writer->SetInput(image);
93 try
94 {
95 writer->Update();
96 }
97 catch (const itk::ExceptionObject & err)
98 {
99 std::cerr << "Exception Object caught: " << std::endl << err << std::endl;
100 throw;
101 }
102 }
103
104 { // Test if writing to an invalid location causes exception to be thrown:
105 imageio = imageio->Clone(); // A new io object is needed because the HDF5 io object is single use. A new IO
106 // object is needed to re-initialize the internal state.
107
108 const std::string bad_root_path{ "/a_blatantly_obvious/bad_file_path/that/should/never/exist/on/the/computer/" };
109 const std::string bad_filename{ bad_root_path + filename };
110 bool exception_correctly_caught = false;
111
112 auto writer = WriterType::New();
113 writer->SetImageIO(imageio);
114 writer->SetFileName(bad_filename);
115 writer->SetInput(image);
116 try
117 {
118 writer->Update();
119 }
120 catch (const itk::ExceptionObject & /* err */)
121 {
122 // This is the correct behavior
123 std::cout << "Correctly caught exception for attempting to write to an invalid file." << std::endl;
124 exception_correctly_caught = true;
125 }
126 catch (...)
127 {
128 itkGenericExceptionMacro("IO library exception not converted to an itk::ExceptionObject.");
129 }
130 if (!exception_correctly_caught)
131 {
132 itkGenericExceptionMacro("Invalid file writing path did not throw an exception: " << bad_filename << " with "
133 << imageio->GetNameOfClass());
134 }
135 }
136 }
137
138 //
139 // generate random pixels of various types
140 static void
141 RandomPix(vnl_random & randgen, itk::RGBPixel<unsigned char> & pix)
142 {
143 for (unsigned int i = 0; i < 3; ++i)
144 {
145 pix[i] = randgen.lrand32(itk::NumericTraits<unsigned char>::max());
146 }
147 }
148
149 template <typename TPixel>
150 static void
151 RandomPix(vnl_random & randgen, TPixel & pix)
152 {
153 pix = randgen.lrand32(itk::NumericTraits<TPixel>::max());
154 }
155
156 static void
157 RandomPix(vnl_random & randgen, long long & pix)
158 {
159 pix = randgen.lrand32(itk::NumericTraits<int>::max());
160 pix = (pix << 32) | randgen.lrand32();
161 }
162
163 static void
164 RandomPix(vnl_random & randgen, unsigned long long & pix)
165 {
166 pix = randgen.lrand32();
167 pix = (pix << 32) | randgen.lrand32();
168 }
169
170 static void
171 RandomPix(vnl_random & randgen, double & pix)
172 {
173 pix = randgen.drand64(itk::NumericTraits<double>::max());
174 }
175
176 static void
177 RandomPix(vnl_random & randgen, float & pix)
178 {
179 pix = randgen.drand64(itk::NumericTraits<float>::max());
180 }
181
182 static int
183 Remove(const char * fname)
184 {
185 return static_cast<bool>(itksys::SystemTools::RemoveFile(fname));
186 }
187
188 template <typename ImageType>
189 static void
191 {
192 typename ImageType::DirectionType dir;
193 dir.SetIdentity();
194 im->SetDirection(dir);
195 }
196
197 template <typename ImageType>
198 static typename ImageType::Pointer
200 const typename ImageType::SpacingType & spacing)
201 {
202 auto rval = ImageType::New();
203 SetIdentityDirection<ImageType>(rval);
204 rval->SetSpacing(spacing);
205 rval->SetRegions(region);
206 rval->Allocate();
207 return rval;
208 }
209 template <typename ImageType>
210 static typename ImageType::Pointer
212 const typename ImageType::SpacingType & spacing,
213 int vecLength)
214 {
215 auto rval = ImageType::New();
216 rval->SetSpacing(spacing);
217 rval->SetRegions(region);
218 rval->SetVectorLength(vecLength);
219 rval->Allocate();
220 return rval;
221 }
222};
223} // namespace itk
224#endif // itkIOTestHelper_h
static ImageType::Pointer AllocateImageFromRegionAndSpacing(const typename ImageType::RegionType &region, const typename ImageType::SpacingType &spacing)
static void SetIdentityDirection(typename ImageType::Pointer &im)
static ImageType::Pointer AllocateImageFromRegionAndSpacing(const typename ImageType::RegionType &region, const typename ImageType::SpacingType &spacing, int vecLength)
static void RandomPix(vnl_random &randgen, double &pix)
static int Remove(const char *fname)
static void RandomPix(vnl_random &randgen, TPixel &pix)
static void RandomPix(vnl_random &randgen, long long &pix)
static TImage::Pointer ReadImage(const std::string &fileName, const bool zeroOrigin=false, typename ImageIOBase::Pointer imageio=nullptr)
static void WriteImage(typename ImageType::Pointer image, const std::string &filename, typename ImageIOType::Pointer imageio=nullptr)
static void RandomPix(vnl_random &randgen, float &pix)
static void RandomPix(vnl_random &randgen, unsigned long long &pix)
static void RandomPix(vnl_random &randgen, itk::RGBPixel< unsigned char > &pix)
Data source that reads image data from a single file.
Writes image data to a single file.
void SetIdentity()
Definition: itkMatrix.h:193
Define additional traits for native types such as int or float.
Represent Red, Green and Blue components for color images.
Definition: itkRGBPixel.h:59
static Pointer New()
SmartPointer< Self > Pointer
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....