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