I invoke the program with:<br><br>./DeformableRegistration &quot;param.file&quot; &quot;m000-talairach.dcm&quot; &quot;/trumpet/downloads/DeformableRegistration_Plugin/DeformableRegistration/datasubject&quot;<br><br>where the last item on the list is the name of the directory containing the dicom series.<br>
<br>john<br><br><div class="gmail_quote">On Tue, Oct 6, 2009 at 10:07 AM, John Drozd <span dir="ltr">&lt;<a href="mailto:john.drozd@gmail.com">john.drozd@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi Bill,<br><br>Yes, I did read in the original DICOM series into 3D Slicer and the original series was not flipped and fine.  I was checking if ITK had read the series correctly into memory, so I wrote it to a volume. I was writing the volume out to see what was in memory and when I viewed the outputted volume in 3D Slicer it was flipped.  In this case, I was basing my code on Examples/IO/DicomSeriesReadImageWrite2.cxx<br>

I plan to today read in the series and write it to a series (instead of a volume) and see if the outputted series will be flipped (hopefully not) when I view it in 3D Slicer.<br>By the way, as shown in Examples/IO/DicomImageReadWrite.cxx, I did read in a dicom volume (a single file containing the talairach atlas) and wrote it out to another dicom volume and the outputted volume this time was not flipped when I viewed it in 3D Slicer.<br>

<br>Below is my code that I used for reading a dicom series and writing to a volume:<br>(It is part of a deformable registration program that I am writing based on Examples/Registration/DeformableRegistration1.cxx so there are some header files and code from that)<br>

<span style="color: rgb(255, 0, 0);">The pertinent reading and writing code is in red.</span> (about 60 lines down)<br style="color: rgb(255, 0, 0);"><br><br>#if defined(_MSC_VER)<br>#pragma warning ( disable : 4786 )<br>

#endif<br><br><br>#include &quot;itkImageFileReader.h&quot; <br>#include &quot;itkImageFileWriter.h&quot; <br><br>#include &quot;itkRescaleIntensityImageFilter.h&quot;<br>#include &quot;itkHistogramMatchingImageFilter.h&quot;<br>

<br>//Added from DicomImageReadWrite.cxx<br>#include &quot;itkGDCMImageIO.h&quot;<br><br>//Added from DicomSeriesReadImageWrite2.cxx<br>#include &quot;itkOrientedImage.h&quot;<br>#include &quot;itkGDCMImageIO.h&quot;<br>
#include &quot;itkGDCMSeriesFileNames.h&quot;<br>
#include &quot;itkImageSeriesReader.h&quot;<br><br>#include &quot;itkFEM.h&quot;<br>#include &quot;itkFEMRegistrationFilter.h&quot;<br><br>//  Next, we use \code{typedef}s to instantiate all necessary classes.  We<br>//  define the image and element types we plan to use to solve a<br>

//  two-dimensional registration problem.  We define multiple element<br>//  types so that they can be used without recompiling the code.<br>//<br>//<br>//  Note that in order to solve a three-dimensional registration<br>

//  problem, we would simply define 3D image and element types in lieu<br>//  of those above.  The following declarations could be used for a 3D<br>//  problem:<br><br>typedef itk::Image&lt;short, 3&gt;                    fileImage3DType;<br>

typedef itk::Image&lt;short, 3&gt;                            Image3DType;<br><br>typedef itk::fem::Element3DC0LinearHexahedronMembrane   Element3DType;<br>typedef itk::fem::Element3DC0LinearTetrahedronMembrane  Element3DType2;<br>

<br>//  Here, we instantiate the load types and explicitly template the<br>//  load implementation type.  We also define visitors that allow the<br>//  elements and loads to communicate with one another.<br><br>typedef itk::fem::FiniteDifferenceFunctionLoad&lt;Image3DType,Image3DType&gt; ImageLoadType;<br>

template class itk::fem::ImageMetricLoadImplementation&lt;ImageLoadType&gt;;<br><br>typedef Element3DType::LoadImplementationFunctionPointer     LoadImpFP;<br>typedef Element3DType::LoadType                              ElementLoadType;<br>

<br>typedef Element3DType2::LoadImplementationFunctionPointer    LoadImpFP2;<br>typedef Element3DType2::LoadType                             ElementLoadType2;<br><br>typedef itk::fem::VisitorDispatcher&lt;Element3DType,ElementLoadType, LoadImpFP&gt;   <br>

                                                           DispatcherType;<br><br>typedef itk::fem::VisitorDispatcher&lt;Element3DType2,ElementLoadType2, LoadImpFP2&gt;   <br>                                                           DispatcherType2;<br>

