def generate_positive_batch(set):
    os.makedirs(LIDC_IDRI_BATCHES_PREFIX, exist_ok=True)
    os.makedirs(os.path.join(LIDC_IDRI_BATCHES_PREFIX, set), exist_ok=True)

    indexes = scan_index_split(1018)[{'train': 0, 'valid': 1, 'test': 2}[set]]

    X = np.ndarray((0, 64, 64, 16, 1), dtype=np.float)
    with closing(Pool(processes=2)) as workers:
        for positive_patches in tqdm(workers.imap(_mp_get_positive_batch,
                                                  indexes),
                                     desc='generate_positive_batch',
                                     total=len(indexes)):
            X = np.append(X, positive_patches, axis=0)

    filename = os.path.join(LIDC_IDRI_BATCHES_PREFIX, set, 'positive.npy')
    np.save(filename, X)
    return None
    def __init__(self, set_name, index, **kwargs):
        def preprocess_image(image):
            """ Preprocess image and its annotations.
            """
            MEAN, STD = 174., 825.
            # image = (image - image.mean()) / image.std()
            image = (image - MEAN) / STD
            return image

        self.set_name = set_name
        self.scan_index = scan_index_split(1018)[{
            'train': 0,
            'valid': 1,
            'test': 2
        }[set_name]][index]
        self.scan = pl.query(pl.Scan).filter()[self.scan_index]
        self.X, self.y = get_patches(self.scan, negative_ratio=2.)
        super(LungScanGenerator, self).__init__(**dict(
            kwargs, group_method='none', preprocess_image=preprocess_image))
def batch_generatorV3(set, batch_size, negative_ratio=0.9, n_batch_per_scan=10, n_scan_bundle=5):
    # load positive patches
    positive_patches = np.load(os.path.join(LIDC_IDRI_BATCHES_PREFIX, set, 'positive.npy'), mmap_mode='r')
    # load all detections from fast_detection_model
    all_detections = pickle.load(open(os.path.join(LIDC_IDRI_BATCHES_PREFIX, set, 'all_detections.pl'), 'rb'))
    indexes = scan_index_split(1018)[{'train': 0, 'valid': 1, 'test': 2}[set]]

    while True:
        # load random scan
        negative_Xs, negative_ys = list(), list()
        for i in range(n_scan_bundle):
            index_scan = np.random.choice(indexes)
            volume, lung_mask, nodule_mask, layer_probability = get_scan(index_scan)
            if volume is None:
                continue

            for index_detection in np.random.randint(len(all_detections[index_scan]), size=int(n_batch_per_scan*batch_size*negative_ratio)):
                d = all_detections[index_scan][index_detection] # [x0, y0, x1, y1, z, score]
                x, y, z = int((d[0]+d[2])/2), int((d[1]+d[3])/2), int(d[4])
                patch, label = extract_patch(volume, nodule_mask, x, y, z)
                if patch is None:
                    continue

                # normalize
                negative_Xs.append(patch)
                negative_ys.append([label, 1-label])

        negative_Xs, negative_ys = np.array(negative_Xs), np.array(negative_ys)

        for i in range(n_batch_per_scan*n_scan_bundle):
            # randomly choose positive patches
            positive_X = positive_patches[np.random.randint(positive_patches.shape[0], size=int(batch_size*(1.-negative_ratio))), ...]
            positive_y = np.array([[1, 0]]*positive_X.shape[0])

            negative_indexes = np.random.randint(negative_Xs.shape[0], size=int(batch_size*negative_ratio))
            negative_X = negative_Xs[negative_indexes, ...]
            negative_y = negative_ys[negative_indexes, ...]

            # generate batch
            X = np.append(negative_X, positive_X, axis=0)
            y = np.append(negative_y, positive_y, axis=0)
            X = (X - 418.) / 414. # normalize
            yield shuffle(X, y)
def generate_negative_detections(set, model_path):
    os.makedirs(LIDC_IDRI_BATCHES_PREFIX, exist_ok=True)
    os.makedirs(os.path.join(LIDC_IDRI_BATCHES_PREFIX, set), exist_ok=True)

    indexes = scan_index_split(1018)[{'train': 0, 'valid': 1, 'test': 2}[set]]

    # load fast-detection model to generate false positive patches
    print('Loading model, this may take a second...')
    fast_detection_model = models.load_model(model_path,
                                             'p3d',
                                             nms=True,
                                             convert=True)

    all_detections = dict()
    for index_scan in tqdm(indexes, desc='generate_negative_detections'):
        scan_detections = list()
        # load scan
        volume, lung_mask, nodule_mask, layer_probability = get_scan(
            index_scan)
        if volume is None:
            continue

        fast_detection_generator = ScanGenerator(volume)
        fast_detections = get_fast_detection(
            generator=fast_detection_generator,
            model=fast_detection_model,
            score_threshold=0.05,
            max_detections=30,
            verbose=True,
            save_path=None,
            do_draw_annotations=False)

        for z in np.arange(len(fast_detections)) + 8:
            for d in fast_detections[z - 8][0]:
                scan_detections.append([d[0], d[1], d[2], d[3], z, d[4]])
        all_detections[index_scan] = scan_detections

    filename = os.path.join(LIDC_IDRI_BATCHES_PREFIX, set, 'all_detections.pl')
    with open(filename, 'wb') as out_pl:
        pickle.dump(all_detections, out_pl)
    return None
