1#==========================================================================
2#
3#   Copyright Insight Software Consortium
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#          http://www.apache.org/licenses/LICENSE-2.0.txt
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16#
17#==========================================================================*/
18
19# also test the import callback feature
20
21from __future__ import print_function
22
23
24def custom_callback(name, progress):
25    if progress == 0:
26        print("Loading %s..." % name, file=sys.stderr)
27    if progress == 1:
28        print("done", file=sys.stderr)
29import itkConfig
30itkConfig.ImportCallback = custom_callback
31
32import itk
33import sys
34import os
35
36# test the force load function
37itk.force_load()
38
39fileName = sys.argv[1]
40
41PixelType = itk.UC
42dim = 2
43ImageType = itk.Image[PixelType, dim]
44ReaderType = itk.ImageFileReader[ImageType]
45reader = ReaderType.New(FileName=fileName)
46
47# test snake_case keyword arguments
48reader = ReaderType.New(file_name=fileName)
49
50# test echo
51itk.echo(reader)
52itk.echo(reader, sys.stdout)
53
54# test class_
55assert itk.class_(reader) == ReaderType
56assert itk.class_("dummy") == str
57
58# test template
59assert itk.template(ReaderType) == (itk.ImageFileReader, (ImageType,))
60assert itk.template(reader) == (itk.ImageFileReader, (ImageType,))
61try:
62    itk.template(str)
63    raise Exception("unknown class should send an exception")
64except KeyError:
65    pass
66
67# test ctype
68assert itk.ctype("unsigned short") == itk.US
69assert itk.ctype("        unsigned      \n   short \t  ") == itk.US
70assert itk.ctype("signed short") == itk.SS
71assert itk.ctype("short") == itk.SS
72try:
73    itk.ctype("dummy")
74    raise Exception("unknown C type should send an exception")
75except KeyError:
76    pass
77
78
79# test output
80assert itk.output(reader) == reader.GetOutput()
81assert itk.output(1) == 1
82# test the deprecated image
83assert itk.image(reader) == reader.GetOutput()
84assert itk.image(1) == 1
85
86# test size
87s = itk.size(reader)
88assert s[0] == s[1] == 256
89s = itk.size(reader.GetOutput())
90assert s[0] == s[1] == 256
91
92# test physical size
93s = itk.physical_size(reader)
94assert s[0] == s[1] == 256.0
95s = itk.physical_size(reader.GetOutput())
96assert s[0] == s[1] == 256.0
97
98# test spacing
99s = itk.spacing(reader)
100assert s[0] == s[1] == 1.0
101s = itk.spacing(reader.GetOutput())
102assert s[0] == s[1] == 1.0
103
104# test origin
105s = itk.origin(reader)
106assert s[0] == s[1] == 0.0
107s = itk.origin(reader.GetOutput())
108assert s[0] == s[1] == 0.0
109
110# test index
111s = itk.index(reader)
112assert s[0] == s[1] == 0
113s = itk.index(reader.GetOutput())
114assert s[0] == s[1] == 0
115
116# test region
117s = itk.region(reader)
118assert s.GetIndex()[0] == s.GetIndex()[1] == 0
119assert s.GetSize()[0] == s.GetSize()[1] == 256
120s = itk.region(reader.GetOutput())
121assert s.GetIndex()[0] == s.GetIndex()[1] == 0
122assert s.GetSize()[0] == s.GetSize()[1] == 256
123
124
125# test range
126assert itk.range(reader) == (0, 255)
127assert itk.range(reader.GetOutput()) == (0, 255)
128
129
130# test write
131itk.imwrite(reader, sys.argv[2])
132itk.imwrite(reader, sys.argv[2], True)
133
134# test read
135image=itk.imread(fileName)
136assert type(image) == itk.Image[itk.RGBPixel[itk.UC],2]
137image=itk.imread(fileName, itk.F)
138assert type(image) == itk.Image[itk.F,2]
139image=itk.imread(fileName, itk.F, fallback_only=True)
140assert type(image) == itk.Image[itk.RGBPixel[itk.UC],2]
141try:
142  image=itk.imread(fileName, fallback_only=True)
143  # Should never reach this point if test passes since an exception
144  # is expected.
145  raise Exception('`itk.imread()` fallback_only should have failed')
146except Exception as e:
147  if str(e) == "`pixel_type` must be set when using `fallback_only` option":
148    pass
149  else:
150    raise e
151
152# test search
153res = itk.search("Index")
154assert res[0] == "Index"
155assert res[1] == "index"
156assert "ContinuousIndex" in res
157
158res = itk.search("index", True)
159assert "Index" not in res
160
161
162# test down_cast
163obj = itk.Object.cast(reader)
164# be sure that the reader is casted to itk::Object
165assert obj.__class__ == itk.Object
166down_casted = itk.down_cast(obj)
167assert down_casted == reader
168assert down_casted.__class__ == ReaderType
169
170# test setting the IO manually
171png_io = itk.PNGImageIO.New()
172assert png_io.GetFileName() == ''
173reader=itk.ImageFileReader.New(FileName=fileName, ImageIO=png_io)
174reader.Update()
175assert png_io.GetFileName() == fileName
176
177# test reading image series
178series_reader = itk.ImageSeriesReader.New(FileNames=[fileName,fileName])
179series_reader.Update()
180assert series_reader.GetOutput().GetImageDimension() == 3
181assert series_reader.GetOutput().GetLargestPossibleRegion().GetSize()[2] == 2
182
183# test reading image series and check that dimension is not increased if
184# last dimension is 1.
185image_series = itk.Image[itk.UC, 3].New()
186image_series.SetRegions([10, 7, 1])
187image_series.Allocate()
188image_series.FillBuffer(0)
189image_series3d_filename = os.path.join(
190    sys.argv[3], "image_series_extras_py.mha")
191itk.imwrite(image_series, image_series3d_filename)
192series_reader = itk.ImageSeriesReader.New(
193    FileNames=[image_series3d_filename, image_series3d_filename])
194series_reader.Update()
195assert series_reader.GetOutput().GetImageDimension() == 3
196
197# test reading image series with itk.imread()
198image_series = itk.imread([fileName, fileName])
199assert image_series.GetImageDimension() == 3
200
201# Numeric series filename generation without any integer index. It is
202# only to produce an ITK object that users could set as an input to
203# `itk.ImageSeriesReader.New()` or `itk.imread()` and test that it works.
204numeric_series_filename = itk.NumericSeriesFileNames.New()
205numeric_series_filename.SetStartIndex(0)
206numeric_series_filename.SetEndIndex(3)
207numeric_series_filename.SetIncrementIndex(1)
208numeric_series_filename.SetSeriesFormat(fileName)
209image_series = itk.imread(numeric_series_filename.GetFileNames())
210number_of_files = len(numeric_series_filename.GetFileNames())
211assert image_series.GetImageDimension() == 3
212assert image_series.GetLargestPossibleRegion().GetSize()[2] == number_of_files
213
214# test reading image series with `itk.imread()` and check that dimension is
215# not increased if last dimension is 1.
216image_series = itk.imread([image_series3d_filename, image_series3d_filename])
217assert image_series.GetImageDimension() == 3
218
219# pipeline, auto_pipeline and templated class are tested in other files
220
221# BridgeNumPy
222try:
223    # Images
224    import numpy as np
225    image = itk.imread(fileName)
226    arr = itk.GetArrayFromImage(image)
227    arr.fill(1)
228    assert np.any(arr != itk.GetArrayFromImage(image))
229    arr = itk.array_from_image(image)
230    arr.fill(1)
231    assert np.any(arr != itk.GetArrayFromImage(image))
232    view = itk.GetArrayViewFromImage(image)
233    view.fill(1)
234    assert np.all(view == itk.GetArrayFromImage(image))
235    image = itk.GetImageFromArray(arr)
236    image.FillBuffer(2)
237    assert np.any(arr != itk.GetArrayFromImage(image))
238    image = itk.GetImageViewFromArray(arr)
239    image.FillBuffer(2)
240    assert np.all(arr == itk.GetArrayFromImage(image))
241    image = itk.GetImageFromArray(arr, is_vector=True)
242    assert image.GetImageDimension() == 2
243    image = itk.GetImageViewFromArray(arr, is_vector=True)
244    assert image.GetImageDimension() == 2
245    arr = np.array([[1,2,3],[4,5,6]]).astype(np.uint8)
246    assert arr.shape[0] == 2
247    assert arr.shape[1] == 3
248    assert arr[1,1] == 5
249    image = itk.GetImageFromArray(arr)
250    arrKeepAxes = itk.GetArrayFromImage(image, keep_axes=True)
251    assert arrKeepAxes.shape[0] == 3
252    assert arrKeepAxes.shape[1] == 2
253    assert arrKeepAxes[1,1] == 4
254    arr = itk.GetArrayFromImage(image, keep_axes=False)
255    assert arr.shape[0] == 2
256    assert arr.shape[1] == 3
257    assert arr[1,1] == 5
258    arrKeepAxes = itk.GetArrayViewFromImage(image, keep_axes=True)
259    assert arrKeepAxes.shape[0] == 3
260    assert arrKeepAxes.shape[1] == 2
261    assert arrKeepAxes[1,1] == 4
262    arr = itk.GetArrayViewFromImage(image, keep_axes=False)
263    assert arr.shape[0] == 2
264    assert arr.shape[1] == 3
265    assert arr[1,1] == 5
266    arr = arr.copy()
267    image = itk.GetImageFromArray(arr)
268    image2 = type(image).New()
269    image2.Graft(image)
270    del image # Delete image but pixel data should be kept in img2
271    image = itk.GetImageFromArray(arr+1) # Fill former memory if wrongly released
272    assert np.array_equal(arr, itk.GetArrayViewFromImage(image2))
273    image2.SetPixel([0]*image2.GetImageDimension(), 3) # For mem check in dynamic analysis
274    # VNL Vectors
275    v1 = itk.vnl_vector.D(2)
276    v1.fill(1)
277    v_np = itk.GetArrayFromVnlVector(v1)
278    assert v1.get(0) == v_np[0]
279    v_np[0] = 0
280    assert v1.get(0) != v_np[0]
281    view = itk.GetArrayViewFromVnlVector(v1)
282    assert v1.get(0) == view[0]
283    view[0] = 0
284    assert v1.get(0) == view[0]
285    # VNL Matrices
286    m1 = itk.vnl_matrix.D(2,2)
287    m1.fill(1)
288    m_np = itk.GetArrayFromVnlMatrix(m1)
289    assert m1.get(0,0) == m_np[0,0]
290    m_np[0,0] = 0
291    assert m1.get(0,0) != m_np[0,0]
292    view = itk.GetArrayViewFromVnlMatrix(m1)
293    assert m1.get(0,0) == view[0,0]
294    view[0,0] = 0
295    assert m1.get(0,0) == view[0,0]
296    arr = np.zeros([3,3])
297    m_vnl = itk.GetVnlMatrixFromArray(arr)
298    assert m_vnl(0,0) == 0
299    m_vnl.put(0,0,3)
300    assert m_vnl(0,0) == 3
301    assert arr[0,0] == 0
302    # ITK Matrix
303    arr = np.zeros([3,3],float)
304    m_itk = itk.GetMatrixFromArray(arr)
305    # Test snake case function
306    m_itk = itk.matrix_from_array(arr)
307    m_itk.SetIdentity()
308    # Test that the numpy array has not changed,...
309    assert arr[0,0] == 0
310    # but that the ITK matrix has the correct value.
311    assert m_itk(0,0) == 1
312    arr2 = itk.GetArrayFromMatrix(m_itk)
313    # Check that snake case function also works
314    arr2 = itk.array_from_matrix(m_itk)
315    # Check that the new array has the new value.
316    assert arr2[0,0] == 1
317    arr2[0,0]=2
318    # Change the array value,...
319    assert arr2[0,0] == 2
320    # and make sure that the matrix hasn't changed.
321    assert m_itk(0,0) == 1
322
323except ImportError:
324    print("NumPy not imported. Skipping BridgeNumPy tests")
325    # Numpy is not available, do not run the Bridge NumPy tests
326    pass
327