<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hello Phillip,<div><br></div><div>You didn't include where you updates were so I'll mention what I see as common problems</div><div><br><div><div>On Apr 7, 2013, at 6:24 PM, Phillip Ward <<a href="mailto:pgwar1@student.monash.edu">pgwar1@student.monash.edu</a>> wrote:</div><div><br></div><blockquote type="cite"><div dir="ltr"><div style=""><div> // Sort image slices</div><div> // Allocate space for sorted image</div><div> ImageType::Pointer sortedImage = ImageType::New();</div><div>
sortedImage->SetRegions(accumulateFilter->GetOutput()->GetLargestPossibleRegion());</div></div></div></blockquote><div><br></div><div>It is important that accumulateFilter has been updated before this point so that is has the correct Image output information such as size and spacing etc... Technically just accumulateFilter->UpdateOutputInformation() is needed, but executing the primary generate data method with the normal "Update" should be ok too.</div><div><br></div> <br><blockquote type="cite"><div dir="ltr"><div style=""><div> sortedImage->Allocate();</div><div><br></div><div> // Size of slices to be sorted</div>
<div> ImageType::SizeType sourceSize;</div><div> sourceSize[0] = Kx;</div><div> sourceSize[1] = Ky;</div><div> sourceSize[2] = 1;</div><div> sourceSize[3] = 1;</div>
<div><br></div><div> PasteFilterType::Pointer pasteFilter = PasteFilterType::New ();</div><div> ImageType::RegionType sourceRegion;<br></div></div></div></blockquote><div><br></div><div>So you are creating a paste filter outside the loop here...</div><br><blockquote type="cite"><div dir="ltr"><div style=""><div><br></div><div> for (int i = 0; i < Ns; ++i)</div>
<div> {</div><div> ImageType::IndexType sourceIndex;</div><div> sourceIndex[0] = 0;</div><div> sourceIndex[1] = 0;</div><div> sourceIndex[2] = i;</div>
<div> sourceIndex[3] = 0;</div><div><br></div><div> ImageType::IndexType destinationIndex; </div><div> if (i%2 == 0) {</div><div> destinationIndex[0] = 0;</div>
<div> destinationIndex[1] = 0;</div><div> destinationIndex[2] = i/2; </div><div> destinationIndex[3] = 0;</div><div> } else {</div><div> destinationIndex[0] = 0;</div>
<div> destinationIndex[1] = 0;</div><div> destinationIndex[2] = i/2 + Ns/2 + Ns%2;</div><div> destinationIndex[3] = 0;</div><div> }</div><div>
<br></div><div> sourceRegion.SetSize(sourceSize);</div><div> sourceRegion.SetIndex(sourceIndex);</div></div></div></blockquote><blockquote type="cite"><div dir="ltr"><div style=""><div><br></div><div> // Paste even slices before odd slices</div>
<div> pasteFilter = PasteFilterType::New ();</div></div></div></blockquote><div><br></div><div>And another here, into the same variable.. This will reduce the reference count of the prior filter to zero, and it will get deleted. So the new paste filter has parent filter, its kind of orphaned.</div><br><blockquote type="cite"><div dir="ltr"><div style=""><div> pasteFilter->SetSourceImage(accumulateFilter->GetOutput());</div><div> pasteFilter->SetDestinationImage(sortedImage);</div>
<div> pasteFilter->SetSourceRegion(sourceRegion);</div><div> pasteFilter->SetDestinationIndex(destinationIndex);</div><div><br></div><div> sortedImage = pasteFilter->GetOutput();</div></div></div></blockquote><div><br></div><div>And there is no update here... and you take you un-updated output and place it back into the input... So there is no way for image to propagate down the pipeline because filters in the pipeline are being disconnected. So based on this I'd expect to see a zero sized image as the output for this pipeline. Not a "black" image...</div><div><br></div><div>Also please keep in mind that with you appear to be trying to run Ns PasteFilters, each one create a new copy for the output and copies it to the output. This poses a significant amount of waisted computation, and if you did keep you each paste filter you'd have over Ns images in memory.</div><div><br></div><div>I hesitate to give recommendations on how to improve your efficiency with the trouble you have already had and without knowing the goals of you filter i.e. memory efficiency, time efficiency, partial updating of parameters, or streaming..</div><div><br></div><div>Hoped this helped,</div><div>Brad</div><br><blockquote type="cite"><div dir="ltr"><div style="">
<div> }</div><div><br></div><div style="">Cheers,</div><div style="">Phil</div><div><br></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On 8 April 2013 04:43, Bradley Lowekamp <span dir="ltr"><<a href="mailto:blowekamp@mail.nih.gov" target="_blank">blowekamp@mail.nih.gov</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello Phil,<br>
<br>
It this is the try of problem that SimpleITK excels out. A lot of the time I like to prototype in SimpleITK, then implement it as an ITK pipeline once I know how what filters I need, what parameters I need, how I want the pipeline to flow for efficiency.<br>
<br>
As it sound like you have been struggling for a while with a variety of some of ITK pipeline and other complication, I'd like to suggest you play with he parameters of the filters you are using in a SimpleITK IPython environment, then implement it in the ITK pipeline after you know what the filters should do. So that it'd separate the filter issues from the pipeline issues.<br>
<br>
There are quite a number of ways you could be trying to setup your pipeline, and it's not clear what your pipeline goals are. You also did not provide code, so I really can't give much of a suggestion<br>
<br>
Here is a quick solution in SimpleITK Python:<br>
<br>
import SimpleITK as sitk<br>
img = sitk.ReadImage( "myfile.mha")<br>
Nz = img.GetSize()[2]<br>
limg = [ img[:,:,z//2] if z%2 else img[:,:,Nz//2+z/2] for z in range(0,Nz) ]<br>
rimg = sitk.JoinSeries( limg, img.GetSpacing()[2] )<br>
<br>
Hopefully, that 4th statement isn't to much pythonic short hand. It uses list comprehension combined with sliced based indexing to for a list of 2D z-slices that are re-ordered as you specified.<br>
<br>
The statement "img[:,:,n]" say ":"- all in x, ":"-all in y, and just the "n-th" slice. Internally it's implemented with an ExtractImageFilter to extract a 2D slice from a 3D image.<br>
<br>
Then the JoinSeriesImageFilter, just takes that re-oreded lists of slices an makes a 3D image from it. And the spacing from the old image is used again.<br>
<br>
From here you can convert to explicitly using the ExtractImageFilter and get closer to the C++ ITK proper code.<br>
<div><div class="h5"><br>
<br>
<br>
On Apr 7, 2013, at 2:42 AM, Phillip Ward <<a href="mailto:pgwar1@student.monash.edu">pgwar1@student.monash.edu</a>> wrote:<br>
<br>
> Hey ITK community,<br>
><br>
> I've got a problem I've been struggling with for a few weeks now and would like some assistance.<br>
><br>
> I have a volume and I would like to rearrange the slices in it, i.e., remap the third dimension of the volume. The volume is read from a single file, so renaming image files or reading in a different order is not suitable.<br>
><br>
> Right now, the even slices are first (1,15) and the odd slices are second (16,30). So the map f(z) = (z%2 ? z/2 : Nz/2 + z/2), where Nz is the length of the third dimension, interleaves the even and odd into their correct order (for even Nz).<br>
><br>
> I've attempted using a paste image filter in a loop to paste each slice one at a time<br>
> size=(Nx,Ny,1), destinationIndex=(0,0,f(z));<br>
> This produced a black image, which I suspect was a pipeline error on my behalf, but I haven't been able to work out how to implement this correctly.<br>
><br>
> I've attempted using a resample image filter, but my knowledge of transformations was lacking and that failed also.<br>
><br>
> I feel like there is an easier way to do this that I am perhaps overlooking, but either way I cannot implement it and would appreciate some advice.<br>
><br>
> Cheers,<br>
> Phil<br>
</div></div>> _____________________________________<br>
> Powered by <a href="http://www.kitware.com/" target="_blank">www.kitware.com</a><br>
><br>
> Visit other Kitware open-source projects at<br>
> <a href="http://www.kitware.com/opensource/opensource.html" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
><br>
> Kitware offers ITK Training Courses, for more information visit:<br>
> <a href="http://www.kitware.com/products/protraining.php" target="_blank">http://www.kitware.com/products/protraining.php</a><br>
><br>
> Please keep messages on-topic and check the ITK FAQ at:<br>
> <a href="http://www.itk.org/Wiki/ITK_FAQ" target="_blank">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" target="_blank">http://www.itk.org/mailman/listinfo/insight-users</a><br>
<br>
</blockquote></div><br></div>
</blockquote></div><br></div></body></html>