<div dir="ltr"><div><div><div>Hello Steve<br><br></div>Thank you very much for your response and the pointer. <br><br>I feel that this might be an additional thing to be looking into once I get the mapping between World and Image coordinates (and back) right. Also, the scan direction is something that is not "bothering" me so much at the moment because each ROI references its grayscale image and I receive them sequentially ordered anyway.<br></div><div><br></div>All the best<br></div>AA<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 6, 2016 at 2:34 PM, Steve Pieper <span dir="ltr"><<a href="mailto:pieper@isomics.com" target="_blank">pieper@isomics.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Athanasios -<div><br></div><div>To get the scan direction you'll need to look at the relative ImagePositionPatient points from slice to slice.  Note that the scan direction is not always the cross product of the row and column orientations since the scan may go in the other direction from a right handed cross product or the slices can be sheared (or even at arbitrary locations)..  There are lots of other things that can happen too, like irregular spacing, missing slices, etc, but usually just normalizing the vector between your origin and any slice in the scan will be what you want.</div><div><br></div><div>This code will give you an idea:<br><div><br></div><div><a href="https://github.com/Slicer/Slicer/blob/master/Modules/Scripted/DICOMPlugins/DICOMScalarVolumePlugin.py#L195-L216" target="_blank">https://github.com/Slicer/<wbr>Slicer/blob/master/Modules/<wbr>Scripted/DICOMPlugins/<wbr>DICOMScalarVolumePlugin.py#<wbr>L195-L216</a><br></div></div><div><br></div><div>Best,</div><div>Steve</div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 6, 2016 at 7:50 AM, Athanasios Anastasiou <span dir="ltr"><<a href="mailto:athanastasiou@gmail.com" target="_blank">athanastasiou@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div>Hello Matthew<br><br></div>Thank you for your response.<br><br></div>As per the DICOM pages:<br><br>    #M = numpy.zeros((4,4))<br>    #M[0:3,0]=numpy.array(tumourIm<wbr>ageData[n].ImageOrientationPat<wbr>ient[0:3]) * tumourImageData[n].PixelSpacin<wbr>g[0]<br>    #M[0:3,1]=numpy.array(tumourIm<wbr>ageData[n].ImageOrientationPat<wbr>ient[3:]) * tumourImageData[n].PixelSpacin<wbr>g[1]<br>    #M[0:3,3]=tumourImageData[n].I<wbr>magePositionPatient<br>    #M[3,3]=1.0<br>    #M=numpy.matrix(M)<br><br></div>ImageOrientationPatient is a flat 1x6 vector as it is coming out of the image but more importantly it contains direction cosines which means that it may not constitute a "proper" rotation matrix. The determinant of that matrix is 0.0. Scaling apart, it would still have to be a "valid" rotation matrix.<br><br></div>Specific Data:<br><br></div><div>ImageOrientationPatient:<br>['0.999857', '0.00390641', '0.0164496', '-0.00741602', '0.975738', '0.218818']<br><br></div><div>ImagePositionPatient:<br>['-127.773', '-105.599', '-94.5758']<br><br></div><div>PixelSpacing:<br>['0.4688', '0.4688']<br><br><br></div><div>Now, if I read this correctly, all the points are offset by ImagePositionPatient, scaled by pixel spacing (and so far so good), the FIRST ROW (i.e. X) points mostly downwards (rotation of almost 90 degrees around the X axis in the world system), and the FIRST COLUMN (i.e. Y) now points left. To interpert the rotations, I am taking the direction cosines as angle differences between the scanner space (x,y,z) and image space (i,j,k) as depicted in (<a href="https://www.slicer.org/slicerWiki/index.php/Coordinate_systems" target="_blank">https://www.slicer.org/slicer<wbr>Wiki/index.php/Coordinate_<wbr>systems</a>). <br><br>Come to think of it, these very small angles might be the reason for the non-zero Z coordinate in the ROI.<br><br></div><div>What am I doing wrong?<br><br></div><div>All the best<span><font color="#888888"><br></font></span></div><span><font color="#888888"><div>AA<br></div><div><br></div><div><br></div><div><br><br></div><div><br><br><br></div><div><br><br></div></font></span></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 6, 2016 at 12:48 AM, Matthew Brett <span dir="ltr"><<a href="mailto:matthew.brett@gmail.com" target="_blank">matthew.brett@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<span><br>
On Sun, Sep 4, 2016 at 12:12 PM, Athanasios Anastasiou<br>
<<a href="mailto:athanastasiou@gmail.com" target="_blank">athanastasiou@gmail.com</a>> wrote:<br>
> Hello everyone<br>
><br>
> I am trying to convert between world and image coordinates and I am having<br>
> some difficulty, particularly with inversing the transform.<br>
><br>
> I need this specifically, as I would like to extract the pixels that have<br>
> been prescribed (manually) by a ROI. I can access the grayscale values which<br>
> are in some pixel space and I can access the ROI data which however is<br>
> expressed in 'mm' and thus in world coordinates.<br>
><br>
> As per <a href="http://nipy.org/nibabel/dicom/dicom_orientation.html" rel="noreferrer" target="_blank">http://nipy.org/nibabel/dicom/<wbr>dicom_orientation.html</a> I have all the<br>
> data to construct the matrix that converts pixel to world coordinates but I<br>
> am interested in the opposite direction (i.e. from world (ROI) to image<br>
> (pixels)).<br>
><br>
> My immediate reaction was to invert the transformation matrix. However, I am<br>
> getting an error that the matrix is "singular".<br>
<br>
</span>Yes, inverting is what you want to do.   The error is telling you<br>
about some error in the affine matrix.<br>
<br>
Would you mind giving more details on where you got the entries for<br>
your affine matrix?  What are your ImageOrientationPatient and<br>
ImagePositionPatient fields?  I assume you got the third column of the<br>
matrix by taking the cross-product of the first two?  What matrix do<br>
you end up with?<br>
<br>
Best,<br>
<br>
Matthew<br>
______________________________<wbr>_________________<br>
Neuroimaging mailing list<br>
<a href="mailto:Neuroimaging@python.org" target="_blank">Neuroimaging@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/neuroimaging" rel="noreferrer" target="_blank">https://mail.python.org/mailma<wbr>n/listinfo/neuroimaging</a><br>
</blockquote></div><br></div>
</div></div><br>______________________________<wbr>_________________<br>
Neuroimaging mailing list<br>
<a href="mailto:Neuroimaging@python.org" target="_blank">Neuroimaging@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/neuroimaging" rel="noreferrer" target="_blank">https://mail.python.org/mailma<wbr>n/listinfo/neuroimaging</a><br>
<br></blockquote></div><br></div>
</div></div><br>______________________________<wbr>_________________<br>
Neuroimaging mailing list<br>
<a href="mailto:Neuroimaging@python.org">Neuroimaging@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/neuroimaging" rel="noreferrer" target="_blank">https://mail.python.org/<wbr>mailman/listinfo/neuroimaging</a><br>
<br></blockquote></div><br></div>