<br>//  Once all the necessary components have been instantiated, we can<br>//  instantiate the \doxygen{FEMRegistrationFilter}, which depends on the<br>//  image input and output types.<br><br>typedef itk::fem::FEMRegistrationFilter&lt;Image3DType,Image3DType&gt; RegistrationType;<br>

<br>int main(int argc, char *argv[])<br>{<br>  char *paramname;<br>  if ( argc &lt; 2 )<br>    {<br>    std::cout &lt;&lt; &quot;Parameter file name missing&quot; &lt;&lt; std::endl;<br>    std::cout &lt;&lt; &quot;Usage: &quot; &lt;&lt; argv[0] &lt;&lt; &quot; param.file&quot; &lt;&lt; &quot; atlas.file&quot; &lt;&lt; &quot; subject.file&quot; &lt;&lt;std::endl;<br>

    return EXIT_FAILURE;<br>    } <br>  else <br>    { <br>    paramname=argv[1]; <br>    }<br><br>//  The \doxygen{fem::ImageMetricLoad} must be registered before it<br>//  can be used correctly with a particular element type.  An example<br>

//  of this is shown below for ElementType.  Similar<br>//  definitions are required for all other defined element types.<br><br><br>// Register the correct load implementation with the element-typed visitor dispatcher. <br>

  {<br>//  Software Guide : BeginCodeSnippet<br>  Element3DType::LoadImplementationFunctionPointer fp = <br>    &amp;itk::fem::ImageMetricLoadImplementation&lt;ImageLoadType&gt;::ImplementImageMetricLoad;<br>  DispatcherType::RegisterVisitor((ImageLoadType*)0,fp);<br>

//  Software Guide : EndCodeSnippet  <br>  }<br>  {<br>  Element3DType2::LoadImplementationFunctionPointer fp =<br>    &amp;itk::fem::ImageMetricLoadImplementation&lt;ImageLoadType&gt;::ImplementImageMetricLoad;<br>  DispatcherType2::RegisterVisitor((ImageLoadType*)0,fp);<br>

  }<br><br>//  In order to begin the registration, we declare an instance of the<br>//  FEMRegistrationFilter.  For simplicity, we will call<br>//  it \code{registrationFilter}.<br><br>  RegistrationType::Pointer registrationFilter = RegistrationType::New();<br>

<br>  <span style="color: rgb(255, 0, 0);">typedef short InputPixelType;</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">  const unsigned int   InputDimension = 3;</span><br style="color: rgb(255, 0, 0);">

<br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">  typedef itk::Image&lt; InputPixelType, InputDimension &gt; InputImageType;</span><br style="color: rgb(255, 0, 0);"><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">  typedef itk::ImageSeriesReader&lt; InputImageType &gt; ReaderSeriesType;</span><br style="color: rgb(255, 0, 0);"><br style="color: rgb(255, 0, 0);"><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">  ReaderSeriesType::Pointer fixedsubjectfilter = ReaderSeriesType::New();</span><br style="color: rgb(255, 0, 0);"><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);"> typedef itk::GDCMImageIO           ImageIOType;</span><br style="color: rgb(255, 0, 0);">

<br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">  ImageIOType::Pointer gdcmImageIO = ImageIOType::New();</span><br style="color: rgb(255, 0, 0);"><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">fixedsubjectfilter-&gt;SetImageIO( gdcmImageIO );</span><br style="color: rgb(255, 0, 0);">

<br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">typedef itk::GDCMSeriesFileNames NamesGeneratorType;</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">  NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();</span><br style="color: rgb(255, 0, 0);">

<br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">  nameGenerator-&gt;SetUseSeriesDetails( true );</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">  nameGenerator-&gt;AddSeriesRestriction(&quot;0008|0021&quot; );</span><br style="color: rgb(255, 0, 0);">

<br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">  nameGenerator-&gt;SetDirectory( argv[3] );</span><br style="color: rgb(255, 0, 0);"><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">try</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">    {</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    std::cout &lt;&lt; std::endl &lt;&lt; &quot;The directory: &quot; &lt;&lt; std::endl;</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">    std::cout &lt;&lt; std::endl &lt;&lt; argv[3] &lt;&lt; std::endl &lt;&lt; std::endl;</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    std::cout &lt;&lt; &quot;Contains the following DICOM Series: &quot;;</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">    std::cout &lt;&lt; std::endl &lt;&lt; std::endl;</span><br style="color: rgb(255, 0, 0);"><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">typedef std::vector&lt; std::string &gt;    SeriesIdContainer;</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">    </span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    const SeriesIdContainer &amp; seriesUID = nameGenerator-&gt;GetSeriesUIDs();</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">    </span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    //std::cout &lt;&lt; seriesUID.begin() &lt;&lt; endl;</span><br style="color: rgb(255, 0, 0);"><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">    SeriesIdContainer::const_iterator seriesItr = seriesUID.begin();</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    SeriesIdContainer::const_iterator seriesEnd = seriesUID.end();</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">    while( seriesItr != seriesEnd )</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      {</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      std::cout &lt;&lt; seriesItr-&gt;c_str() &lt;&lt; std::endl;</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">      seriesItr++;</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      }</span><br style="color: rgb(255, 0, 0);"><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">std::string seriesIdentifier;</span><br style="color: rgb(255, 0, 0);">

<br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    if( argc &gt; 4 ) // If no optional series identifier</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      {</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">      seriesIdentifier = argv[3];</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      }</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    else</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">      {</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      seriesIdentifier = seriesUID.begin()-&gt;c_str();</span><br style="color: rgb(255, 0, 0);">
<span style="color: rgb(255, 0, 0);">      }</span><br style="color: rgb(255, 0, 0);">
<br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">std::cout &lt;&lt; std::endl &lt;&lt; std::endl;</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    std::cout &lt;&lt; &quot;Now reading series: &quot; &lt;&lt; std::endl &lt;&lt; std::endl;</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">    std::cout &lt;&lt; seriesIdentifier &lt;&lt; std::endl;</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    std::cout &lt;&lt; std::endl &lt;&lt; std::endl;</span><br style="color: rgb(255, 0, 0);">

