<table cellspacing="0" cellpadding="0" border="0" ><tr><td valign="top" style="font: inherit;"><div>Thank you for clarifying your point,</div><div><br></div><div>Yes you are right, the itk::WarpImageFilter uses the deformation field to map a</div><div><br></div><div>point from the output space to the input space. This is basically resides in the difference</div><div><br></div><div>between a transformation and a warping, as in transformation a point from the input space</div><div><br></div><div>is mapped to the output space with no guarantees for back transformations or size&nbsp;</div><div><br></div><div>correspondence&nbsp;which is only natural since there are numerous types of transformations</div><div><br></div><div>with high levels of complexity and that would make it a fairly hard task to obtain the&nbsp;</div><div><br></div><div>inverse transformation (as you pointed out).</div><div><br></div><div>On the opposite side, the whole point of warping is
 to map points from the output space to</div><div><br></div><div>the input space, hence the itk::WarpImageFilter does its work with inverse mapping, this</div><div><br></div><div>also avoids creation of holes and overlaps in the output image.</div><div><br></div><div>Best regards,</div><div><br></div><div>Dawood</div><div><br></div><div><br></div>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;<div><br></div><div>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;<br><br>--- On <b>Tue, 5/24/11, Gao, Yi
 <i>&lt;gaoyi.cn@gmail.com&gt;</i></b> wrote:<br><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"><br>From: Gao, Yi &lt;gaoyi.cn@gmail.com&gt;<br>Subject: Re: question on itkWarpImageFilter<br>To: "Dawood Masslawi" &lt;davoud_zzz@yahoo.com&gt;<br>Cc: insight-users@itk.org<br>Date: Tuesday, May 24, 2011, 8:10 AM<br><br><div class="plainMail">Hi Dawood,<br><br>Thanks for the answer.<br><br>The reason I was asking is because that when previously dealing with<br>image transformation, I thought we need to know "where it is from"<br>from the transformation information, which tells "where to go".<br><br>For example, if image A is to be translated by 10 pixel to the RIGHT.<br>Then, we go through the new image, and for each pixel we find out<br>"where it is from": 10 pixel from the LEFT. Note in such cases, the<br>output image do NOT have to be the same size as the input one.<br>Moreover, if A is a simple binary
 image with an object in the center,<br>then in the transformed image, the object would appear to be a little<br>on the right (on the screen, and assuming the output region is the<br>same as the input one.)<br><br>Therefore I thought for transformation with general vector deformation<br>field, this would be the same. However getting the inverse transform<br>from a vector field is in general difficult. So I asked the previous<br>question.<br><br>However, for transformation with vector deformation field, it does not<br>seems to be working that way. The transformation information (vector<br>field) directly tells "where it is from". I did the following<br>experiment:<br><br>1. I generate a 2D image A of the width 100 and height 50. In the<br>middle (middle of the left-right) 1/3 region it has some content.<br><br>2. I generate a vector field D, the 1st component of each vector is<br>10, and the 2nd component is 0. Therefore I hope this vector field to<br>do
 the same as the translation above. And I expect the transformed<br>image, B, has the object moved to the RIGHT.<br><br>3. However, the result is opposites to that of the 2D Translation<br>Transformation. The object appears to the LEFT.<br><br>4. No problem, because this is consistent with the Software Guide:<br>p_in = p_out + deformationVector.<br><br>5. I think this confirms the behavior that the vector field tells<br>"where is from".<br><br>6. So seems that the we should say the deformation is defined on the<br>domain of the *output image*?<br><br><br><br>Here is my testing code:<br><br>#include "itkImage.h"<br>#include "itkImageFileWriter.h"<br>#include "itkWarpImageFilter.h"<br>#include "itkLinearInterpolateImageFunction.h"<br><br><br>template&lt;typename itkImage_t&gt;<br>typename itkImage_t::Pointer generate_image(int nx, int ny);<br><br>template&lt;typename deformation_t&gt;<br>typename deformation_t::Pointer generate_deformation_field(int nx,
 int ny);<br><br>template&lt;typename itkImage_t&gt;<br>void write_image(typename itkImage_t::Pointer im, std::string file_name);<br><br><br>int main( int argc, char * argv[] )<br>{<br>&nbsp; const&nbsp; &nbsp;&nbsp;&nbsp;unsigned int&nbsp;&nbsp;&nbsp;Dimension = 2;<br><br>&nbsp; typedef&nbsp;&nbsp;&nbsp;float VectorComponentType;<br>&nbsp; typedef&nbsp;&nbsp;&nbsp;itk::Vector&lt; VectorComponentType, Dimension &gt; VectorPixelType;<br>&nbsp; typedef&nbsp;&nbsp;&nbsp;itk::Image&lt; VectorPixelType,&nbsp; Dimension &gt;&nbsp;&nbsp;&nbsp;DeformationFieldType;<br><br>&nbsp; typedef&nbsp;&nbsp;&nbsp;unsigned char&nbsp; PixelType;<br>&nbsp; typedef&nbsp;&nbsp;&nbsp;itk::Image&lt; PixelType,&nbsp; Dimension &gt;&nbsp;&nbsp;&nbsp;ImageType;<br><br><br>&nbsp; int nx = 100;<br>&nbsp; int ny = 50;<br>&nbsp; ImageType::Pointer img = generate_image&lt;ImageType&gt;(nx, ny);<br><br>&nbsp; DeformationFieldType::Pointer deformationField
 =<br>generate_deformation_field&lt;DeformationFieldType&gt;(nx, ny);<br><br>&nbsp; typedef itk::LinearInterpolateImageFunction&lt; ImageType, double &gt;<br>InterpolatorType;<br>&nbsp; InterpolatorType::Pointer interpolator = InterpolatorType::New();<br><br>&nbsp; typedef itk::WarpImageFilter&lt; ImageType, ImageType,<br>DeformationFieldType&nbsp; &gt;&nbsp; FilterType;<br>&nbsp; FilterType::Pointer filter = FilterType::New();<br>&nbsp; filter-&gt;SetInterpolator( interpolator );<br>&nbsp; filter-&gt;SetOutputSpacing( deformationField-&gt;GetSpacing() );<br>&nbsp; filter-&gt;SetOutputOrigin(&nbsp; deformationField-&gt;GetOrigin() );<br>&nbsp; filter-&gt;SetOutputDirection(&nbsp; deformationField-&gt;GetDirection() );<br>&nbsp; filter-&gt;SetDeformationField( deformationField );<br>&nbsp; filter-&gt;SetInput( img );<br>&nbsp; filter-&gt;Update();<br><br>&nbsp; write_image&lt;ImageType&gt;(img, "a.nrrd");<br>&nbsp;
 write_image&lt;ImageType&gt;(filter-&gt;GetOutput(), "b.nrrd");<br>&nbsp; write_image&lt;DeformationFieldType&gt;(deformationField, "c.nrrd");<br><br>&nbsp; return EXIT_SUCCESS;<br>}<br><br>template&lt;typename itkImage_t&gt;<br>typename itkImage_t::Pointer generate_image(int nx, int ny)<br>{<br>&nbsp; typename itkImage_t::IndexType start = {{0, 0}};<br>&nbsp; typename itkImage_t::SizeType size = {{nx, ny}};<br><br>&nbsp; typename itkImage_t::RegionType region;<br>&nbsp; region.SetSize(size);<br>&nbsp; region.SetIndex(start);<br><br>&nbsp; typename itkImage_t::Pointer img = itkImage_t::New();<br>&nbsp; img-&gt;SetRegions(region);<br>&nbsp; img-&gt;Allocate();<br>&nbsp; img-&gt;FillBuffer(0);<br><br>&nbsp; for (int ix = nx/3; ix &lt; 2*nx/3; ++ix)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; for (int iy = 0; iy &lt; ny; ++iy)<br>&nbsp; &nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; typename itkImage_t::IndexType idx = {{ix,
 iy}};<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img-&gt;SetPixel(idx, static_cast&lt;typename<br>itkImage_t::PixelType&gt;(127*(sin(ix/2.0) + 1)));<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; }<br><br>&nbsp; return img;<br>}<br><br><br><br>template&lt;typename deformation_t&gt;<br>typename deformation_t::Pointer generate_deformation_field(int nx, int ny)<br>{<br>&nbsp; typename deformation_t::IndexType start = {{0, 0}};<br>&nbsp; typename deformation_t::SizeType size = {{nx, ny}};<br><br>&nbsp; typename deformation_t::RegionType region;<br>&nbsp; region.SetSize(size);<br>&nbsp; region.SetIndex(start);<br><br>&nbsp; typename deformation_t::PixelType v;<br>&nbsp; v[0] = 0.0;<br>&nbsp; v[1] = 0.0;<br><br>&nbsp; typename deformation_t::Pointer deformationField = deformation_t::New();<br>&nbsp; deformationField-&gt;SetRegions(region);<br>&nbsp; deformationField-&gt;Allocate();<br>&nbsp; deformationField-&gt;FillBuffer(v);<br><br>&nbsp; for (int ix = 0;
 ix &lt; nx; ++ix)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; for (int iy = 0; iy &lt; ny; ++iy)<br>&nbsp; &nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; typename deformation_t::IndexType idx = {{ix, iy}};<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //v[0] = ix/5.0;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v[0] = 10;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v[1] = 0;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deformationField-&gt;SetPixel(idx, v);<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; }<br><br>&nbsp; return deformationField;<br>}<br><br><br>template&lt;typename itkImage_t&gt;<br>void write_image(typename itkImage_t::Pointer im, std::string file_name)<br>{<br>&nbsp; typedef itk::ImageFileWriter&lt; itkImage_t &gt;&nbsp; WriterType;<br>&nbsp; typename WriterType::Pointer writer = WriterType::New();<br>&nbsp; writer-&gt;SetFileName( file_name.c_str() );<br>&nbsp; writer-&gt;SetInput( im );<br><br>&nbsp; try<br>&nbsp; &nbsp; {<br>&nbsp;
 &nbsp; &nbsp; writer-&gt;Update();<br>&nbsp; &nbsp; }<br>&nbsp; catch( itk::ExceptionObject &amp; excp )<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; std::cerr &lt;&lt; "Exception thrown " &lt;&lt; std::endl;<br>&nbsp; &nbsp; std::cerr &lt;&lt; excp &lt;&lt; std::endl;<br>&nbsp; &nbsp; }<br><br>&nbsp; return;<br>}<br><br><br><br><br><br><br><br>On Tue, May 24, 2011 at 4:38 AM, Dawood Masslawi &lt;<a ymailto="mailto:davoud_zzz@yahoo.com" href="/mc/compose?to=davoud_zzz@yahoo.com">davoud_zzz@yahoo.com</a>&gt; wrote:<br>&gt;<br>&gt; Hi Yi,<br>&gt; Each vector in the deformation filed image has the same dimension as the input image,<br>&gt; meaning that&nbsp;it has equal number of dimensions for each pixel corresponding to movement<br>&gt; of&nbsp;the&nbsp;input pixel. Naturally the deformation field image would have the&nbsp;same size&nbsp;as<br>&gt; the&nbsp;input image so it wold cover all the pixels in the input image.<br>&gt; As for your third question, note
 that the input and output image would also have the same<br>&gt; size, so using the deformation field it is clear that which pixels correspond to each other.<br>&gt; Hope this answers your questions,<br>&gt; Dawood<br>&gt;<br>&gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;<br>&gt; &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;<br>&gt;<br>&gt; Dear group,<br>&gt;<br>&gt; I'm a little confused about the itkWarpImageFilter....<br>&gt;<br>&gt; 1. I understand that in computing the deformed (output) image, we<br>&gt; should go
 through the domain of the *output* image, and inversely<br>&gt; trace back (according to the deformation vector field) to find the<br>&gt; intensity in the input image.<br>&gt;<br>&gt; 2. However, on page 242 of the software guide, above equation 6.21, we<br>&gt; see that the deformation vector field (as a vector image) should have<br>&gt; the same size as the *input* image. So the deformation field is<br>&gt; defined on the domain of the *input* image.<br>&gt;<br>&gt; 3. Then, go back to item 1, how do we achieve the inversion of the<br>&gt; vector field so as it defines on the domain of the *output* image?<br>&gt;<br>&gt; Is there anything I misunderstand? Thanks for any hint!<br>&gt;<br>&gt; Best,<br>&gt; yi<br></div></blockquote></div></td></tr></table>