3 from os.path import isdir, join
6 from pprint import pprint
10 from decimal import Decimal as d, ROUND_HALF_UP as rhu
12 PNG16_MAX = pow(2, 16) - 1 # here if thinks the heaviest weight bit is for transparency or something not in use with dicom imgs
13 PNG8_MAX = pow(2, 8+1) - 1 # heaviest weight bit is 8 => 2**8, but dont forget the others: the reason of +1
15 INPUT_DIR = '../../Data/Images_anonymous/Case_0350/'
16 OUT_DIR = './generated/'
20 # private func to trim the Matrix, but in one direction, vertically | horizontally
21 # return the slice, don't affect the Matrix
22 # y | : for column, x -> : for rows
24 # not my fault, numpy architecture
26 while i < len(Mat):# search by top
32 while i >= 0:# search by bottom
37 # print('y1, y2', y1, y2)
38 return slice(y1, y2+1)# +1 to stop at y2
41 # most use who make implicit call of ftrim twice
42 horizontal = ftrim(Mat)
43 vertical = ftrim(Mat.T)
44 # print('horizontal:vertical', horizontal, vertical)
45 return Mat[horizontal, vertical]
47 def map16(array):# can be useful in future
51 # return d(str(n)).quantize(d('1'), rounding=rhu)# safe round without
53 def affine(Mat, ab, cd):
56 ab: the 'from' interval (2, 384) or {begin:2, end:384} begin is 0, and end is 1
57 cd: the 'to' interval (0, 1024) {begin:0, end:1024}
62 with np.nditer(Mat, op_flags=['readwrite']) as M:
64 x[...] = max( 0, round( (x-a) * (d-c) / (b-a) + c ) ) # could not be negative
68 return '/'.join(filepath.split('/')[:-1]) + '/'
70 def topng(inputfile, outfile=None, overwrite=True):
72 return (64, 64) : the width and height
75 dicimg = pydicom.read_file(inputfile) # read dicom image
76 except pydicom.errors.InvalidDicomError as e:
77 # @TODO: log, i can't read this file
79 img = trim(dicimg.pixel_array)# get image array (12bits)
82 # return img.shape # $$ COMMENT OR REMOVE THIS LINE
84 # print('img', type(img))
85 # print('min', img.min(), 'max', img.max())
86 # dicimg.convert_pixel_data() # same as using dicimg.pixel_array
87 # pixa = dicimg._pixel_array
88 # print('dicimg._pixel_array', pixa)
89 # print('dicimg.pixel_array==pixa', dicimg.pixel_array==pixa)
92 # affine transfo to png 16 bits, func affects img variable
93 maxdepth = pow(2, dicimg.BitsStored) - 1
94 print('dicimg.BitsStored, PNG8_MAX', dicimg.BitsStored, PNG8_MAX) # testing..
96 (0, maxdepth), # img.min() replace 0 may be, but not sure it would be good choice
97 (0, PNG16_MAX if maxdepth > PNG8_MAX else PNG8_MAX)
100 savepath = (outfile or inputfile) + '.png'
101 savedir = getdir(savepath)
102 if overwrite and not isdir( savedir ):
103 pathlib.Path(savedir).mkdir(parents=True, exist_ok=True)
107 # tmp = np.array(img) # to get eye on the numpy format of img
108 # tmp = np.array(img) # to get eye on the numpy format of img
109 # print("img[0,0]", img[0,0])
111 # tmp.dtype = 'uint32'
112 # np.savetxt(savepath + '.npy', img)
115 cv2.imwrite(savepath, img, [cv2.IMWRITE_PNG_COMPRESSION, 0]) # write png image
120 def topngs(inputdir, outdir):
122 inputdir : directory which contains directly dicom files
124 files = [f for f in os.listdir(inputdir)]
127 topng( inputdir + f, join(outdir, f) )
129 if __name__ == '__main__':
130 topngs( INPUT_DIR, join(OUT_DIR, INPUT_DIR.split('/')[-2]) )
131 # topng(INPUT_DIR+'Image00001', OUT_DIR + INPUT_DIR.split('/')[-2] +'-Image00001')