# Filter a 3D image slice by slice and store results

**URL:** https://discourse.itk.org/t/filter-a-3d-image-slice-by-slice-and-store-results/3484
**Category:** Beginner Questions
**Created:** [September 25, 2020, 1:41pm UTC](https://discourse.itk.org/t/filter-a-3d-image-slice-by-slice-and-store-results/3484 "2020-09-25T13:41:33Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Elli](https://discourse.itk.org/letter_avatar_proxy/v4/letter/e/58f4c7/32.png) [@Elli](https://discourse.itk.org/u/Elli)
#### Post date: [September 25, 2020, 1:41pm UTC](https://discourse.itk.org/t/filter-a-3d-image-slice-by-slice-and-store-results/3484/1 "2020-09-25T13:41:34Z")

</div>

Dear all,  
I have a 3D volume, I want to iterate over all 2D slices, apply a convolutional filter on each slice and then put them again together as a 3D volume and store this 3D volume.

Somehow, I am failing to do so and I do not know what might be the problem. I wanted to iterate over the image slice by slice and consequently update the image. But it fails at the second slice/loop Thats what I have so far:

```auto
//create the convolutional kernel (that works, should be OK, it gives me a 3D image with size (5x5x1)
ImageType::Pointer kernel = ImageType::New();
CreateKernel(kernel)
using PasteFilterType = itk::PasteImageFilter<ImageType>;
//extract an image slice
using ExtractFilterType = itk::ExtractImageFilter<ImageType, ImageType>;
ExtractFilterType::Pointer extractFilter = ExtractFilterType::New();
extractFilter->SetDirectionCollapseToSubmatrix();
//image to change
ImageType * inputImage = image;
const typename ImageType::RegionType& imageRegion = image->GetLargestPossibleRegion();
const typename ImageType::SizeType& imageRegionSize = imageRegion.GetSize();
ImageType::RegionType inputRegion = inputImage->GetBufferedRegion();
ImageType::SizeType size = inputRegion.GetSize();
size[2] = 1; // we extract along z direction
ImageType::IndexType start = inputRegion.GetIndex();
//start at slice 0
unsigned int sliceNumber = 0;
//use convolutional filter
using FilterType = itk::ConvolutionImageFilter<ImageType>;
ImageType::RegionType desiredRegion;
FilterType::Pointer convolutionFilter = FilterType::New();
//iterate over all slices
for (int depth = 0; depth < imageRegionSize[2]; depth++) {
//set slice nr
			sliceNumber = depth;
			start[2] = sliceNumber;
			//get 2D slice
			desiredRegion.SetSize(size);
			desiredRegion.SetIndex(start);

			extractFilter->SetExtractionRegion(desiredRegion);
			//paste filtered slice
			PasteFilterType::Pointer pasteFilter = PasteFilterType::New();
			extractFilter->SetInput(inputImage);
			//convolve image
			convolutionFilter->SetInput(extractFilter->GetOutput());
			convolutionFilter->SetKernelImage(kernel);
//insert filtered slice
			pasteFilter->SetSourceImage(convolutionFilter->GetOutput());
			pasteFilter->SetDestinationImage(inputImage);
			
			pasteFilter->SetDestinationIndex(start);
			
			pasteFilter->SetSourceRegion(convolutionFilter->GetOutput()->GetBufferedRegion());
			pasteFilter->Update();

			
			inputImage= pasteFilter->GetOutput();
		}
		writer->SetFileName("E:/IBSI2/ibsi_2_digital_phantom/gabor1.nii");
		writer->SetInput(inputImage);
		writer->Update();
		
	}

```

Thanks a lot for the help!

---

<div class="post-metadata">

### Author: ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)
#### Post date: [September 25, 2020, 1:54pm UTC](https://discourse.itk.org/t/filter-a-3d-image-slice-by-slice-and-store-results/3484/2 "2020-09-25T13:54:40Z")

</div>

Hello,

With SimpleITK 2.0 we just added some infrastructure and [examples](https://simpleitk.readthedocs.io/en/master/link_SliceBySliceDecorator_docs.html) for this exact problem.

The current ITK PasteImageFilter does not allow a 2D Image to be pasted into a 3D Image. But I extended it into an [NPasteImageFilter](https://github.com/InsightSoftwareConsortium/ITKSimpleITKFilters/blob/master/include/itkNPasteImageFilter.h) which is available in ITK from the SimpleITKFitlers remote module. I was just starting to patch the ITK PasteImageFilter with the added functionality.

I am having problem following your posted code. You can edit the most to reformat it, or post a link to your code.

---

<div class="post-metadata">

### Author: ![Elli](https://discourse.itk.org/letter_avatar_proxy/v4/letter/e/58f4c7/32.png) [@Elli](https://discourse.itk.org/u/Elli)
#### Post date: [September 25, 2020, 3:02pm UTC](https://discourse.itk.org/t/filter-a-3d-image-slice-by-slice-and-store-results/3484/4 "2020-09-25T15:02:20Z")

</div>

Thanks already for your answer. Sorry, I see, the code looks very messy. I tried to make t more readable:

//create the convolutional kernel (that works, should be OK, it gives me a 3D image with size (5x5x1)):

> ImageType::Pointer kernel = ImageType::New();  
> CreateKernel(kernel)

//define the image I want to change (imageType is a 3D image)

> ImageType \* inputImage = image;  
> const typename ImageType::RegionType& imageRegion = image-\>GetLargestPossibleRegion();  
> const typename ImageType::SizeType& imageRegionSize = imageRegion.GetSize();  
> ImageType::RegionType inputRegion = inputImage-\>GetBufferedRegion();  
> ImageType::SizeType size = inputRegion.GetSize();

//define extract image filter to extract an image slice

> using ExtractFilterType = itk::ExtractImageFilter\<ImageType, ImageType\>;  
> ExtractFilterType::Pointer extractFilter = ExtractFilterType::New();  
> extractFilter-\>SetDirectionCollapseToSubmatrix();  
> size[2] = 1; // we extract along z direction  
> ImageType::IndexType start = inputRegion.GetIndex();

// now start at slice 0

> unsigned int sliceNumber = 0;

//define convolutional and paste filter  
using PasteFilterType = itk::PasteImageFilter;

> using FilterType = itk::ConvolutionImageFilter;  
> ImageType::RegionType desiredRegion;  
> FilterType::Pointer convolutionFilter = FilterType::New();

//iterate over all slices

> for (int depth = 0; depth \< imageRegionSize[2]; depth++) {  
> //set slice nr  
> sliceNumber = depth;  
> start[2] = sliceNumber;  
> //get 2D slice  
> desiredRegion.SetSize(size);  
> desiredRegion.SetIndex(start);
> 
> extractFilter-\>SetExtractionRegion(desiredRegion);  
> //paste filtered slice  
> PasteFilterType::Pointer pasteFilter = PasteFilterType::New();   
> extractFilter-\>SetInput(inputImage);  
> //convolve image  
> convolutionFilter-\>SetInput(extractFilter-\>GetOutput());  
> convolutionFilter-\>SetKernelImage(kernel);
> 
> //insert filtered slice  
> pasteFilter-\>SetSourceImage(convolutionFilter-\>GetOutput());  
> pasteFilter-\>SetDestinationImage(inputImage);  
> pasteFilter-\>SetDestinationIndex(start);  
> pasteFilter-\>SetSourceRegion(convolutionFilter-\>GetOutput()-\>GetBufferedRegion());  
> pasteFilter-\>Update();
> 
> inputImage= pasteFilter-\>GetOutput();  
> }

---

<div class="post-metadata">

### Author: ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)
#### Post date: [September 25, 2020, 4:57pm UTC](https://discourse.itk.org/t/filter-a-3d-image-slice-by-slice-and-store-results/3484/5 "2020-09-25T16:57:48Z")

</div>

To help debug, I would construct and configure all filters inside the for loop.

Also, your radius of [5,5,1] is equal to a diameter of [11,11,3] so the boundary condition is being used in the Z direction and the efficiency is being reduced.

---

<div class="post-metadata">

### Author: ![lassoan](https://discourse.itk.org/user_avatar/discourse.itk.org/lassoan/32/27_2.png) [@lassoan](https://discourse.itk.org/u/lassoan)
#### Post date: [September 25, 2020, 6:49pm UTC](https://discourse.itk.org/t/filter-a-3d-image-slice-by-slice-and-store-results/3484/6 "2020-09-25T18:49:11Z")

</div>

@Elli Please use triple backticks when including source code (see more options [here](https://discourse.equality-tech.com/t/more-tips-on-formatting-your-posts-syntax-highlighting/159)).
