<div dir="ltr"><div>Hi Fernando,</div><div>No, there is no way to transpose your projections. It should be fairly easy to add (in the ProjectionsReader) or to do it before hand with itk. Any contribution to RTK is welcomed.</div><div>Now, I'm not sure I follow the long explanation. Is the reconstruction transposed or the projections? If it's the former, so what you really want is to transpose the reconstructed volume. You can do this by setting a rotation matrix to the reconstructed volume with the --direction option of rtkfdk.</div><div>Simon<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, May 16, 2022 at 4:29 PM Fernando Hueso González <<a href="mailto:fernando.hueso@uv.es">fernando.hueso@uv.es</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
  
    
  
  <div>
    <p>Hello RTK-users,</p>
    <p>as a newbie, I am not yet familiar with the way how to correctly use RTK, so my apologies if I am asking something dumb.</p>
    <p>My question is (short version):</p>
    <p>Is there a way to use rtk::ProjectionsReader with images that have files and columns transposed with respect to the convention (wrt the rotation axis)? And if not, would it be possible to add such a feature in the future?</p>
    <p>
</p>
    <p>The long story:
</p>
    <p></p>
    <p>Currently, I am trying to migrate a script I wrote in MATLAB, which correctly performs a 3D reconstruction based on 360 projections (2D). Thus, I am sure that my geometry parameters and input data are correct. I open them exaclty in the same format both in MATLAB and in RTK (as uint16).
</p>
    <p>The MATLAB script does something like this (The flip below is because projections go from 0, -1, -2, ... degrees):</p>
    <p>
ctWidth = 768
ctHeight = 486
pitch = 0.075*4
allProjections = zeros(ctWidth,ctHeight,ctProjections,'uint16');
for proj = 1:ctProjections
    allProjections(:,:,proj) = fread(fopen(projfile(proj),'rb','l'),[ctWidth,ctHeight],'uint16');
end
Di = 90; % isocenter to detector distance mm
Ds = 151; % isocenter to source distance mm
offset = 1.6; % mm
for i = 1:ctHeight
    Ifan(i) = ifanbeam( ...
    log(16383./flip(single(squeeze(allProjections(round(offset*2/pitch):end,i,:))),2)), ...
    Ds/pitch, ...
        'FanSensorSpacing',Ds/(Di+Ds), ...
        'FanSensorGeometry','line', ...
        'Filter', 'Hann', ...
        'OutputSize', 700);
end
</p>
    <p>And after saving Ifan, it correctly generates a 3D image that I can open with Slicer3D. ( A cylinder with some wires).

</p>
    <p><img src="cid:180cd5a3f42c9c51cc61" alt="" width="328" height="175"></p>
    <p>Now, if I try to do the same thing with RTK in C++, I cannot seem to find the proper settings to do the exact same reconstruction.
First I try to define the geometry and input format:
</p>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)">    </span><span style="color:rgb(128,128,0)">using</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">GeometryType</span><span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">rtk</span>::<span style="color:rgb(128,0,128)">ThreeDCircularProjectionGeometry</span>;</pre>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)">    </span><span style="color:rgb(128,0,128)">GeometryType</span>::<span style="color:rgb(128,0,128)">Pointer</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">geometry</span><span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">GeometryType</span>::<span style="color:rgb(0,103,124)">New</span>();</pre>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)">    </span><span style="color:rgb(128,128,0)">for</span><span style="color:rgb(192,192,192)"> </span>(<span style="color:rgb(128,0,128)">size_t</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">i</span><span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">0</span>;<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">i</span><span style="color:rgb(192,192,192)"> </span><<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">360</span>;<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">i</span>++)<span style="color:rgb(192,192,192)"> </span>{</pre>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)">        </span><span style="color:rgb(128,128,0)">const</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">float</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">angle</span><span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span>-<span style="color:rgb(9,46,100)">i</span>;</pre>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)">        </span><span style="color:rgb(128,128,0)">const</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">float</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">sid</span><span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">151</span>;</pre>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)">        </span><span style="color:rgb(128,128,0)">const</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">float</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">sdd</span><span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">90+151</span>;</pre>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)">        </span><span style="color:rgb(9,46,100)">geometry</span>-><span style="color:rgb(0,103,124)">AddProjection</span>(<span style="color:rgb(9,46,100)">sid</span>,<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">sdd</span>,<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">angle</span>,<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">1.6</span>);</pre>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)">    </span>}