<br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">typedef std::vector&lt; std::string &gt;   FileNamesContainer;</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    FileNamesContainer fileNames;</span><br style="color: rgb(255, 0, 0);">

<br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    fileNames = nameGenerator-&gt;GetFileNames( seriesIdentifier );</span><br style="color: rgb(255, 0, 0);"><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">fixedsubjectfilter-&gt;SetFileNames( fileNames );</span><br style="color: rgb(255, 0, 0);">

<br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">try</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      {</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      fixedsubjectfilter-&gt;Update();</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">      std::cout &lt;&lt; &quot;Subject read successfully&quot;  &lt;&lt; std::endl;</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      }</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">    catch (itk::ExceptionObject &amp;ex)</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      {</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      std::cout &lt;&lt; ex &lt;&lt; std::endl;</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">      return EXIT_FAILURE;</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      }</span><br style="color: rgb(255, 0, 0);"><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">typedef itk::ImageFileWriter&lt; InputImageType &gt; WriterSubjectType;</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">  </span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">  WriterSubjectType::Pointer fixedsubjectfilterwriter = WriterSubjectType::New();</span><br style="color: rgb(255, 0, 0);"><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">fixedsubjectfilterwriter-&gt;SetFileName( &quot;subjectout.dcm&quot; );</span><br style="color: rgb(255, 0, 0);">

