def dsc(y_pred, y_true, lcc=True): if lcc and np.any(y_pred): y_pred = np.round(y_pred).astype(int) y_true = np.round(y_true).astype(int) y_pred = largest_connected_component(y_pred) return np.sum( y_pred[y_true == 1]) * 2.0 / (np.sum(y_pred) + np.sum(y_true))
def ask(self, image_b64): decoded = base64.b64decode(image_b64) img = Image.open(BytesIO(decoded)).convert("RGB") img = img.resize((256, 256)) img = normalize_volume(np.array(img)) img = self.transform(img) img = img.to(self.device) pred = self.model(img) seg_mask = pred.squeeze(0).squeeze(0).detach().cpu().numpy() seg_mask = np.round(seg_mask).astype(int) if len(seg_mask[seg_mask != 0]) != 0: seg_mask = largest_connected_component(seg_mask) else: raise BaseException("nothing found") initial_image = img.reshape((3, 256, 256))[1] initial_image = initial_image.reshape( (256, 256)).detach().cpu().numpy() initial_image = gray2rgb(initial_image) outlined_img = outline(initial_image, seg_mask, color=[255, 0, 0]) out_img = Image.fromarray(outlined_img) imgByteArr = BytesIO() out_img.save(imgByteArr, format="PNG") imgByteArr = imgByteArr.getvalue() return imgByteArr
def main(): args = getArguments(getParser()) # prepare logger logger = Logger.getInstance() if args.debug: logger.setLevel(logging.DEBUG) elif args.verbose: logger.setLevel(logging.INFO) # loading input images b0img, b0hdr = load(args.b0image) bximg, bxhdr = load(args.bximage) # convert to float b0img = b0img.astype(numpy.float) bximg = bximg.astype(numpy.float) # check if image are compatible if not b0img.shape == bximg.shape: raise ArgumentError('The input images shapes differ i.e. {} != {}.'.format(b0img.shape, bximg.shape)) if not header.get_pixel_spacing(b0hdr) == header.get_pixel_spacing(bxhdr): raise ArgumentError('The input images voxel spacing differs i.e. {} != {}.'.format(header.get_pixel_spacing(b0hdr), header.get_pixel_spacing(bxhdr))) # check if supplied threshold value as well as the b value is above 0 if args.threshold is not None and not args.threshold >= 0: raise ArgumentError('The supplied threshold value must be greater than 0, otherwise a division through 0 might occur.') if not args.b > 0: raise ArgumentError('The supplied b-value must be greater than 0.') # compute threshold value if not supplied if args.threshold is None: b0thr = otsu(b0img, 32) / 4. # divide by 4 to decrease impact bxthr = otsu(bximg, 32) / 4. if 0 >= b0thr: raise ArgumentError('The supplied b0image seems to contain negative values.') if 0 >= bxthr: raise ArgumentError('The supplied bximage seems to contain negative values.') else: b0thr = bxthr = args.threshold logger.debug('thresholds={}/{}, b-value={}'.format(b0thr, bxthr, args.b)) # threshold b0 + bx DW image to obtain a mask # b0 mask avoid division through 0, bx mask avoids a zero in the ln(x) computation mask = binary_fill_holes(b0img > b0thr) & binary_fill_holes(bximg > bxthr) # perform a number of binary morphology steps to select the brain only mask = binary_erosion(mask, iterations=1) mask = largest_connected_component(mask) mask = binary_dilation(mask, iterations=1) logger.debug('excluding {} of {} voxels from the computation and setting them to zero'.format(numpy.count_nonzero(mask), numpy.prod(mask.shape))) # compute the ADC adc = numpy.zeros(b0img.shape, b0img.dtype) adc[mask] = -1. * args.b * numpy.log(bximg[mask] / b0img[mask]) adc[adc < 0] = 0 # saving the resulting image save(adc, args.output, b0hdr, args.force)
def postprocess_per_volume(input_list, pred_list, true_list, patient_slice_index, patients): volumes = {} num_slices = np.bincount([p[0] for p in patient_slice_index]) index = 0 for p in range(len(num_slices)): volume_in = np.array(input_list[index:index + num_slices[p]]) volume_pred = np.round(np.array(pred_list[index:index + num_slices[p]])).astype(int) volume_pred = largest_connected_component(volume_pred) volume_true = np.array(true_list[index:index + num_slices[p]]) volumes[patients[p]] = (volume_in, volume_pred, volume_true) index += num_slices[p] return volumes
def postprocess_per_volume(input_list, pred_list, true_list, patient_slice_index, patients): volumes = {} num_slices = np.bincount([p[0] for p in patient_slice_index]) index = 0 for p in range(len(num_slices)): volume_in = np.array(input_list[index:index + num_slices[p]]) volume_pred = np.round(np.array(pred_list[index:index + num_slices[p]])).astype(int) volume_pred = largest_connected_component(volume_pred) volume_true = np.array(true_list[index:index + num_slices[p]]) volumes[patients[p]] = (volume_in, volume_pred, volume_true) index += num_slices[p] # pdb.set_trace() # (Pdb) pp type(volumes), len(volumes), volumes['TCGA_DU_7010_19860307'][0].shape # (<class 'dict'>, 10, (55, 3, 256, 256)) return volumes
y_true_np = y_true.detach().cpu().numpy() true_list.extend([y_true_np[s] for s in range(y_true_np.shape[0])]) x_np = x.detach().cpu().numpy() input_list.extend([x_np[s] for s in range(x_np.shape[0])]) volumes = {} num_slices = np.bincount([p[0] for p in loader.dataset.patient_slice_index]) index = 0 for p in range(len(num_slices)): volume_in = np.array(input_list[index : index + num_slices[p]]) volume_pred = np.round(np.array(pred_list[index : index + num_slices[p]])).astype(int) volume_pred = largest_connected_component(volume_pred) volume_true = np.array(true_list[index : index + num_slices[p]]) volumes[loader.dataset.patients[p]] = (volume_in, volume_pred, volume_true) index += num_slices[p] dsc_dict = {} for p in volumes: y_pred = volumes[p][1] y_true = volumes[p][2] dsc_dict[p] = dsc(y_pred, y_true, lcc=False) y_positions = np.arange(len(dsc_dict)) dsc_dict = sorted(dsc_dict.items(), key=lambda x: x[1]) values = [x[1] for x in dsc_dict]
def main(): args = getArguments(getParser()) # prepare logger logger = Logger.getInstance() if args.debug: logger.setLevel(logging.DEBUG) elif args.verbose: logger.setLevel(logging.INFO) # loading input images b0img, b0hdr = load(args.b0image) bximg, bxhdr = load(args.bximage) # convert to float b0img = b0img.astype(numpy.float) bximg = bximg.astype(numpy.float) # check if image are compatible if not b0img.shape == bximg.shape: raise ArgumentError( 'The input images shapes differ i.e. {} != {}.'.format( b0img.shape, bximg.shape)) if not header.get_pixel_spacing(b0hdr) == header.get_pixel_spacing(bxhdr): raise ArgumentError( 'The input images voxel spacing differs i.e. {} != {}.'.format( header.get_pixel_spacing(b0hdr), header.get_pixel_spacing(bxhdr))) # check if supplied threshold value as well as the b value is above 0 if args.threshold is not None and not args.threshold >= 0: raise ArgumentError( 'The supplied threshold value must be greater than 0, otherwise a division through 0 might occur.' ) if not args.b > 0: raise ArgumentError('The supplied b-value must be greater than 0.') # compute threshold value if not supplied if args.threshold is None: b0thr = otsu(b0img, 32) / 4. # divide by 4 to decrease impact bxthr = otsu(bximg, 32) / 4. if 0 >= b0thr: raise ArgumentError( 'The supplied b0image seems to contain negative values.') if 0 >= bxthr: raise ArgumentError( 'The supplied bximage seems to contain negative values.') else: b0thr = bxthr = args.threshold logger.debug('thresholds={}/{}, b-value={}'.format(b0thr, bxthr, args.b)) # threshold b0 + bx DW image to obtain a mask # b0 mask avoid division through 0, bx mask avoids a zero in the ln(x) computation mask = binary_fill_holes(b0img > b0thr) & binary_fill_holes(bximg > bxthr) # perform a number of binary morphology steps to select the brain only mask = binary_erosion(mask, iterations=1) mask = largest_connected_component(mask) mask = binary_dilation(mask, iterations=1) logger.debug( 'excluding {} of {} voxels from the computation and setting them to zero' .format(numpy.count_nonzero(mask), numpy.prod(mask.shape))) # compute the ADC adc = numpy.zeros(b0img.shape, b0img.dtype) adc[mask] = -1. * args.b * numpy.log(bximg[mask] / b0img[mask]) adc[adc < 0] = 0 # saving the resulting image save(adc, args.output, b0hdr, args.force)