SimpleITK  
RawImageReading/RawImageReading.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 """ A SimpleITK example that demonstrates how to read a raw image. """
21 
22 import argparse
23 import os
24 import tempfile
25 
26 import SimpleITK as sitk
27 
28 
29 def read_raw(
30  binary_file_name,
31  image_size,
32  sitk_pixel_type,
33  image_spacing=None,
34  image_origin=None,
35  big_endian=False,
36 ):
37  """
38  Read a raw binary scalar image.
39 
40  Parameters
41  ----------
42  binary_file_name (str): Raw, binary image file content.
43  image_size (tuple like): Size of image (e.g. [2048,2048])
44  sitk_pixel_type (SimpleITK pixel type: Pixel type of data (e.g.
45  sitk.sitkUInt16).
46  image_spacing (tuple like): Optional image spacing, if none given assumed
47  to be [1]*dim.
48  image_origin (tuple like): Optional image origin, if none given assumed to
49  be [0]*dim.
50  big_endian (bool): Optional byte order indicator, if True big endian, else
51  little endian.
52 
53  Returns
54  -------
55  SimpleITK image or None if fails.
56  """
57 
58  pixel_dict = {
59  sitk.sitkUInt8: "MET_UCHAR",
60  sitk.sitkInt8: "MET_CHAR",
61  sitk.sitkUInt16: "MET_USHORT",
62  sitk.sitkInt16: "MET_SHORT",
63  sitk.sitkUInt32: "MET_UINT",
64  sitk.sitkInt32: "MET_INT",
65  sitk.sitkUInt64: "MET_ULONG_LONG",
66  sitk.sitkInt64: "MET_LONG_LONG",
67  sitk.sitkFloat32: "MET_FLOAT",
68  sitk.sitkFloat64: "MET_DOUBLE",
69  }
70  direction_cosine = [
71  "1 0 0 1",
72  "1 0 0 0 1 0 0 0 1",
73  "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1",
74  ]
75  dim = len(image_size)
76  header = [
77  "ObjectType = Image\n".encode(),
78  (f"NDims = {dim}\n").encode(),
79  ("DimSize = " + " ".join([str(v) for v in image_size]) + "\n").encode(),
80  (
81  "ElementSpacing = "
82  + (
83  " ".join([str(v) for v in image_spacing])
84  if image_spacing
85  else " ".join(["1"] * dim)
86  )
87  + "\n"
88  ).encode(),
89  (
90  "Offset = "
91  + (
92  " ".join([str(v) for v in image_origin])
93  if image_origin
94  else " ".join(["0"] * dim) + "\n"
95  )
96  ).encode(),
97  ("TransformMatrix = " + direction_cosine[dim - 2] + "\n").encode(),
98  ("ElementType = " + pixel_dict[sitk_pixel_type] + "\n").encode(),
99  "BinaryData = True\n".encode(),
100  ("BinaryDataByteOrderMSB = " + str(big_endian) + "\n").encode(),
101  # ElementDataFile must be the last entry in the header
102  ("ElementDataFile = " + os.path.abspath(binary_file_name) + "\n").encode(),
103  ]
104  fp = tempfile.NamedTemporaryFile(suffix=".mhd", delete=False)
105 
106  print(header)
107 
108  # Not using the tempfile with a context manager and auto-delete
109  # because on windows we can't open the file a second time for ReadImage.
110  fp.writelines(header)
111  fp.close()
112  img = sitk.ReadImage(fp.name)
113  os.remove(fp.name)
114  return img
115 
116 
117 parser = argparse.ArgumentParser()
118 parser.add_argument("raw_file_name", help="path to raw binary image file")
119 parser.add_argument(
120  "out_file_name", help="output file name when image read as little endian"
121 )
122 parser.add_argument(
123  "big_endian",
124  type=lambda v: v.lower() in {"1", "true"},
125  help="'false' for little ending or 'true'for big " "endian",
126 )
127 parser.add_argument(
128  "sitk_pixel_type", help="SimpleITK pixel type (e.g. sitk.sitkUInt16)"
129 )
130 parser.add_argument("sz", nargs="+", help="image size, x,y,...", type=int)
131 args = parser.parse_args()
132 
133 string_to_pixelType = {
134  "sitkUInt8": sitk.sitkUInt8,
135  "sitkInt8": sitk.sitkInt8,
136  "sitkUInt16": sitk.sitkUInt16,
137  "sitkInt16": sitk.sitkInt16,
138  "sitkUInt32": sitk.sitkUInt32,
139  "sitkInt32": sitk.sitkInt32,
140  "sitkUInt64": sitk.sitkUInt64,
141  "sitkInt64": sitk.sitkInt64,
142  "sitkFloat32": sitk.sitkFloat32,
143  "sitkFloat64": sitk.sitkFloat64,
144 }
145 
146 # Read the image using both big and little endian
147 image = read_raw(
148  binary_file_name=args.raw_file_name,
149  image_size=args.sz,
150  sitk_pixel_type=string_to_pixelType[args.sitk_pixel_type],
151  big_endian=args.big_endian,
152 )
153 
154 sitk.WriteImage(image, args.out_file_name)
155 
156 if "SITK_NOSHOW" not in os.environ:
157  sitk.Show(image, "raw converted")
itk::simple::Show
void SITKIO_EXPORT Show(const Image &image, const std::string &title="", const bool debugOn=ProcessObject::GetGlobalDefaultDebug())
itk::simple::WriteImage
SITKIO_EXPORT void WriteImage(const Image &image, const std::vector< PathType > &fileNames, bool useCompression=false, int compressionLevel=-1)
WriteImage is a procedural interface to the ImageSeriesWriter. class which is convenient for many ima...
itk::simple::ReadImage
SITKIO_EXPORT Image ReadImage(const std::vector< PathType > &fileNames, PixelIDValueEnum outputPixelType=sitkUnknown, const std::string &imageIO="")
ReadImage is a procedural interface to the ImageSeriesReader class which is convenient for most image...