From d983932e5a974928a10bbab7e86fdf3e162ae2ae Mon Sep 17 00:00:00 2001 From: Bernardo TOD Date: Tue, 28 May 2019 11:32:13 +0200 Subject: [PATCH 1/1] applied mask horizontally --- formatdicom.py | 107 ------------------------------------------------- regularjson.py | 2 + topng.py | 103 ++++++++++++++++++++++++++++++++++++++++++----- totraindir.py | 17 +++----- 4 files changed, 102 insertions(+), 127 deletions(-) delete mode 100644 formatdicom.py diff --git a/formatdicom.py b/formatdicom.py deleted file mode 100644 index 54aa277..0000000 --- a/formatdicom.py +++ /dev/null @@ -1,107 +0,0 @@ -import os -import png -import dicom -import argparse - - -def mri_to_png(mri_file, png_file): - """ Function to convert from a DICOM image to png - - @param mri_file: An opened file like object to read te dicom data - @param png_file: An opened file like object to write the png data - """ - - # Extracting data from the mri file - plan = dicom.read_file(mri_file) - shape = plan.pixel_array.shape - - image_2d = [] - max_val = 0 - for row in plan.pixel_array: - pixels = [] - for col in row: - pixels.append(col) - if col > max_val: max_val = col - image_2d.append(pixels) - - # Rescaling grey scale between 0-255 - image_2d_scaled = [] - for row in image_2d: - row_scaled = [] - for col in row: - col_scaled = int((float(col) / float(max_val)) * 255.0) - row_scaled.append(col_scaled) - image_2d_scaled.append(row_scaled) - - # Writing the PNG file - w = png.Writer(shape[0], shape[1], greyscale=True) - w.write(png_file, image_2d_scaled) - - -def convert_file(mri_file_path, png_file_path): - """ Function to convert an MRI binary file to a - PNG image file. - - @param mri_file_path: Full path to the mri file - @param png_file_path: Fill path to the png file - """ - - # Making sure that the mri file exists - if not os.path.exists(mri_file_path): - raise Exception('File "%s" does not exists' % mri_file_path) - - # Making sure the png file does not exist - if os.path.exists(png_file_path): - raise Exception('File "%s" already exists' % png_file_path) - - mri_file = open(mri_file_path, 'rb') - png_file = open(png_file_path, 'wb') - - mri_to_png(mri_file, png_file) - - png_file.close() - - -def convert_folder(mri_folder, png_folder): - """ Convert all MRI files in a folder to png files - in a destination folder - """ - - # Create the folder for the pnd directory structure - os.makedirs(png_folder) - - # Recursively traverse all sub-folders in the path - for mri_sub_folder, subdirs, files in os.walk(mri_folder): - for mri_file in os.listdir(mri_sub_folder): - mri_file_path = os.path.join(mri_sub_folder, mri_file) - - # Make sure path is an actual file - if os.path.isfile(mri_file_path): - - # Replicate the original file structure - rel_path = os.path.relpath(mri_sub_folder, mri_folder) - png_folder_path = os.path.join(png_folder, rel_path) - if not os.path.exists(png_folder_path): - os.makedirs(png_folder_path) - png_file_path = os.path.join(png_folder_path, '%s.png' % mri_file) - - try: - # Convert the actual file - convert_file(mri_file_path, png_file_path) - print('SUCCESS>', mri_file_path, '-->', png_file_path) - except Exception as e: - print('FAIL>', mri_file_path, '-->', png_file_path, ':', e) - - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description="Convert a dicom MRI file to png") - parser.add_argument('-f', action='store_true') - parser.add_argument('dicom_path', help='Full path to the mri file') - parser.add_argument('png_path', help='Full path to the generated png file') - - args = parser.parse_args() - print(args) - if args.f: - convert_folder(args.dicom_path, args.png_path) - else: - convert_file(args.dicom_path, args.png_path) \ No newline at end of file diff --git a/regularjson.py b/regularjson.py index fa89890..ba7f97e 100644 --- a/regularjson.py +++ b/regularjson.py @@ -22,6 +22,8 @@ from pprint import pprint RT_PATH = '../../Data/json/' JSON_GTS = ['json_GT', 'json_GT_part2'] INFA_STR = 'Infa' +EPI_STR = 'Epi' +ENDO_STR = 'Endo' # Globals featurerefs = [] diff --git a/topng.py b/topng.py index 0000a58..8722d98 100644 --- a/topng.py +++ b/topng.py @@ -6,16 +6,20 @@ import pydicom from pprint import pprint import numpy as np import pathlib +import json from decimal import Decimal as d, ROUND_HALF_UP as rhu PNG16_MAX = pow(2, 16) - 1 # here if thinks the heaviest weight bit is for transparency or something not in use with dicom imgs PNG8_MAX = pow(2, 8+1) - 1 # heaviest weight bit is 8 => 2**8, but dont forget the others: the reason of +1 -INPUT_DIR = '../../Data/Images_anonymous/Case_0350/' +INPUT_DIR = '../../Data/Images_anonymous/Case_0002/' OUT_DIR = './generated/' #os.mkdir(outdir) +def roundall(*l): + return (round(e) for e in l) + def ftrim(Mat): # private func to trim the Matrix, but in one direction, vertically | horizontally # return the slice, don't affect the Matrix @@ -24,13 +28,13 @@ def ftrim(Mat): # not my fault, numpy architecture y1 = y2 = i = 0 while i < len(Mat):# search by top - if max(Mat[i]) > 0: + if Mat[i].max() > 0: y1 = i break i += 1 i = len(Mat) - 1 while i >= 0:# search by bottom - if max(Mat[i]) > 0: + if Mat[i].max() > 0: y2 = i break i -= 1 @@ -44,6 +48,80 @@ def trim(Mat): # print('horizontal:vertical', horizontal, vertical) return Mat[horizontal, vertical] +def mask(Mat, maskfile): + # return + xmin, ymin, xmax, ymax = minmax(Mat, maskfile) + + y1 = y2 = i = 0 + while i < len(Mat):# search by top + if i < ymin: + Mat[i].fill(0)# paint the row in black + else: break + i += 1 + + i = len(Mat) - 1 + while i >= 0:# search by bottom + if i > ymax: + Mat[i].fill(0)# paint the row in black + else: break + i -= 1 + # print('y1, y2', y1, y2) + # return slice(y1, y2+1)# +1 to stop at y2 + + + +def minmax(Mat, file): + """ + { + 'Image00001': [{ + 'color': '#ff0000', + 'points': [ + {'x': 94.377, 'y': 137.39}, + {'x': 100.38, 'y': 139.55}, + {'x': 103.26, 'y': 142.67}, + {'x': 105.91, 'y': 147.95}, + {'x': 105.42, 'y': 152.76}, + {'x': 100.62, 'y': 156.84}, + {'x': 95.338, 'y': 159.96}, + {'x': 89.573, 'y': 158.52}, + {'x': 84.53, 'y': 153}, + {'x': 82.848, 'y': 149.15}, + {'x': 82.368, 'y': 142.91}, + {'x': 85.01, 'y': 138.11}, + {'x': 89.813, 'y': 137.39}, + {'x': 94.377, 'y': 137.39} + ] + }] + } + return xmin, ymin, xmax, ymax + """ + with open(file) as jsonfile: + data = json.load(jsonfile) + pprint(data) + + for imgXXX in data:pass # get the value of key ~= "Image00001", cause it's dynamic + + for obj in data[imgXXX]:pass # get the object that contains the points, cause it's a list + points = obj['points'] + + + # print("print, ", data) + # print("imgXXX, ", imgXXX) + # print("points, ", points) + # print("imgXXX, ", obj['points']) + tmp = [(pt['x'], pt['y']) for pt in points ] # extract x,y. {'x': 94.377, 'y': 137.39} => (94.377, 137.39) + r = np.array(tmp) + + print(r) # log + + xmin, ymin = np.min(r, axis=0) + xmax, ymax = np.max(r, axis=0) + + print('xmax, ymax', xmax, ymax) + print('xmin, ymin', xmin, ymin) + + return roundall(xmin, ymin, xmax, ymax) + def map16(array):# can be useful in future return array * 16 @@ -67,9 +145,10 @@ def affine(Mat, ab, cd): def getdir(filepath): return '/'.join(filepath.split('/')[:-1]) + '/' -def topng(inputfile, outfile=None, overwrite=True): +def topng(inputfile, outfile=None, overwrite=True, verbose=False): """ - return (64, 64) : the width and height + (verbose) return (64, 64) : the width and height + (not verbose) return (img, dicimg) : the image and the dicimg objects """ try: dicimg = pydicom.read_file(inputfile) # read dicom image @@ -91,12 +170,15 @@ def topng(inputfile, outfile=None, overwrite=True): # affine transfo to png 16 bits, func affects img variable maxdepth = pow(2, dicimg.BitsStored) - 1 - print('dicimg.BitsStored, PNG8_MAX', dicimg.BitsStored, PNG8_MAX) # testing.. + print('dicimg.BitsStored, (img.min(), img.max())', dicimg.BitsStored, (img.min(), img.max())) # testing.. affine(img, (0, maxdepth), # img.min() replace 0 may be, but not sure it would be good choice (0, PNG16_MAX if maxdepth > PNG8_MAX else PNG8_MAX) ) + mask(img, '/Users/user/Desktop/Master/Stage/Data/json/json_GT/0_Case_0002/contours/1.2.3.4.5.6/31/-85.9968/Epicardic.json') + + savepath = (outfile or inputfile) + '.png' savedir = getdir(savepath) if overwrite and not isdir( savedir ): @@ -115,7 +197,10 @@ def topng(inputfile, outfile=None, overwrite=True): cv2.imwrite(savepath, img, [cv2.IMWRITE_PNG_COMPRESSION, 0]) # write png image # test - return img.shape + if verbose: + return img, dicimg + else: + return img.shape def topngs(inputdir, outdir): """ @@ -127,5 +212,5 @@ def topngs(inputdir, outdir): topng( inputdir + f, join(outdir, f) ) if __name__ == '__main__': - topngs( INPUT_DIR, join(OUT_DIR, INPUT_DIR.split('/')[-2]) ) - # topng(INPUT_DIR+'Image00001', OUT_DIR + INPUT_DIR.split('/')[-2] +'-Image00001') + # topngs( INPUT_DIR, join(OUT_DIR, INPUT_DIR.split('/')[-2]) ) + topng(INPUT_DIR+'Image00003', OUT_DIR + INPUT_DIR.split('/')[-2] +'-Image00003') diff --git a/totraindir.py b/totraindir.py index 8d90c14..1fbaf08 100644 --- a/totraindir.py +++ b/totraindir.py @@ -4,8 +4,8 @@ import pydicom from os.path import join # locals -from topng import topng -from regularjson import search, RT_PATH, JSON_GTS, INFA_STR +from topng import topng, mask +from regularjson import search, RT_PATH, JSON_GTS, INFA_STR, EPI_STR # constants GLOB_DIR = '../../Data/Images_anonymous/' @@ -68,15 +68,10 @@ if __name__ == '__main__': ref = join(r, l2[i]) # logically, should be the json ref of i dicom image infarctus = search(ref, INFA_STR) - if infarctus: - # print("infarctus:", infarctus) # Testing.. - # topng(join(caspath, dic), '%/%-%' % (join(OUT_DIR, 'infarctus'), cas, dic) - # print(join(caspath, dic), '{}/{}-{}'.format(join(OUT_DIR, 'infarctus'), cas, dic)) # Testing.. - w, h = topng(join(caspath, dic), '{}/{}-{}'.format(join(OUT_DIR, 'infarctus'), cas, dic)) - else: - # print("no infarctus:", infarctus) # Testing.. - # print(join(caspath, dic), '{}/{}-{}'.format(join(OUT_DIR, 'noinfarctus'), cas, dic)) # Testing.. - w, h = topng(join(caspath, dic), '{}/{}-{}'.format(join(OUT_DIR, 'noinfarctus'), cas, dic)) + # epimask = mask(ref, EPI_STR) + # print("infarctus:", infarctus) # Testing.. + # topng(join(caspath, dic), '%/%-%' % (join(OUT_DIR, 'infarctus'), cas, dic) + w, h = topng(join(caspath, dic), '{}/{}-{}'.format(join(OUT_DIR, 'infarctus' if infarctus else 'noinfarctus'), cas, dic)) # search maximums if wmax < w: wmax = w -- 2.39.5