[Insight-users] ITK Rearrange slices in volume

Phillip Ward pgwar1 at student.monash.edu
Mon Apr 8 19:20:22 EDT 2013


Hi Brad,

Thanks for the help. Sorry I left so much out of the code, I thought I was
already pasting too much for the mailing list.

As for the comments. I have an update prior to that code to ensure the
output information is available. The reason I had the paste filter declared
outside the loop as I was attempting to use the output of the last
iteration as input for the remainder of the pipeline. e.g.

Filter f

for i->n
f = new
f->update
end for

Filter g
g->SetInput(f->GetOutput())

I've modified this now to be:

for i->N

Filter f = new
f->Destination(sortedImage)
f->Update()
sortedImage=f->GetOutput()

end for

Filter g
g->SetInput(sortedImage);

This seems to work fine as the final image is as expected. I think the
reason I was getting a black image, rather than a zero image, was because
only the final iteration of the loop was doing anything (instead of the
first as I presumed). The filter was never being executed in the earlier
iterations.

So now I have a solution that works, but given I have Ns paste filters
running, it is less than efficient. Do you have any advice on how to
perform this operation in a less inefficient way? I feel the PasteFilter is
probably not the best solution for mapping one image to another. The
ResampleFilter comes to mind, but I'm unsure how to construct a transform
that is a function rather than a constant shift as in the translation
examples.

The pipeline is used only once. Prior to this section many filters and
transforms are executed in a very straightforward way, no loops or reuse.
Just about 8 filters set input to output in a standard pipeline. I would
have preferred to take the pixel buffer and do this part of the problem
"manually" but I'm trying to stay within the ITK paradigm.

Cheers,
Phil


On 8 April 2013 23:42, Bradley Lowekamp <blowekamp at mail.nih.gov> wrote:

> Hello Phillip,
>
> You didn't include where you updates were so I'll mention what I see as
> common problems
>
> On Apr 7, 2013, at 6:24 PM, Phillip Ward <pgwar1 at student.monash.edu>
> wrote:
>
>                 // Sort image slices
>                 // Allocate space for sorted image
>                 ImageType::Pointer sortedImage = ImageType::New();
>
> sortedImage->SetRegions(accumulateFilter->GetOutput()->GetLargestPossibleRegion());
>
>
> 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.
>
>
>
>                 sortedImage->Allocate();
>
>                 // Size of slices to be sorted
>                 ImageType::SizeType sourceSize;
>                 sourceSize[0] = Kx;
>                 sourceSize[1] = Ky;
>                 sourceSize[2] = 1;
>                 sourceSize[3] = 1;
>
>                 PasteFilterType::Pointer pasteFilter =
> PasteFilterType::New ();
>                 ImageType::RegionType sourceRegion;
>
>
> So you are creating a paste filter outside the loop here...
>
>
>                 for (int i = 0; i < Ns; ++i)
>                 {
>                    ImageType::IndexType sourceIndex;
>                    sourceIndex[0] = 0;
>                    sourceIndex[1] = 0;
>                    sourceIndex[2] = i;
>                    sourceIndex[3] = 0;
>
>                    ImageType::IndexType destinationIndex;
>                    if (i%2 == 0) {
>                       destinationIndex[0] = 0;
>                       destinationIndex[1] = 0;
>                       destinationIndex[2] = i/2;
>                       destinationIndex[3] = 0;
>                    } else {
>                       destinationIndex[0] = 0;
>                       destinationIndex[1] = 0;
>                       destinationIndex[2] = i/2 + Ns/2 + Ns%2;
>                       destinationIndex[3] = 0;
>                    }
>
>                    sourceRegion.SetSize(sourceSize);
>                    sourceRegion.SetIndex(sourceIndex);
>
>
>                    // Paste even slices before odd slices
>                    pasteFilter = PasteFilterType::New ();
>
>
> 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.
>
>
>  pasteFilter->SetSourceImage(accumulateFilter->GetOutput());
>                    pasteFilter->SetDestinationImage(sortedImage);
>                    pasteFilter->SetSourceRegion(sourceRegion);
>                    pasteFilter->SetDestinationIndex(destinationIndex);
>
>                    sortedImage = pasteFilter->GetOutput();
>
>
> 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...
>
> 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.
>
> 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..
>
> Hoped this helped,
> Brad
>
>                 }
>
> Cheers,
> Phil
>
>
>
> On 8 April 2013 04:43, Bradley Lowekamp <blowekamp at mail.nih.gov> wrote:
>
>> Hello Phil,
>>
>> 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.
>>
>> 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.
>>
>> 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
>>
>> Here is a quick solution in SimpleITK Python:
>>
>> import SimpleITK as sitk
>> img = sitk.ReadImage( "myfile.mha")
>> Nz = img.GetSize()[2]
>> limg = [ img[:,:,z//2] if z%2 else img[:,:,Nz//2+z/2] for z in
>> range(0,Nz) ]
>> rimg = sitk.JoinSeries( limg, img.GetSpacing()[2] )
>>
>> 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.
>>
>> 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.
>>
>> 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.
>>
>> From here you can convert to explicitly using the ExtractImageFilter and
>> get closer to the C++ ITK proper code.
>>
>>
>>
>> On Apr 7, 2013, at 2:42 AM, Phillip Ward <pgwar1 at student.monash.edu>
>> wrote:
>>
>> > Hey ITK community,
>> >
>> > I've got a problem I've been struggling with for a few weeks now and
>> would like some assistance.
>> >
>> > 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.
>> >
>> > 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).
>> >
>> > I've attempted using a paste image filter in a loop to paste each slice
>> one at a time
>> > size=(Nx,Ny,1), destinationIndex=(0,0,f(z));
>> > 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.
>> >
>> > I've attempted using a resample image filter, but my knowledge of
>> transformations was lacking and that failed also.
>> >
>> > 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.
>> >
>> > Cheers,
>> > Phil
>> > _____________________________________
>> > Powered by www.kitware.com
>> >
>> > Visit other Kitware open-source projects at
>> > http://www.kitware.com/opensource/opensource.html
>> >
>> > Kitware offers ITK Training Courses, for more information visit:
>> > http://www.kitware.com/products/protraining.php
>> >
>> > Please keep messages on-topic and check the ITK FAQ at:
>> > http://www.itk.org/Wiki/ITK_FAQ
>> >
>> > Follow this link to subscribe/unsubscribe:
>> > http://www.itk.org/mailman/listinfo/insight-users
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20130409/51688da4/attachment.htm>


More information about the Insight-users mailing list