def batch_generatorV2(set, batch_size, negative_ratio=0.9, n_batch_per_scan=10, n_scan_bundle=5):
    # load positive patches
    positive_patches = np.load(os.path.join(LIDC_IDRI_BATCHES_PREFIX, set, 'positive.npy'))
    indexes = scan_index_split(1018)[{'train': 0, 'valid': 1, 'test': 2}[set]]

    while True:
        # load random scan
        negative_Xs, negative_ys = np.ndarray((0, 64, 64, 16, 1), dtype=np.float), np.ndarray((0, 2), dtype=np.float)

        for i in range(n_scan_bundle):
            volume, lung_mask, nodule_mask, layer_probability = get_scan(np.random.choice(indexes))
            if volume is None:
                continue

            tmp_Xs, tmp_ys = get_patches(volume=volume,
                                            size=int(batch_size*negative_ratio*n_batch_per_scan),
                                            is_positive=False,
                                            lung_mask=lung_mask,
                                            nodule_mask=nodule_mask,
                                            layer_probability=layer_probability,
                                            patch_size=(64, 64, 16))
            negative_Xs = np.append(tmp_Xs, negative_Xs, axis=0)
            negative_ys = np.append(tmp_ys, negative_ys, axis=0)

        for i in range(n_batch_per_scan*n_scan_bundle):
            # randomly choose positive patches
            positive_X = positive_patches[np.random.randint(positive_patches.shape[0], size=int(batch_size*(1.-negative_ratio))), ...]
            positive_y = np.array([[1, 0]]*positive_X.shape[0])

            negative_indexes = np.random.randint(negative_Xs.shape[0], size=int(batch_size*negative_ratio))
            negative_X = negative_Xs[negative_indexes, ...]
            negative_y = negative_ys[negative_indexes, ...]

            # generate batch
            X = np.append(negative_X, positive_X, axis=0)
            y = np.append(negative_y, positive_y, axis=0)
            X = (X - 418.) / 414. # normalize
            yield shuffle(X, y)
def predict(set, index):
    index_scan = scan_index_split(1018)[{
        'train': 0,
        'valid': 1,
        'test': 2
    }[set]][index]
    scans = pl.query(pl.Scan).filter()

    volume = scans[index_scan].to_volume()

    # load the models
    print('Loading model, this may take a second...')
    fast_detection_model = models.load_model(
        FAST_DETECTION_PARM['path'],
        backbone_name=FAST_DETECTION_PARM['backbone'],
        nms=True,
        convert=FAST_DETECTION_PARM['convert_model'])
    # fast_detection_model.summary()

    fpr_model = load_model(FPR_MODEL_PATH)
    fpr_model = keras.utils.multi_gpu_model(fpr_model)

    fast_detection_generator = ScanGenerator(volume)
    fast_detection = get_fast_detection(generator=fast_detection_generator,
                                        model=fast_detection_model,
                                        score_threshold=0.05,
                                        max_detections=30,
                                        verbose=True,
                                        save_path=None,
                                        do_draw_annotations=False)

    # false positive reduction
    result = false_positive_reduction(volume, fast_detection, fpr_model)

    with open('result.pl', 'wb') as f:
        pickle.dump(result, f)

    return index_scan, volume, result
def patch_generator(set='train',
                    batch_size=32,
                    batch_per_scan=50,
                    patch_size=(64, 64, 16)):
    # scans = pl.query(pl.Scan).filter()
    train, valid, test = scan_index_split(1018)
    if set == 'train':
        indexes = train
    elif set == 'valid':
        indexes = valid
    else:
        indexes = test

    while True:
        scan_index = random.choice(indexes)  # randomly choose one scan
        volume, lung_mask, nodule_mask, layer_probability = get_scan(
            scan_index)

        # validate
        if volume is None:
            continue

        # yield batch_per_scan number of batches
        for bi in range(batch_per_scan):
            # get batch_size // 2 negative patches
            negative_patches = get_patches(volume, batch_size // 2, False,
                                           lung_mask, nodule_mask,
                                           layer_probability)
            positive_patches = get_patches(volume, batch_size // 2, True,
                                           lung_mask, nodule_mask,
                                           layer_probability)
            X = negative_patches[0] + positive_patches[0]
            y = negative_patches[1] + positive_patches[1]
            X, y = shuffle(np.array(X), np.array(y))
            X = (X - 418.) / 414.
            yield X, y