def read_xray(path, voi_lut=True, fix_monochrome=True, use_8bit=True, rescale_times=None): from pydicom.pixel_data_handlers.util import apply_voi_lut dicom = pydicom.read_file(path) # VOI LUT (if available by DICOM device) is used to transform raw DICOM data to "human-friendly" view if voi_lut: data = apply_voi_lut(dicom.pixel_array, dicom) else: data = dicom.pixel_array data = data.astype(np.float64) if rescale_times: data = cv2.resize( data, (data.shape[1] // rescale_times, data.shape[0] // rescale_times), interpolation=cv2.INTER_CUBIC) # depending on this value, X-ray may look inverted - fix that: if fix_monochrome and dicom.PhotometricInterpretation == "MONOCHROME1": data = np.amax(data) - data data = data - np.min(data) data = data / np.max(data) if use_8bit is True: data = (data * 255).astype(np.uint8) else: data = (data * 65535).astype(np.uint16) return data
def read_xray(path, voi_lut=True, fix_monochrome=True): """ Refs ---- - https://www.kaggle.com/raddar/convert-dicom-to-np-array-the-correct-way Examples -------- >>> import matplotlib.pyplot as plt >>> %matplotlib inline >>> img = read_xray('../input/vinbigdata-chest-xray-abnormalities-detection/train/0108949daa13dc94634a7d650a05c0bb.dicom') >>> plt.figure(figsize = (12,12)) >>> plt.imshow(img, 'gray') """ dicom = pydicom.read_file(path) # VOI LUT (if available by DICOM device) is used to transform raw DICOM data to "human-friendly" view if voi_lut: data = apply_voi_lut(dicom.pixel_array, dicom) else: data = dicom.pixel_array # depending on this value, X-ray may look inverted - fix that: if fix_monochrome and dicom.PhotometricInterpretation == "MONOCHROME1": data = np.amax(data) - data data = data - np.min(data) data = data / np.max(data) data = (data * 255).astype(np.uint8) return data
def __getitem__(self, index): img_slices = glob(os.path.join(self.imgs[index]['img'], '*.dcm')) vol = [ pydicom.dcmread(img_slice_name) for img_slice_name in img_slices ] z_flip_flag = vol[1].ImagePositionPatient[-1] - vol[ 0].ImagePositionPatient[ -1] < 0 # is this dicom acquired in the opposite direction (along Z)? vol = [apply_voi_lut(arr=i.pixel_array, ds=i) for i in vol] vol_name = self.imgs[index]['img'] vol = np.asarray(vol).astype(np.float32) mask = self.imgs[index]['gt'] if z_flip_flag: self.counter += 1 vol = np.flip(vol, axis=0) mask = np.flip(mask, axis=0) if self.transform is not None: vol, mask = self.transform(vol, mask) if self.input_image_transform is not None: vol = self.input_image_transform(vol) if self.mask_transform is not None: mask = self.transform(mask) if self.n_channels != 1: vol = vol.repeat(self.n_channels, 1, 1, 1) return vol, mask, vol_name
def __getitem__(self, index): volume_idx = index // 60 slice_idx = index % 60 img_slices = glob(os.path.join(self.imgs[volume_idx]['img'], '*.dcm')) img_slice_name = img_slices[slice_idx] image = pydicom.dcmread(img_slice_name) image = apply_voi_lut(arr=image.pixel_array, ds=image) image = np.expand_dims(image, -1).astype(np.float32) image = np.repeat(image, 3, -1) try: mask = self.imgs[volume_idx]['gt'][slice_idx] except Exception as e: print(e) if self.transform is not None: image, mask = self.transform(image, mask) if self.input_image_transform is not None: image = self.input_image_transform(image) if self.mask_transform is not None: mask = self.transform(mask) return image, mask, img_slice_name
def read_dcm(path): dcm = pydicom.read_file(path) img = apply_voi_lut(apply_modality_lut(dcm.pixel_array, dcm), dcm) img = ((img - img.min()) / (img.max() - img.min()) * 255).astype(np.uint8) img = np.invert(img) if len(img.shape) < 3: img = np.repeat(img[..., None], 3, axis=-1) return img
def read_dicom_image(self, img_name, invert): dcm = pydicom.read_file(img_name) img = apply_voi_lut(apply_modality_lut(dcm.pixel_array, dcm), dcm) img = ((img - img.min()) / (img.max() - img.min()) * 255).astype( np.uint8) if invert != None: img = np.invert(img) img = np.expand_dims(img, axis=-1) return img
def load_annotation(self, id): global ann2, anns_1, anns_2, indx, file_name, folder_name, index index = id row = ann2.iloc[id] indx = row['indx'] folder_name = indx.split("-")[0] file_name = indx.split("-")[1] + "-" + indx.split( "-")[2] + "-" + indx.split("-")[3][:-5] #print(folder_name,file_name) is_normal_1 = is_normal_2 = False density_level_1 = density_level_2 = -1 #print("Got Here:!") try: impath = os.path.join(data_directory_1, folder_name, file_name) #im_save_path=os.path.join(destination_directory,str(im_counter)+"_"+filename[:-4]+".png") #print(impath) json_path_1 = os.path.join(data_directory_1, folder_name, file_name + ".json") json_path_2 = os.path.join(data_directory_2, folder_name, file_name + ".json") ds = pydicom.dcmread(impath, force=True) img = ds.pixel_array.astype(float) if 'WindowWidth' in ds: #print('Dataset has windowing') windowed = apply_voi_lut(ds.pixel_array, ds) #plt.imshow(windowed, cmap="gray", vmax=windowed.max(), vmin=windowed.min) #plt.show() img = windowed.astype(float) #return "windowed" # Convert to uint img = (np.maximum(img, 0) / img.max()) * 255.0 img = np.uint8(img) img = cv2.merge([img, img, img]) #img = cv2.COLOR_GRAY2RGB() #(ori_h,ori_w)=img.shape #print("annotation by ",first_doctor) anns_1 = self.extract_annotation(json_path_1) #print("annotation by ",second_doctor) anns_2 = self.extract_annotation(json_path_2) im_1 = img.copy() im_2 = img.copy() #print("processing file", index, "of ", len(ann2.index)) if len(anns_1) > 0: im_1 = self.plot_image(im_1, anns_1, class_names) if len(anns_2) > 0: im_2 = self.plot_image(im_2, anns_2, class_names) return im_1, im_2, anns_1, anns_2 except Exception as e: print("General error Occured at the end", e) return [0, 0, 0, 0]
def load_dicom(path, preprocessing = 'norm'): dicom = pydicom.read_file(path) data = dicom.pixel_array if preprocessing == 'norm': data = data - np.min(data) if np.max(data) != 0: data = data / (np.max(data) - np.min(data)) data = (data * 255).astype(np.uint8) if preprocessing == 'apply_voi_lut': data = apply_voi_lut(dicom.pixel_array, dicom) return data
def dicom_2_png(self, dataset_path, metadata_name, downsampling_path): """ dicom to png converter """ dicom_metadata = pd.read_csv(str(dataset_path+metadata_name), sep=",", header=0) print("++ Metadata: {}".format(dicom_metadata.shape)) for dcm in dicom_metadata["patientId"]: ## Read dicom image and covert pixels into a numpy array ds = dcmread(str(dataset_path+"/stage_2_train_images/"+dcm+".dcm")) windowed = apply_voi_lut(ds.pixel_array, ds) ## Write the image converted cv2.imwrite(os.path.join(downsampling_path, str(dcm+".png")), windowed)
def dicom2narray(path, voi_lut = False, fix_monochrome = True): """ Converts a DICOM into a NUMPY array and returns this array and its corresponding dataset. """ dicom = pydicom.read_file(path) # VOI LUT (if available by DICOM device) is used to transform raw DICOM data # to "human-friendly" view if voi_lut: # If the modality is CT (Scanner Image) we have to convert the values of # the image first with apply_modality # It uses the values of RescaleSlope and RescaleIntercept to convert the # values or the attribute LUT Sequence if dicom.Modality == "CT": data = apply_modality_lut(dicom.pixel_array, dicom) data = apply_voi_lut(data, dicom) else: data = apply_voi_lut(dicom.pixel_array, dicom) else: data = dicom.pixel_array # depending on this value, X-ray may look inverted - fix that: if fix_monochrome and dicom.PhotometricInterpretation == "MONOCHROME1": data = np.amax(data) - data #If the DICOM are not in one of these two formats, it can bring new problems. if dicom.PhotometricInterpretation != "MONOCHROME2" and \ dicom.PhotometricInterpretation != "MONOCHROME1": warnings.warn("PhotometricInterpretation " + dicom.PhotometricInterpretation + " can cause unexpected behaviors.\n" + "File concerned : " + path) data = data - np.min(data) data = data / np.max(data) data = (data * 255).astype(np.uint8) return (data, dicom)
def dcm2png(path): dcm = pydicom.read_file(path) # extracting image (pixels data) img = apply_voi_lut(apply_modality_lut(dcm.pixel_array, dcm), dcm) if not (("PhotometricInterpretation" in dcm) and (dcm.PhotometricInterpretation == 'MONOCHROME2')): img = np.invert(img) img -= img.min() img = img / img.max() img = (img * 255) img = img.astype(np.uint8) path = str(path) + '.png' plt.imsave(path, img) return path
def dicom2array(path, voi_lut=True, fix_monochrome=True): """ Convert dicom file to numpy array Args: path (str): Path to the dicom file to be converted voi_lut (bool): Whether or not VOI LUT is available fix_monochrome (bool): Whether or not to apply monochrome fix Returns: Numpy array of the respective dicom file """ # Use the pydicom library to read the dicom file dicom = pydicom.read_file(path) # VOI LUT (if available by DICOM device) is used to # transform raw DICOM data to "human-friendly" view if voi_lut: data = apply_voi_lut(dicom.pixel_array, dicom) else: data = dicom.pixel_array # The XRAY may look inverted # - If we want to fix this we can if fix_monochrome and dicom.PhotometricInterpretation == "MONOCHROME1": data = np.amax(data) - data # Normalize the image array and return data = data - np.min(data) data = data / np.max(data) data = (data * 255).astype(np.uint8) return data def plot_image(img, title="", figsize=(8,8), cmap=None): """ Function to plot an image to save a bit of time """ plt.figure(figsize=figsize) if cmap: plt.imshow(img, cmap=cmap) else: img plt.imshow(img) plt.title(title, fontweight="bold") plt.axis(False) plt.show() def get_image_id(path): """ Function to return the image-id from a path """ return path.rsplit("/", 1)[1].rsplit(".", 1)[0]
def dcm2image(dcm_path): dcm = dcmread(dcm_path) array = apply_voi_lut(dcm.pixel_array, dcm) if dcm.PhotometricInterpretation == "MONOCHROME1": array = np.amax(array) - array array = array - np.min(array) array = array / np.max(array) array = array * 255 array = array.astype(np.uint8) image = np.stack([array] * 3, axis=0) image = np.transpose(image, (1, 2, 0)) return image
def dicom2array(path, voi_lut=True, fix_monochrome=True): dicom = pydicom.read_file(path) if voi_lut: data = apply_voi_lut(dicom.pixel_array, dicom) else: data = dicom.pixel_array if fix_monochrome and dicom.PhotometricInterpretation == "MONOCHROME1": data = np.amax(data) - data data = data - np.min(data) data = data / np.max(data) #data = (data*255).astype(np.uint8) return data
def read_xray(path): dicom = pydicom.read_file(path) # VOI LUT is used to transform raw DICOM data to "human-friendly" view data = apply_voi_lut(dicom.pixel_array, dicom) # depending on this value, X-ray may look inverted - fix that: if dicom.PhotometricInterpretation == "MONOCHROME1": data = np.amax(data) - data data = data - np.min(data) data = data / np.max(data) data = (data * 255).astype(np.uint8) return data
def dicom2array(path, voi_lut=True, fix_monochrome=True): dicom = pydicom.read_file(path) # VOI LUT (if available by DICOM device) is used to # transform raw DICOM data to "human-friendly" view if voi_lut: data = apply_voi_lut(dicom.pixel_array, dicom) else: data = dicom.pixel_array # depending on this value, X-ray may look inverted - fix that: if fix_monochrome and dicom.PhotometricInterpretation == "MONOCHROME1": data = np.amax(data) - data data = data - np.min(data) data = data / np.max(data) data = (data * 255).astype(np.uint8) return data
def read_xray(path, voi_lut=True, fix_monochrome=True): # Original from: https://www.kaggle.com/raddar/convert-dicom-to-np-array-the-correct-way dicom = pydicom.read_file(path) # VOI LUT (if available by DICOM device) is used to transform raw DICOM data to # "human-friendly" view if voi_lut: data = apply_voi_lut(dicom.pixel_array, dicom) else: data = dicom.pixel_array # depending on this value, X-ray may look inverted - fix that: if fix_monochrome and dicom.PhotometricInterpretation == "MONOCHROME1": data = np.amax(data) - data data = data - np.min(data) data = data / np.max(data) data = (data * 255).astype(np.uint8) return data
def read_xray(path, voi_lut=True, fix_monochrome=True, clahe=False, hist=False): # Original from: https://www.kaggle.com/raddar/convert-dicom-to-np-array-the-correct-way dicom = pydicom.read_file(path) # VOI LUT (if available by DICOM device) is used to transform raw DICOM data to # "human-friendly" view if voi_lut: image = apply_voi_lut(dicom.pixel_array, dicom) else: image = dicom.pixel_array # depending on this value, X-ray may look inverted - fix that: if fix_monochrome and dicom.PhotometricInterpretation == "MONOCHROME1": image = np.amax(image) - image intercept = dicom.RescaleIntercept if "RescaleIntercept" in dicom else 0.0 slope = dicom.RescaleSlope if "RescaleSlope" in dicom else 1.0 if slope != 1: image = slope * image.astype(np.float64) image = image.astype(np.int16) image += np.int16(intercept) image = image - np.min(image) # Hist normalization if hist: image = exposure.equalize_hist(image) # CLAHE normalization if clahe: image = exposure.equalize_adapthist(image / np.max(image)) else: image = image / np.max(image) image = (image * 255).astype(np.uint8) return image
def read_xray(self, voi_lut = True, fix_monochrome = True): if self.data_friendly is not None and self.voi_lut == voi_lut and self.fix_monochrome == fix_monochrome: return self.data_friendly else: self.voi_lut = voi_lut self.fix_monochrome = fix_monochrome dicom = self.dicom # VOI LUT (if available by DICOM device) is used to transform raw DICOM data to "human-friendly" view if voi_lut: data = apply_voi_lut(dicom.pixel_array, dicom) else: data = dicom.pixel_array # depending on this value, X-ray may look inverted - fix that: if fix_monochrome and dicom.PhotometricInterpretation == "MONOCHROME1": data = np.amax(data) - data data = data - np.min(data) data = data / np.max(data) data = (data * 255).astype(np.uint8) self.data_friendly = data return data
def windowing(img, dcmfile): background = copy.deepcopy(background_img) # apply windowing img = apply_voi_lut(img, dcmfile) pixel_array = img pixel_array = np.stack((pixel_array, ) * 3, axis=-1) h, w = img.shape size = (int(462 * h / w), 462) if h < w else (462, int(462 * w / h)) pixel_array = resize(pixel_array, size, preserve_range=True) # update background with windowed image start = int((600 - len(pixel_array)) / 2) end = int((600 - len(pixel_array[0])) / 2) background[start:start + len(pixel_array), end:end + len(pixel_array[0])] = pixel_array data = background.astype(np.uint8) return data
def read_xray(image_id, data_dir, voi_lut=True, fix_monochrome=True): path = data_dir / f'{image_id}.dicom' if not path.exists(): return 'n' dicom = pydicom.read_file(path, stop_before_pixels=True) if not (data_dir / f'{image_id}.npy').exists(): dicom = pydicom.read_file(path) # VOI LUT (if available by DICOM device) is used to transform raw DICOM data to "human-friendly" view if voi_lut: data = apply_voi_lut(dicom.pixel_array, dicom) else: data = dicom.pixel_array # depending on this value, X-ray may look inverted - fix that: if fix_monochrome and dicom.PhotometricInterpretation == "MONOCHROME1": data = np.amax(data) - data data = data.astype(np.uint16) np.save(data_dir / f'{image_id}.npy', data) meta = dict( image_id=image_id, rows=dicom.Rows, columns=dicom.Columns, sex=dicom.get('PatientSex'), age=dicom.get('PatientAge'), ) for label in [ 'WindowCenter', 'WindowWidth', 'RescaleIntercept', 'RescaleSlope' ]: meta[label] = dicom.get(label) # Uncomment to remove dicom # os.remove(path) return 'a'
folder_path = "stage_1_test_images" # Specify the output jpg/png/tiff folder path jpg_path = "JPG_test" png_path = "PNG_test" tiff_path = "TIFF_test" images_path = os.listdir(folder_path) for n, image in enumerate(images_path): ds = dicom.dcmread(os.path.join(folder_path, image)) arr = ds.pixel_array if choose == 1: image = image.replace('.dcm', '.jpg') # apply modality arr = util.apply_modality_lut(arr, ds) arr = util.apply_voi_lut(arr, ds, index=0) cv2.imwrite(os.path.join(jpg_path, image), arr) elif choose == 2: image = image.replace('.dcm', '.png') shape = ds.pixel_array.shape # Convert to float to avoid overflow or underflow losses. image_2d = ds.pixel_array.astype(float) # Rescaling grey scale between 0-255 image_2d_scaled = (np.maximum(image_2d,0) / image_2d.max()) * 255.0 # Convert to uint image_2d_scaled = np.uint8(image_2d_scaled)
try: impath = os.path.join(data_directory_1, folder_name, file_name) #im_save_path=os.path.join(destination_directory,str(im_counter)+"_"+filename[:-4]+".png") #print(impath) json_path_1 = os.path.join(data_directory_1, folder_name, file_name + ".json") json_path_2 = os.path.join(data_directory_2, folder_name, file_name + ".json") ds = pydicom.dcmread(impath, force=True) img = ds.pixel_array.astype(float) if 'WindowWidth' in ds: #print('Dataset has windowing') windowed = apply_voi_lut(ds.pixel_array, ds) #plt.imshow(windowed, cmap="gray", vmax=windowed.max(), vmin=windowed.min) #plt.show() img = windowed.astype(float) #return "windowed" # Convert to uint img = (np.maximum(img, 0) / img.max()) * 255.0 img = np.uint8(img) img = cv2.merge([img, img, img]) #img = cv2.COLOR_GRAY2RGB() #(ori_h,ori_w)=img.shape print("annotation by ", first_doctor) anns_1 = extract_annotation(json_path_1) print("annotation by ", second_doctor) anns_2 = extract_annotation(json_path_2)