Hi Antoine,<br><br>probably I had the same problem with DICOM converted in NIFTI using MIPAV (<a href="http://mipav.cit.nih.gov/">http://mipav.cit.nih.gov/</a>). <br>I solved the problem flipping and shifting the NIFTI file:<br>
<br>int main( int argc, char ** argv )<br>{<br> typedef short PixelType;<br> const unsigned int Dimension = 3;<br><br> typedef itk::OrientedImage< PixelType, Dimension > ImageType;<br><br> typedef itk::ImageFileReader< ImageType > ReaderType;<br>
typedef itk::ImageFileWriter< ImageType > WriterType;<br><br> ReaderType::Pointer reader = ReaderType::New();<br> WriterType::Pointer writer = WriterType::New();<br><br> const char * inputFilename = argv[1];<br>
const char * outputFilename = argv[2];<br><br> reader->SetFileName( inputFilename );<br> writer->SetFileName( outputFilename );<br><br>reader->Update();<br>reader->GetOutput()->Print(std::cout);<br><br>typedef itk::FlipImageFilter< ImageType> FlipType;<br>
FlipType::Pointer flip = FlipType::New();<br><br> FlipType::FlipAxesArrayType flipAxesSet;<br><br> flipAxesSet[0] = 0;<br> flipAxesSet[1] = -1;<br> flipAxesSet[2] = 0;<br><br> flip->SetFlipAxes(flipAxesSet);<br> flip->FlipAboutOriginOff();<br>
flip->SetInput(reader->GetOutput());<br> flip->Update();<br> flip->GetOutput()->Print(std::cout);<br><br>ImageType::Pointer image = ImageType::New();<br> image = flip->GetOutput();<br> image->SetOrigin(reader->GetOutput()->GetOrigin());<br>
image->Print(std::cout);<br><br> writer->SetInput(image);<br>}<br><br>In this way if I read the original DICOM with itk I obtain:<br><br>TransformMatrix = 1 0 0 0 1 0 0 0 1<br>Offset = -250 -250 -515.03<br>AnatomicalOrientation = RAI <br>
<br>The NIFTI image converted using MIPAV is:<br><br>TransformMatrix = 1 0 0 0 -1 0 0 0 1<br>Offset = -250 -250 -515.03<br>AnatomicalOrientation = RPI<br><br>While the NIFTI image after flip and shif is:<br><br>TransformMatrix = 1 0 0 0 1 0 0 0 1<br>
Offset = -250 -250 -515.03<br>AnatomicalOrientation = RAI<br><br>Also, if I use Paraview to see the images (after a conversion in .mhd format) the original and the flipped and shifted one are consistent (are the same) while the other (NIFTI from MIPAV) has a wrong position and orientation.<br>
<br>I hope this could help you...<br><br>Elena<br><br><br><br><br>> From: Luis Ibanez <<a href="mailto:luis.ibanez@kitware.com">luis.ibanez@kitware.com</a>><br>> Subject: Re: [Insight-users] Nifti vs Dicom orientation<br>
><br>> Hi Antoine,<br>><br>> Thanks for looking at the original image orientation.<br>><br>> It seems that the problem lies in the interpretation<br>> of orientation in the Nii file...<br>> or... it may be a bug in dcm2nii...<br>
><br>><br>> I would suggest to post the question about the assumed<br>> orientation of the Nifti file format to the Nifti forum:<br>><br>> <a href="http://nifti.nimh.nih.gov/board/list.php?f=1">http://nifti.nimh.nih.gov/board/list.php?f=1</a><br>
><br>> Of course, we will be interested in learning about their<br>> reply.<br>><br>> It may mean that we need to modify the NiftiImageIO<br>> class in ITK...<br>><br>><br>> ---<br>><br>> On the other hand, please note that in practice you don't<br>
> need to use "dcm2nii" since you can achieve exactly the<br>> same goal by runing the example:<br>><br>><br>> Insight/Examples/IO<br>> DicomSeriesReadImageWrite2.cxx<br>><br>> (reading DICOM and saving it as a nifti file).<br>
><br>> Which should give you a consistent set of orientations.<br>><br>><br>> Thanks<br>><br>><br>> Luis<br>><br>><br>> ------------------------<br>> Antoine DUCHAMPS wrote:<br>
>> Hi Luis,<br>>><br>>> I've read the original DICOM with ITK and I've obtained exactly the same<br>>> direction cosines:<br>>><br>>> 0.9997 0.0000 0.0252<br>>> 0.0002 1.0000 -0.0072<br>
>> -0.0252 0.0072 0.9997<br>>><br>>> So, should I assume a LAS orientation in nii image? (even when the<br>>> standard is RAS)<br>>><br>>> Antoine.<br>>><br>>><br>>><br>
>> Le lundi 06 avril 2009 ? 11:47 -0400, Luis Ibanez a ?crit :<br>>><br>>>>Hi Antoine,<br>>>><br>>>>Could you please read the original DICOM series with ITK and<br>>>>report the Direction that you get from the ITK image in that case ?<br>
>>><br>>>><br>>>><br>>>>In this way we will be able to figure out if the problem is in<br>>>><br>>>><br>>>>A) the conversion from DICOM to Nifti as processed by "dcm2nii"<br>
>>><br>>>> or<br>>>><br>>>>B) the process of reading the nifti file with itkNiftiImageIo.<br>>>><br>>>><br>>>>Please post to the list the Direction cosines that you obtain<br>
>>>when your read the original DICOM series with ITK.<br>>>><br>>>><br>>>> Thanks<br>>>><br>>>><br>>>> Luis<br>>>><br>>>><br>>>>-----------------<br>
>>>On Mon, Apr 6, 2009 at 10:46 AM, Antoine DUCHAMPS<br>>>><<a href="mailto:antoine.duchamps@gmail.com">antoine.duchamps@gmail.com</a>> wrote:<br>>>><br>>>>>Hi all,<br>>>>><br>
>>>>I have a DWI sequence (brain) acquired with a Siemens scanner in Dicom<br>>>>>format. After converting it to NIfTI with dcm2nii<br>>>>>(<a href="http://www.sph.sc.edu/comd/rorden/mricron/dcm2nii.html">http://www.sph.sc.edu/comd/rorden/mricron/dcm2nii.html</a>) I tried to read<br>
>>>>it an recover the orientation by using ITK (I've copied the code below).<br>>>>>The matrix I obtain is the following:<br>>>>><br>>>>> 0.9997 0.0000 0.0252<br>>>>> 0.0002 -1.0000 -0.0072<br>
>>>>-0.0252 -0.0072 0.9997<br>>>>><br>>>>>However, the transforation matrix in the Dicom header is<br>>>>><br>>>>> 0.9997 0.0000 0.0252<br>>>>> 0.0002 1.0000 -0.0072<br>
>>>>-0.0252 0.0072 0.9997<br>>>>><br>>>>>If the Dicom image orientation is LPS, this means that the image<br>>>>>orientation in NIfTI is LAS (And not RAS as I believed). Could anybody<br>
>>>>clarify this please? Are there several possible orientations in NIfTI?<br>>>>>If so, how can I know the specific image orientation?<br>>>>><br>>>>>Antoine.<br>>>>><br>
>>>><br>>>>>#include "itkImageFileReader.h"<br>>>>>#include "itkOrientedImage.h"<br>>>>><br>>>>>const unsigned int Dimension = 4;<br>>>>>typedef short PixelType;<br>
>>>>typedef itk::OrientedImage<PixelType, Dimension> ImageType;<br>>>>>typedef ImageType::Pointer ImagePointerType;<br>>>>>typedef itk::ImageFileReader< ImageType > ReaderType;<br>
>>>><br>>>>><br>>>>>int main(int argc, char* argv[])<br>>>>>{<br>>>>><br>>>>> ImageType::Pointer image = ImageType::New();<br>>>>><br>>>>> ReaderType::Pointer reader = ReaderType::New();<br>
>>>> reader->SetFileName(argv[1]);<br>>>>> reader->Update();<br>>>>><br>>>>> image = reader -> GetOutput();<br>>>>> std::cout << image->GetDirection() << std::endl; std::cout.flush();<br>
>>>><br>>>>>}<br>>>>><br>>>>>_____________________________________<br>>>>>Powered by <a href="http://www.kitware.com">www.kitware.com</a><br>>>>><br>
>>>>Visit other Kitware open-source projects at<br>>>>><a href="http://www.kitware.com/opensource/opensource.html">http://www.kitware.com/opensource/opensource.html</a><br>>>>><br>>>>>Please keep messages on-topic and check the ITK FAQ at: <a href="http://www.itk.org/Wiki/ITK_FAQ">http://www.itk.org/Wiki/ITK_FAQ</a><br>
>>>><br>>>>>Follow this link to subscribe/unsubscribe:<br>>>>><a href="http://www.itk.org/mailman/listinfo/insight-users">http://www.itk.org/mailman/listinfo/insight-users</a><br>>>>><br>
>><br>>><br>>><br>><br>><br>> ------------------------------<br>><br>> Message: 2<br>> Date: Wed, 8 Apr 2009 15:04:43 -0400<br>> From: Bradley Lowekamp <<a href="mailto:blowekamp@mail.nih.gov">blowekamp@mail.nih.gov</a>><br>
> Subject: Re: [Insight-users] Visible Human Dataset<br>> To: Zein Salah <<a href="mailto:salah@gris.uni-tuebingen.de">salah@gris.uni-tuebingen.de</a>><br>> Cc: ITK Users <<a href="mailto:insight-users@itk.org">insight-users@itk.org</a>><br>
> Message-ID: <<a href="mailto:30DAA271-C7D3-4C09-A11C-3D015A1B0CB9@mail.nih.gov">30DAA271-C7D3-4C09-A11C-3D015A1B0CB9@mail.nih.gov</a>><br>> Content-Type: text/plain; charset="us-ascii"; Format="flowed";<br>
> DelSp="yes"<br>><br>> Hello Zein,<br>><br>> You can find all the information for the original data here:<br>><br>> <a href="http://www.nlm.nih.gov/research/visible/visible_human.html">http://www.nlm.nih.gov/research/visible/visible_human.html</a><br>
> <a href="http://www.nlm.nih.gov/research/visible/getting_data.html">http://www.nlm.nih.gov/research/visible/getting_data.html</a><br>><br>> The uncompressed Fullcolor slices are 7471104 bytes. The original data<br>
> on the ftp is losslessly "Z" compress, but the sizes of these files<br>> very. They are originally named a_vm1001.raw.Z to a_vm2878.raw.Z<br>><br>> Then the radiological frozenCT data is name c_vm1006.fro.Z to<br>
> c_vm2882.fro.Z when they are decompressed they are only 527704 bytes.<br>><br>> As your data does not match any of the original data, it has likely<br>> been processed some how. Hopefully there is information contained in<br>
> the .inf file to help you.<br>><br>> Good luck,<br>> Brad<br>><br>><br>> On Apr 7, 2009, at 4:37 PM, Zein Salah wrote:<br>><br>>> Hello all,<br>>><br>>> I have a copy of the Visible Human data (colored, male) which I<br>
>> downloaded some years ago. I am trying now to read it using itk. I<br>>> found information how to generate a .mhd file for the raw images<br>>> that I have. My problem is that I do not any more know the<br>
>> specification of the data, i.e. resolution, pixel type, etc.<br>>><br>>> The data look like this:<br>>><br>>> - There are raw files named as follows: c_vm1006.raw,<br>>> c_vm1007.raw, ..., c_vm2882.raw.<br>
>> - There is a file named vismale_fro.inf<br>>> - The size of each raw file is exactly 4,980,736 bytes<br>>><br>>> Does any body have this data? Can somebody help me identifying the<br>>> specification of the data that I have, probably with a suitable .mhd<br>
>> file?<br>>><br>>> Much thanks,<br>>><br>>> Zein<br>>> <ATT00001.txt><br>><br>> ========================================================<br>> Bradley Lowekamp<br>> Lockheed Martin Contractor for<br>
> Office of High Performance Computing and Communications<br>> National Library of Medicine<br>> <a href="mailto:blowekamp@mail.nih.gov">blowekamp@mail.nih.gov</a><br>><br>><br>> -------------- next part --------------<br>
> An HTML attachment was scrubbed...<br>> URL: <<a href="http://www.itk.org/pipermail/insight-users/attachments/20090408/891c8f3c/attachment-0001.htm">http://www.itk.org/pipermail/insight-users/attachments/20090408/891c8f3c/attachment-0001.htm</a>><br>
><br>> ------------------------------<br>><br>> Message: 3<br>> Date: Wed, 8 Apr 2009 23:29:09 -0400<br>> From: Geoff Topping <<a href="mailto:g_topping@hotmail.com">g_topping@hotmail.com</a>><br>> Subject: [Insight-users] ResampleImageFilter Producing Garbled Output<br>
> When Image Size Changed<br>> To: <<a href="mailto:insight-users@itk.org">insight-users@itk.org</a>><br>> Message-ID: <COL104-W51D457E7BFA5B25CF998B58C830@phx.gbl><br>> Content-Type: text/plain; charset="iso-8859-1"<br>
><br>><br>> Hi.<br>><br>> I'm trying to use ResampleImageFilter to resize, crop or expand the volume of an image using ITK. My input image is 128x128x95 voxels with spacings of 0.865759x0.865759x0.796, 16-bit signed integer Analyze75 format.<br>
><br>> When I use the following code (see full listing below for context) to set the output image size and scaling, things work fine, and I get back an image very similar to my input image (although stored as floats instead of signed ints, and with the calibration factor ignored by the casting between formats):<br>
><br>> resampleFilter->SetSize( inputImage->GetLargestPossibleRegion().GetSize());<br>> resampleFilter->SetOutputOrigin( inputImage->GetOrigin());<br>> resampleFilter->SetOutputSpacing( inputImage->GetSpacing());<br>
><br>> When I switch to using hard coded image size and spacings (128x128x95 and 0.865759x0.865759x0.796), I also get an effectively identical output image:<br>><br>> double spacing[] = {0.865759, 0.865759, 0.796};<br>
> resampleFilter->SetOutputSpacing(spacing);<br>><br>> double origin[] = {0.0, 0.0, 0.0};<br>> resampleFilter->SetOutputOrigin(origin);<br>><br>> ImageType::SizeType size = {128, 128, 95};<br>
> resampleFilter->SetSize(size);<br>><br>> However, if I change the hard-coded image size, I get garbled output. Setting hard-coded size to 256x256x190, with or without dividing all the spacings by 2.0 results in most, but not all, of the slices of the resulting image being quite garbled, with apparent tilings of a few slices over and over, occasional mirroring of a series of slices, or what looks like the early frames of a high-speed camera observing an exploding object, instead of the original image contents. Examining the resulting images, I see four copies of the (distorted) image in some of the transverse slices, tiled ul, ur, ll, lr. In other slice orientations I see two or four tiled copies in a row.<br>
><br>> Any ideas what might be going wrong or how I can fix or debug this?<br>><br>> Thanks,<br>> Geoff Topping<br>><br>><br>> My current code:<br>><br>><br>> The program takes two filenames from the command line: input image and output image file name. It reads the input image, applies an identity transform while resampling, and outputs the resulting image.<br>
><br>> ***********************************************************************<br>><br>> #include "itkVersorRigid3DTransform.h"<br>> #include "itkIdentityTransform.h"<br>><br>> #include "itkNearestNeighborInterpolateImageFunction.h"<br>
> #include "itkLinearInterpolateImageFunction.h"<br>><br>> #include "itkImage.h"<br>> #include "itkImageFileReader.h"<br>> #include "itkImageFileWriter.h"<br>><br>
> #include "itkResampleImageFilter.h"<br>> #include "itkShiftScaleImageFilter.h"<br>><br>><br>> #include "vcl_cmath.h"<br>><br>> namespace {<br>> const unsigned int Dimension = 3;<br>
> typedef float PixelType;<br>> typedef itk::Image<PixelType, Dimension> ImageType;<br>> typedef itk::ImageFileReader<ImageType> ImageReaderType;<br>
> typedef itk::ImageFileWriter<ImageType> ImageWriterType;<br>><br>> typedef itk::VersorRigid3DTransform<double> RigidTransformType;<br>> typedef itk::IdentityTransform<double, Dimension> IdentityTransformType;<br>
> typedef IdentityTransformType TransformType;<br>><br>> typedef itk::LinearInterpolateImageFunction<ImageType, double> LinearInterpolatorType;<br>> typedef itk::NearestNeighborInterpolateImageFunction<<br>
> ImageType, double> NearestInterpolatorType;<br>> typedef NearestInterpolatorType InterpolatorType;<br>><br>> typedef itk::ResampleImageFilter<ImageType, ImageType> ResampleFilterType;<br>
> }<br>><br>><br>> int main( int argc, char *argv[] ) {<br>> if( argc < 2 ) {<br>> std::cerr << "Missing Parameters " << std::endl;<br>> std::cerr << "Usage: " << argv[0] << " fixedImageFile movingImageFile outputImagefile" << std::endl;<br>
> return EXIT_FAILURE;<br>> }<br>><br>><br>> ImageReaderType::Pointer imageReader = ImageReaderType::New();<br>> imageReader->SetFileName(argv[1]);<br>> imageReader->Update();<br>
><br>><br>> TransformType::Pointer transform = TransformType::New();<br>><br>> InterpolatorType::Pointer interpolator = InterpolatorType::New();<br>><br>><br>> ImageType::Pointer inputImage = imageReader->GetOutput();<br>
><br>><br>> ResampleFilterType::Pointer resampleFilter = ResampleFilterType::New();<br>> resampleFilter->SetInput( inputImage);<br>> resampleFilter->SetTransform( transform);<br>
> resampleFilter->SetInterpolator( interpolator);<br>> resampleFilter->SetDefaultPixelValue( 0);<br>> resampleFilter->SetOutputDirection( inputImage->GetDirection());<br>><br>
><br>> #ifdef FROM_INPUT<br>> resampleFilter->SetSize( inputImage->GetLargestPossibleRegion().GetSize());<br>> resampleFilter->SetOutputOrigin( inputImage->GetOrigin());<br>
> resampleFilter->SetOutputSpacing( inputImage->GetSpacing());<br>> #endif<br>><br>> #ifdef PRINT_INPUT_STUFF<br>> const ImageType::SpacingType& inputImageSpacing = inputImage->GetSpacing();<br>
> std::cout << "input image spacings: " << inputImageSpacing[0] << ", "<br>> << inputImageSpacing[1] << ", "<br>
> << inputImageSpacing[2] << std::endl;<br>><br>> const ImageType::PointType& inputImageOrigin = inputImage->GetOrigin();<br>> std::cout << "input image origin: " << inputImageOrigin[0] << ", "<br>
> << inputImageOrigin[1] << ", "<br>> << inputImageOrigin[2] << std::endl;<br>><br>> const ImageType::SizeType& inputImageSize = inputImage->GetLargestPossibleRegion().GetSize();<br>
> std::cout << "input image size: " << inputImageSize[0] << ", "<br>> << inputImageSize[1] << ", "<br>> << inputImageSize[2] << std::endl;<br>
> #endif<br>><br>> //#ifdef HARD_CODED<br>> double spacing[] = {0.865759, 0.865759, 0.796};<br>> resampleFilter->SetOutputSpacing(spacing);<br>><br>> double origin[] = {0.0, 0.0, 0.0};<br>
> resampleFilter->SetOutputOrigin(origin);<br>><br>> ImageType::SizeType size = {128, 128, 95};<br>> resampleFilter->SetSize(size);<br>> //#endif<br>><br>><br>> ImageWriterType::Pointer writer = ImageWriterType::New();<br>
> writer->SetFileName(argv[2]);<br>> writer->SetInput(resampleFilter->GetOutput());<br>><br>> try {<br>> writer->Update();<br>> } catch (itk::ExceptionObject& err) {<br>
> std::cerr << "ExceptionObject caught !" << std::endl;<br>> std::cerr << err << std::endl;<br>> return EXIT_FAILURE;<br>> }<br>><br>> return EXIT_SUCCESS;<br>
> }<br>><br>><br>> _________________________________________________________________<br>> Reinvent how you stay in touch with the new Windows Live Messenger.<br>> <a href="http://go.microsoft.com/?linkid=9650731">http://go.microsoft.com/?linkid=9650731</a><br>
> -------------- next part --------------<br>> An HTML attachment was scrubbed...<br>> URL: <<a href="http://www.itk.org/pipermail/insight-users/attachments/20090408/b8f41c60/attachment.htm">http://www.itk.org/pipermail/insight-users/attachments/20090408/b8f41c60/attachment.htm</a>><br>
><br>> ------------------------------<br>><br>> _______________________________________________<br>> Insight-users mailing list<br>> <a href="mailto:Insight-users@itk.org">Insight-users@itk.org</a><br>> <a href="http://www.itk.org/mailman/listinfo/insight-users">http://www.itk.org/mailman/listinfo/insight-users</a><br>
><br>><br>> End of Insight-users Digest, Vol 60, Issue 44<br>> *********************************************<br>><br><br>