SimpleITK  
SliceBySliceDecorator/SliceBySliceDecorator.py
1#!/usr/bin/env python
2# =========================================================================
3#
4# Copyright NumFOCUS
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0.txt
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18# =========================================================================
19
20""" Example demonstrating a slice-by-slice function decorator """
21
22import sys
23import itertools
24from functools import wraps
25import SimpleITK as sitk
26
27
28def slice_by_slice_decorator(func):
29 """
30 A function decorator which executes func on each 3D sub-volume and
31 *in-place* pastes the results into the input image. The input image type
32 and the output image type are required to be the same type.
33
34 :param func: A function which take a SimpleITK Image as it's first
35 argument and returns an Image as results.
36
37 :return: A decorated function.
38 """
39
40 iter_dim = 2
41
42 @wraps(func)
43 def slice_by_slice(image, *args, **kwargs):
44
45 dim = image.GetDimension()
46
47 if dim <= iter_dim:
48 #
49 image = func(image, *args, **kwargs)
50 return image
51
52 extract_size = list(image.GetSize())
53 extract_size[iter_dim:] = itertools.repeat(0, dim - iter_dim)
54
55 extract_index = [0] * dim
56 paste_idx = [slice(None, None)] * dim
57
58 extractor = sitk.ExtractImageFilter()
59 extractor.SetSize(extract_size)
60
61 for high_idx in itertools.product(
62 *[range(s) for s in image.GetSize()[iter_dim:]]
63 ):
64
65 # The lower 2 elements of extract_index are always 0.
66 # The remaining indices are iterated through all indexes.
67 extract_index[iter_dim:] = high_idx
68 extractor.SetIndex(extract_index)
69
70 # Sliced based indexing for setting image values internally uses
71 # the PasteImageFilter executed "in place". The lower 2 elements
72 # are equivalent to ":". For a less general case the assignment
73 # could be written as image[:,:,z] = ...
74 paste_idx[iter_dim:] = high_idx
75 image[paste_idx] = func(extractor.Execute(image), *args, **kwargs)
76
77 return image
78
79 return slice_by_slice
80
81
82if len(sys.argv) < 3:
83 print("Usage: SubDimensionProcess inputImage outputImage", file=sys.stderr)
84 sys.exit(1)
85
86inputImage = sitk.ReadImage(sys.argv[1])
87
88# Decorate the function
89adaptive_histogram_equalization_2d = slice_by_slice_decorator(
90 sitk.AdaptiveHistogramEqualization
91)
92
93adaptive_histogram_equalization_2d(inputImage, radius=[20] * 2, alpha=0.3, beta=0.3)
94
95sitk.WriteImage(inputImage, sys.argv[2])
Decrease the image size by cropping the image to the selected region bounds.
SITKIO_EXPORT Image ReadImage(const PathType &filename, PixelIDValueEnum outputPixelType=sitkUnknown, const std::string &imageIO="")
ReadImage is a procedural interface to the ImageFileReader class which is convenient for most image r...
SITKIO_EXPORT void WriteImage(const Image &image, const PathType &fileName, bool useCompression=false, int compressionLevel=-1)
WriteImage is a procedural interface to the ImageFileWriter. class which is convenient for many image...