<br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">fixedsubjectfilterwriter-&gt;SetInput( fixedsubjectfilter-&gt;GetOutput() );</span><br style="color: rgb(255, 0, 0);"><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">try</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      {</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      fixedsubjectfilterwriter-&gt;Update();</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">      }</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    catch (itk::ExceptionObject &amp;ex)</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      {</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">      std::cout &lt;&lt; ex &lt;&lt; std::endl;</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">      return EXIT_FAILURE;</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">      }</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    }</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">  catch (itk::ExceptionObject &amp;ex)</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">    {</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    std::cout &lt;&lt; ex &lt;&lt; std::endl;</span><br style="color: rgb(255, 0, 0);"><span style="color: rgb(255, 0, 0);">    return EXIT_FAILURE;</span><br style="color: rgb(255, 0, 0);">

<span style="color: rgb(255, 0, 0);">    }</span><br><br><br><br>return EXIT_SUCCESS;<br>}<br><font color="#888888"><br><br>john</font><div><div></div><div class="h5"><br><br><div class="gmail_quote">On Mon, Oct 5, 2009 at 7:09 PM, Bill Lorensen <span dir="ltr">&lt;<a href="mailto:bill.lorensen@gmail.com" target="_blank">bill.lorensen@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">3D Slicer can read the DICOM directly. It will use the direction<br>
information properly. Why are you reading and writing it? I am<br>
suprised (and concerned) that 3D SLicer would flip the images.<br>
<br>
Bill<br>
<div><div></div><div><br>
On Mon, Oct 5, 2009 at 6:13 PM, John Drozd &lt;<a href="mailto:john.drozd@gmail.com" target="_blank">john.drozd@gmail.com</a>&gt; wrote:<br>
&gt; Hello,<br>
&gt;<br>
&gt; I am reading a brain subject in the form of a DICOM series using ITK and<br>
&gt; writing it out from memory as a volume.<br>
&gt; I used the method shown in Examples/IO/DicomSeriesReadImageWrite2.cxx<br>
&gt; I viewed the original DICOM series in 3D Slicer, and also viewed the<br>
&gt; outputted volume in 3D Slicer.<br>
&gt; I am using 3D Slicer because I am developing a segmentation module for 3D<br>
&gt; Slicer using ITK.<br>
&gt; I noticed that the original DICOM series and the outputted volume are<br>
&gt; inverted in orientation, such that the original series is the radiologist<br>
&gt; view and the outputted volume is the neurosurgean view as per<br>
&gt; <a href="http://www.itk.org/pipermail/insight-users/2009-June/031128.html" target="_blank">http://www.itk.org/pipermail/insight-users/2009-June/031128.html</a> and<br>
&gt; <a href="http://www.itk.org/Wiki/Proposals:Orientation#DICOM_LPS_Differences_in_Visualization_presented_to_Radiologist_and_NeuroSurgeons" target="_blank">http://www.itk.org/Wiki/Proposals:Orientation#DICOM_LPS_Differences_in_Visualization_presented_to_Radiologist_and_NeuroSurgeons</a><br>


&gt;<br>
&gt; Does this have something to do with what I read on the internet that vtk&#39;s<br>
&gt; images are flipped vertically from itk&#39;s images?<br>
&gt; Is there a way to manipulate the image in memory using ITK so that Slicer<br>
&gt; will display the outputted volume in the same radiologist orientation as the<br>
&gt; original DICOM series?<br>
&gt;<br>
&gt; Thank you.<br>
&gt;<br>
&gt; john<br>
&gt;<br>
&gt; --<br>
&gt; John Drozd<br>
&gt; Postdoctoral Fellow<br>
&gt; Imaging Research Laboratories<br>
&gt; Robarts Research Institute<br>
&gt; Room 1256<br>
&gt; 100 Perth Drive<br>
&gt; London, Ontario, Canada<br>
&gt; N6A 5K8<br>
&gt; (519) 661-2111 ext. 25306<br>
&gt;<br>
</div></div>&gt; _____________________________________<br>
&gt; Powered by <a href="http://www.kitware.com" target="_blank">www.kitware.com</a><br>
&gt;<br>
&gt; Visit other Kitware open-source projects at<br>
&gt; <a href="http://www.kitware.com/opensource/opensource.html" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
&gt;<br>
&gt; Please keep messages on-topic and check the ITK FAQ at:<br>
&gt; <a href="http://www.itk.org/Wiki/ITK_FAQ" target="_blank">http://www.itk.org/Wiki/ITK_FAQ</a><br>
&gt;<br>
&gt; Follow this link to subscribe/unsubscribe:<br>
&gt; <a href="http://www.itk.org/mailman/listinfo/insight-users" target="_blank">http://www.itk.org/mailman/listinfo/insight-users</a><br>
&gt;<br>
&gt;<br>
</blockquote></div><br><br clear="all"><br></div></div>-- <br><div><div></div><div class="h5">John Drozd<br>Postdoctoral Fellow<br>Imaging Research Laboratories<br>Robarts Research Institute<br>Room 1256<br>100 Perth Drive<br>
London, Ontario, Canada<br>N6A 5K8<br>
(519) 661-2111 ext. 25306<br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>John Drozd<br>Postdoctoral Fellow<br>Imaging Research Laboratories<br>Robarts Research Institute<br>Room 1256<br>100 Perth Drive<br>London, Ontario, Canada<br>
N6A 5K8<br>(519) 661-2111 ext. 25306<br>