<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(128,0,128)">ImageIOType</span>::<span style="color:rgb(128,0,128)">Pointer</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">io</span><span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">ImageIOType</span>::<span style="color:rgb(0,103,124)">New</span>();
<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">io</span><span style="color:rgb(0,103,124)">-></span><span style="font-style:italic;color:rgb(0,103,124)">SetDimensions</span>(<span style="color:rgb(0,0,128)">0</span>,<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">ctWidth</span>);
<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">io</span><span style="color:rgb(0,103,124)">-></span><span style="font-style:italic;color:rgb(0,103,124)">SetDimensions</span>(<span style="color:rgb(0,0,128)">1</span>,<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">ctHeight</span>);
<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">io</span><span style="color:rgb(0,103,124)">-></span><span style="color:rgb(0,103,124)">SetByteOrderToLittleEndian</span>();
<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">io</span><span style="color:rgb(0,103,124)">-></span><span style="font-style:italic;color:rgb(0,103,124)">SetOrigin</span>(<span style="color:rgb(0,0,128)">0</span>,<span style="color:rgb(192,192,192)"> </span>-<span style="color:rgb(9,46,100)">detPitchU</span><span style="color:rgb(192,192,192)"> </span>*<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">detSizeU</span><span style="color:rgb(192,192,192)"> </span>/<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">2</span>);
<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">io</span><span style="color:rgb(0,103,124)">-></span><span style="font-style:italic;color:rgb(0,103,124)">SetOrigin</span>(<span style="color:rgb(0,0,128)">1</span>,<span style="color:rgb(192,192,192)"> </span>-<span style="color:rgb(9,46,100)">detPitchV</span><span style="color:rgb(192,192,192)"> </span>*<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">detSizeV</span><span style="color:rgb(192,192,192)"> </span>/<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">2</span>);
<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">io</span><span style="color:rgb(0,103,124)">-></span><span style="font-style:italic;color:rgb(0,103,124)">SetSpacing</span>(<span style="color:rgb(0,0,128)">0</span>,<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">detPitchU</span><span style="color:rgb(192,192,192)"> </span>*<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">binningU</span>);
<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">io</span><span style="color:rgb(0,103,124)">-></span><span style="font-style:italic;color:rgb(0,103,124)">SetSpacing</span>(<span style="color:rgb(0,0,128)">1</span>,<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">detPitchV</span><span style="color:rgb(192,192,192)"> </span>*<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">binningV</span>);


<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(128,128,0)">using</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">NameGeneratorType</span><span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">itk</span>::<span style="color:rgb(128,0,128)">NumericSeriesFileNames</span>;
<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(128,0,128)">NameGeneratorType</span>::<span style="color:rgb(128,0,128)">Pointer</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">nameGenerator</span><span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">NameGeneratorType</span>::<span style="color:rgb(0,103,124)">New</span>();
<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">nameGenerator</span><span style="color:rgb(0,103,124)">-></span><span style="font-style:italic;color:rgb(0,103,124)">SetSeriesFormat</span>(<span style="color:rgb(9,46,100)">subfolder</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,103,124)">+</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">"/%d.ct"</span>);
<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">nameGenerator</span><span style="color:rgb(0,103,124)">-></span><span style="font-style:italic;color:rgb(0,103,124)">SetStartIndex</span>(<span style="color:rgb(0,0,128)">0</span>);
<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">nameGenerator</span><span style="color:rgb(0,103,124)">-></span><span style="font-style:italic;color:rgb(0,103,124)">SetEndIndex</span>(<span style="color:rgb(0,0,128)">359</span>);
<span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">nameGenerator</span><span style="color:rgb(0,103,124)">-></span><span style="font-style:italic;color:rgb(0,103,124)">SetIncrementIndex</span>(<span style="color:rgb(0,0,128)">1</span>);
</pre>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(128,128,0)">    
    using</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">ReaderType</span><span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">rtk</span>::<span style="color:rgb(128,0,128)">ProjectionsReader</span><<span style="color:rgb(128,0,128)">OutputImageType</span>>;</pre>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)">    </span><span style="color:rgb(128,0,128)">ReaderType</span>::<span style="color:rgb(128,0,128)">Pointer</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(9,46,100)">reader</span><span style="color:rgb(192,192,192)"> </span>=<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">ReaderType</span>::<span style="color:rgb(0,103,124)">New</span>();</pre>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">reader</span><span style="color:rgb(0,103,124)">-></span><span style="color:rgb(0,103,124)">SetFileNames</span>(<span style="color:rgb(9,46,100)">nameGenerator</span><span style="color:rgb(0,103,124)">-></span><span style="color:rgb(0,103,124)">GetFileNames</span>());</pre>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">reader</span><span style="color:rgb(0,103,124)">-></span><span style="font-style:italic;color:rgb(0,103,124)">SetImageIO</span>(<span style="font-style:italic;color:rgb(9,46,100)">io</span>);</pre>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">reader</span><span style="color:rgb(0,103,124)">-></span><span style="font-style:italic;color:rgb(0,103,124)">SetI0</span>(<span style="color:rgb(0,0,128)">16383</span>);</pre>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)">    </span><span style="color:rgb(9,46,100)">reader</span><span style="color:rgb(0,103,124)">-></span><span style="font-style:italic;color:rgb(0,103,124)">Update</span>();</pre>
    <p></p>
    <p>After reconstructing, it looks then transposed with respect to the MATLAB version. The circular section is on the right, and the vertical cylinder on the left. (Sorry about it not being centered, that's my bad.). (Changing 'nColumns' with 'nRows' of course does not solve the issue, as this would lead to wrong 2D images being imported.)</p>
    <p><img src="cid:180cd5a3f44ed19a5bc2" alt="" width="332" height="173"></p>
    <p>
</p>
    <p>So the question would be if there is a way to solve this without having to mess around with my data. Maybe there is a 'transpose flag' that I have overlooked when calling rtk-projectionsreader?

If you prefer, I can share with you the full script and input data via my Cloud-Drive.</p>
    <p>
</p>
    <p>Thanks in advance for the help! Have a nice weekend.</p>
    <p>Fernando.</p>
  </div>
_______________________________________________<br>
Rtk-users mailing list<br>
<a href="mailto:Rtk-users@public.kitware.com" target="_blank">Rtk-users@public.kitware.com</a><br>
<a href="https://public.kitware.com/cgi-bin/mailman/listinfo/rtk-users" rel="noreferrer" target="_blank">https://public.kitware.com/cgi-bin/mailman/listinfo/rtk-users</a><br>
</blockquote></div>