DMRITool  v0.1.1-139-g860d86b4
Diffusion MRI Tool
PrintImage.cxx
Go to the documentation of this file.
1 
11 #include "PrintImageCLP.h"
12 #include "itkImageRegionIteratorWithIndex.h"
21 #include "utl.h"
22 
25 
26 typedef double ScalarType;
27 typedef itk::VectorImage<ScalarType, 3> VectorImageType;
28 typedef itk::Image<ScalarType, 4> NDImageType;
30 typedef itk::Image<itk::VariableLengthVector<ScalarType>, 3> VariableLengthImageType;
31 
32 template <class ImageType, class Image2Type>
33 void
34 ConvertImage ( const itk::SmartPointer<ImageType>& image, itk::SmartPointer<Image2Type>& imageOut )
35 {
36  // if (itk::GetImageType(image)==itk::GetImageType(imageOut))
37  // imageOut = image;
38 }
39 
40 template<>
41 void
42 ConvertImage<NDImageType, VectorImageType>( const itk::SmartPointer<NDImageType>& image, itk::SmartPointer<VectorImageType>& imageOut )
43 {
44  itk::MultiVolumeToVectorImage(image, imageOut);
45 }
46 
47 template<>
48 void
49 ConvertImage<VectorImageType, NDImageType>( const itk::SmartPointer<VectorImageType>& image, itk::SmartPointer<NDImageType>& imageOut )
50 {
51  itk::VectorToMultiVolumeImage(image, imageOut);
52 }
53 
54 
55 template <class IndexType>
56 bool
57 IsOutsideBox ( const IndexType& index, const std::vector<int>& box )
58 {
59  return index[0]<box[0] || index[0]>box[1] || index[1]<box[2] || index[1]>box[3] || index[2]<box[4] || index[2]>box[5];
60 }
61 
62 template <class ImageType, class ReaderType, class Image0Type=ImageType, class Reader0Type=ReaderType>
63 int
64 PrintImage(int argc, char const* argv[])
65 {
66  PARSE_ARGS;
67  typename ImageType::Pointer image = ImageType::New();
68  itk::ReadImage<ImageType, ReaderType>(_InputImageFile, image);
69 
70  itk::VectorImageRegionIteratorWithIndex<ImageType> it(image, image->GetLargestPossibleRegion());
71  int vecSize = itk::GetVectorImageVectorSize(image);
72  std::vector<int> size = itk::GetVectorImage3DVolumeSize(image);
73 
74  utlGlobalException(_Box.size()!=6, "wrong size of _Box");
75  std::vector<int> realBox(_Box);
76  realBox[0] = realBox[0]<0 ? 0 : (realBox[0]>size[0]-1 ? size[0]-1 : realBox[0]);
77  realBox[1] = realBox[1]==-1 ? size[0]-1 : (realBox[1]<0 ? 0 : (realBox[1]>size[0]-1 ? size[0]-1 : realBox[1]) );
78  realBox[2] = realBox[2]<0 ? 0 : (realBox[2]>size[1]-1 ? size[1]-1 : realBox[2]);
79  realBox[3] = realBox[3]==-1 ? size[1]-1 : (realBox[3]<0 ? 0 : (realBox[3]>size[1]-1 ? size[1]-1 : realBox[3]) );
80  realBox[4] = realBox[4]<0 ? 0 : (realBox[4]>size[2]-1 ? size[2]-1 : realBox[4]);
81  realBox[5] = realBox[5]==-1 ? size[2]-1 : (realBox[5]<0 ? 0 : (realBox[5]>size[2]-1 ? size[2]-1 : realBox[5]) );
82 
83  // utl::PrintVector(realBox, "realBox");
84 
85  typedef itk::Image<double, 3> ScalarImageType;
86  ScalarImageType::Pointer mask = ScalarImageType::New();
87  itk::ImageRegionIteratorWithIndex<ScalarImageType> maskIt;
88  if (_MaskImageFile!="")
89  {
90  itk::ReadImage<ScalarImageType>(_MaskImageFile, mask);
91  std::vector<int> sizeMask = itk::GetVectorImage3DVolumeSize(mask);
92  utlGlobalException(!utl::IsSameVector(size,sizeMask), "mask image has different size");
93 
94  maskIt = itk::ImageRegionIteratorWithIndex<ScalarImageType> (mask, mask->GetLargestPossibleRegion());
95  }
96 
97  utlGlobalException((_DifferencePercent==1 || _DifferencePercent==2) && _BaseImageFile=="", "need to set _BaseImageFile");
98 
99  typename ImageType::IndexType index;
100  itk::VariableLengthVector<double> vec;
101 
102  std::cout << "\nImage option:" << std::endl;
103  for (it.GoToBegin(), maskIt.GoToBegin();
104  !it.IsAtEnd();
105  ++it, ++maskIt)
106  {
107  if (_MaskImageFile!="" && maskIt.Get()<=0)
108  continue;
109 
110  index = it.GetIndex();
111  if (IsOutsideBox(index, realBox))
112  continue;
113 
114  it.GetVector(vec);
115 
116  if (!_PrintAllVoxels && vec.GetNorm()<1e-8)
117  continue;
118 
119  if (_DifferencePercent!=2)
120  {
121  std::ostringstream oss;
122  oss << "Image1 " << index << " ";
123 
124  if (_OrientationsFile=="" && std::fabs(_Power-1.0)>1e-10)
125  {
126  // only use power without _OrientationsFile
127  for ( int i = 0; i < vec.Size(); ++i )
128  vec[i] = std::pow(vec[i], _Power);
129  }
130 
131  utl::PrintVector(vec, vec.Size(), oss.str());
132  }
133  }
134 
135  if (_BaseImageFile!="")
136  {
137  std::cout << "\nImage difference option:" << std::endl;
138 
139  typename Image0Type::Pointer image0 = Image0Type::New();
140  int baseImageType = itk::GetImageType(_BaseImageFile);
141  if (itk::GetImageType(image0)==baseImageType)
142  {
143  itk::ReadImage<Image0Type, Reader0Type>(_BaseImageFile, image0);
144  }
145  else
146  {
147  if (baseImageType==IMAGE_ND)
148  {
149  typename NDImageType::Pointer imageTmp = NDImageType::New();
150  itk::ReadImage<NDImageType>(_BaseImageFile, imageTmp);
151  ConvertImage(imageTmp, image0);
152  }
153  else if (baseImageType==IMAGE_VECTOR)
154  {
155  typename VectorImageType::Pointer imageTmp = VectorImageType::New();
156  itk::ReadImage<VectorImageType>(_BaseImageFile, imageTmp);
157  ConvertImage(imageTmp, image0);
158  }
159  else
160  utlGlobalException(true, "wrong image type");
161  }
162 
163  std::vector<int> size0 = itk::GetVectorImage3DVolumeSize(image0);
164  int vecSize0 = itk::GetVectorImageVectorSize(image0);
165  utlGlobalException(!utl::IsSameVector(size0,size) || vecSize!=vecSize0, "these two image have different sizes");
166 
167  itk::VectorImageRegionIteratorWithIndex<Image0Type> it0(image0, image0->GetLargestPossibleRegion());
168  itk::VariableLengthVector<double> vec0, diff;
169 
170  for (it.GoToBegin(), it0.GoToBegin(), maskIt.GoToBegin();
171  !it.IsAtEnd();
172  ++it, ++it0, ++maskIt)
173  {
174  if (_MaskImageFile!="" && maskIt.Get()<=0)
175  continue;
176 
177  index = it.GetIndex();
178  if (IsOutsideBox(index, realBox))
179  continue;
180 
181  it.GetVector(vec);
182  it0.GetVector(vec0);
183 
184  if (_OrientationsFile=="" && std::fabs(_Power-1.0)>1e-10)
185  {
186  // only use power without _OrientationsFile
187  for ( int i = 0; i < vec.Size(); ++i )
188  {
189  vec[i] = std::pow(vec[i],_Power);
190  vec0[i] = std::pow(vec0[i],_Power);
191  }
192  }
193  diff = vec-vec0;
194  for ( int jj = 0; jj < diff.Size(); ++jj )
195  diff[jj] = std::fabs(diff[jj]);
196 
197  if (!_PrintAllVoxels && (diff.GetNorm()<1e-8 || vec0.GetNorm()<1e-8 || vec.GetNorm()<1e-8))
198  continue;
199 
200  if (_DifferencePercent!=2)
201  {
202  std::ostringstream oss;
203  oss << "difference " << index << " ";
204 
205  utl::PrintVector(diff, diff.Size(), oss.str());
206  }
207  }
208 
209  if (_DifferencePercent==1 || _DifferencePercent==2)
210  {
211  std::cout << "\nImage difference percentage option:" << std::endl;
212 
213  std::vector<double> perVec;
214  for (it.GoToBegin(), it0.GoToBegin(), maskIt.GoToBegin();
215  !it.IsAtEnd();
216  ++it, ++it0, ++maskIt)
217  {
218  if (_MaskImageFile!="" && maskIt.Get()<=0)
219  continue;
220 
221  index = it.GetIndex();
222  if (IsOutsideBox(index, realBox))
223  continue;
224 
225  it.GetVector(vec);
226  it0.GetVector(vec0);
227 
228  if (_OrientationsFile=="" && std::fabs(_Power-1.0)>1e-10)
229  {
230  for ( int i = 0; i < vec.Size(); ++i )
231  {
232  vec[i] = std::pow(vec[i],_Power);
233  vec0[i] = std::pow(vec0[i],_Power);
234  }
235  }
236  diff = vec-vec0;
237  for ( int jj = 0; jj < diff.Size(); ++jj )
238  diff[jj] = std::fabs(diff[jj]);
239 
240  if (!_PrintAllVoxels && (diff.GetNorm()<1e-8 || vec0.GetNorm()<1e-8 || vec.GetNorm()<1e-8))
241  continue;
242 
243  double diffPer = diff.GetNorm()/vec0.GetNorm();
244  if (_DifferencePercent==1)
245  {
246  std::ostringstream oss;
247  oss << "difference percentage " << index << " ";
248  std::cout << oss.str() << ": " << diffPer << std::endl;
249  }
250  perVec.push_back(diffPer);
251  }
252  utl::PrintVector(perVec, "percentage vector");
253  }
254 
255  }
256 
257  if (vecSize==6)
258  {
259  std::cout << "\nDTI option:" << std::endl;
260  itk::VariableLengthVector<double> dt(9);
261  for (it.GoToBegin(), maskIt.GoToBegin();
262  !it.IsAtEnd();
263  ++it, ++maskIt)
264  {
265  if (_MaskImageFile!="" && maskIt.Get()<=0)
266  continue;
267 
268  index = it.GetIndex();
269  if (IsOutsideBox(index, realBox))
270  continue;
271 
272  it.GetVector(vec);
273 
274  if (!_PrintAllVoxels && vec.GetNorm()<1e-8)
275  continue;
276 
277  if (_DifferencePercent!=2)
278  {
279  std::ostringstream oss;
280  oss << "DTI " << index << " ";
281  if (_TensorStorageFormat=="6D_UPPER") utl::ConvertTensor6DTo9D(vec, dt, TENSOR_UPPER_TRIANGULAR);
282  if (_TensorStorageFormat=="6D_LOWER") utl::ConvertTensor6DTo9D(vec, dt, TENSOR_LOWER_TRIANGULAR);
283  if (_TensorStorageFormat=="6D_EMBED") utl::ConvertTensor6DTo9D(vec, dt, TENSOR_EMBED6D);
284  if (_TensorStorageFormat=="6D_DIAGONAL_FIRST") utl::ConvertTensor6DTo9D(vec, dt, TENSOR_DIAGONAL_FIRST);
285  if (_TensorStorageFormat=="9D") dt=vec;
286  utl::PrintVector(dt, dt.Size(), oss.str());
287  }
288  }
289  }
290 
291  if (_OrientationsFile!="")
292  {
293  std::cout << "\nSpherical function option:" << std::endl;
294  typedef utl::NDArray<double,2> MatrixType;
295  typedef utl_shared_ptr<MatrixType> MatrixPointer;
296  typedef utl::NDArray<double,1> VectorType;
297 
298  int shRank = utl::DimToRankSH(vecSize);
299  utlPrintVar2(true, vecSize, shRank);
300  MatrixPointer grad = utl::ReadGrad<double>(_OrientationsFile, DIRECTION_NODUPLICATE, CARTESIAN_TO_SPHERICAL);
301  MatrixPointer basisMatrix = utl::ComputeSHMatrix(shRank, *grad, SPHERICAL_TO_SPHERICAL);
302 
303  VectorType sf, sh(vecSize);
304  for (it.GoToBegin(), maskIt.GoToBegin();
305  !it.IsAtEnd();
306  ++it, ++maskIt)
307  {
308  if (_MaskImageFile!="" && maskIt.Get()<=0)
309  continue;
310 
311  index = it.GetIndex();
312  if (IsOutsideBox(index, realBox))
313  continue;
314 
315  it.GetVector(vec);
316 
317  if (!_PrintAllVoxels && vec.GetNorm()<1e-8)
318  continue;
319 
320  utl::VectorToVector(vec, sh, vecSize);
321  std::ostringstream oss;
322  oss << "SF " << index << " ";
323  sf = (*basisMatrix) * sh;
324 
325  if (std::fabs(_Power-1.0)>1e-10)
326  {
327  for ( int i = 0; i < sf.Size(); ++i )
328  sf[i] = std::pow(sf[i], _Power);
329  }
330  utl::PrintVector(sf, sf.Size(), oss.str());
331  }
332  }
333  return 0;
334 }
335 
339 int
340 main (int argc, char const* argv[])
341 {
342  // GenerateCLP
343  PARSE_ARGS;
344 
345 
346  int inputType = itk::GetImageType(_InputImageFile);
347 
348  if (inputType==IMAGE_VECTOR)
349  return PrintImage<VectorImageType, itk::ImageFileReader<VectorImageType>>(argc, argv);
350  else if (inputType==IMAGE_ND)
351  return PrintImage<NDImageType, itk::ImageFileReader<NDImageType>>(argc, argv);
352  else if (inputType==IMAGE_SPARSE)
353  return PrintImage<SparseImageType, itk::SpatiallyDenseSparseVectorImageFileReader<SparseImageType>>(argc, argv);
354  else if (inputType==IMAGE_VARIABLELENGTH)
355  return PrintImage<VariableLengthImageType, itk::VariableLengthVectorImageFileReader<VariableLengthImageType>>(argc, argv);
356 
357  // if (!_BaseImageFileArg.isSet())
358  // {
359  // if (isInputVectorImage)
360  // return PrintImage<VectorImageType, VectorImageType>(argc, argv);
361  // else
362  // return PrintImage<NDImageType, VectorImageType>(argc, argv);
363  // }
364  // else
365  // {
366  // isBaseVectorImage = itk::IsVectorImage(_BaseImageFile);
367  // if (isInputVectorImage && isBaseVectorImage)
368  // return PrintImage<VectorImageType, VectorImageType>(argc, argv);
369  // else if (!isInputVectorImage && isBaseVectorImage)
370  // return PrintImage<NDImageType, VectorImageType>(argc, argv);
371  // else if (isInputVectorImage && !isBaseVectorImage)
372  // return PrintImage<VectorImageType, NDImageType>(argc, argv);
373  // else if (!isInputVectorImage && !isBaseVectorImage)
374  // return PrintImage<NDImageType, NDImageType>(argc, argv);
375  // }
376 
377  return 0;
378 }
int GetImageType(const std::string &filename)
Definition: utlITK.h:203
itk::Image< itk::VariableLengthVector< ScalarType >, 3 > VariableLengthImageType
Definition: PrintImage.cxx:30
Created "06-10-2016.
helper functions specifically used in dmritool
void VectorToVector(const T1 &v1, T2 &v2, const int N)
Definition: utlCore.h:1699
void ConvertImage< NDImageType, VectorImageType >(const itk::SmartPointer< NDImageType > &image, itk::SmartPointer< VectorImageType > &imageOut)
Definition: PrintImage.cxx:42
void MultiVolumeToVectorImage(const SmartPointer< Image< ScalarType, Dim+1 > > &image1, SmartPointer< VectorImage< ScalarType, Dim > > &image2)
int DimToRankSH(const int dimm)
Definition: utlDMRI.h:182
void ConvertImage(const itk::SmartPointer< ImageType > &image, itk::SmartPointer< Image2Type > &imageOut)
Definition: PrintImage.cxx:34
void ConvertImage< VectorImageType, NDImageType >(const itk::SmartPointer< VectorImageType > &image, itk::SmartPointer< NDImageType > &imageOut)
Definition: PrintImage.cxx:49
std::shared_ptr< NDArray< T, 2 > > ComputeSHMatrix(const unsigned int rank, const NDArray< T, 2 > &grad, const int mode)
Definition: utl.h:171
double ScalarType
Definition: PrintImage.cxx:26
int PrintImage(int argc, char const *argv[])
Definition: PrintImage.cxx:64
#define utlGlobalException(cond, expout)
Definition: utlCoreMacro.h:372
itk::VectorImage< ScalarType, 3 > VectorImageType
Definition: PrintImage.cxx:27
#define utlPrintVar2(cond, var1, var2)
Definition: utlCoreMacro.h:557
bool IsSameVector(const std::vector< T > &vec1, const std::vector< T > &vec2, const double eps=1e-10)
Definition: utlCore.h:1365
std::vector< int > GetVectorImage3DVolumeSize(const SmartPointer< ImageType > &image)
Definition: utlITK.h:331
int main(int argc, char const *argv[])
Print image.
Definition: PrintImage.cxx:340
bool IsOutsideBox(const IndexType &index, const std::vector< int > &box)
Definition: PrintImage.cxx:57
void GetVector(PixelVectorType &vec, const int offIndex=0) const
int GetVectorImageVectorSize(const SmartPointer< ImageType > &image, const int axis=-1)
Definition: utlITK.h:278
void PrintVector(const std::vector< T > &vec, const std::string &str="", const char *separate=" ", std::ostream &os=std::cout, bool showStats=true)
Definition: utlCore.h:1002
void ConvertTensor6DTo9D(const V1Type &v6d, V2Type &v9d, int v6dStoreWay)
Definition: utlDMRI.h:257
itk::SpatiallyDenseSparseVectorImage< ScalarType, 3 > SparseImageType
Definition: PrintImage.cxx:29
void VectorToMultiVolumeImage(const SmartPointer< VectorImage< ScalarType, Dim > > &image1, SmartPointer< Image< ScalarType, Dim+1 > > &image2)
itk::Image< ScalarType, 4 > NDImageType
Definition: PrintImage.cxx:28
An n-dimensional vector image with a sparse memory model.
A multi-dimensional iterator templated over image type. It provides the same interfaces for both itk:...