Ejemplo n.º 1
0
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))
Ejemplo n.º 2
0
    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)
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
        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]
Ejemplo n.º 7
0
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)