def __init__(self, directory, image_data_generator,
                 resize=None, target_size=None, color_mode='rgb',
                 dim_ordering='default',
                 classes=None, class_mode='categorical',
                 batch_size=32, shuffle=True, seed=None, gt_directory=None,
                 save_to_dir=None, save_prefix='', save_format='jpeg', model_name=None):
        # Check dim order
        if dim_ordering == 'default':
            dim_ordering = K.image_dim_ordering()
        self.dim_ordering = dim_ordering

        self.directory = directory
        self.gt_directory = gt_directory
        self.image_data_generator = image_data_generator
        self.resize = resize
        self.save_to_dir = save_to_dir
        self.save_prefix = save_prefix
        self.save_format = save_format

        self.model_name = model_name

        # Check target size
        if target_size is None and batch_size > 1:
            raise ValueError('Target_size None works only with batch_size=1')
        self.target_size = (None, None) if target_size is None else tuple(target_size)

        # Check color mode
        if color_mode not in {'rgb', 'grayscale', 'bgr'}:
            raise ValueError('Invalid color mode:', color_mode,
                             '; expected "rgb" or "grayscale".')
        self.color_mode = color_mode
        if self.color_mode == 'rgb' or self.color_mode == 'bgr':
            self.grayscale = False
            if self.dim_ordering == 'tf':
                self.image_shape = self.target_size + (3,)
                self.gt_image_shape = self.target_size + (1,)
            else:
                self.image_shape = (3,) + self.target_size
                self.gt_image_shape = (1,) + self.target_size
        else:
            self.grayscale = True
            if self.dim_ordering == 'tf':
                self.image_shape = self.target_size + (1,)
                self.gt_image_shape = self.image_shape
            else:
                self.image_shape = (1,) + self.target_size
                self.gt_image_shape = self.image_shape

        # Check class mode
        if class_mode not in {'categorical', 'binary', 'sparse',
                              'segmentation', 'detection', None}:
            raise ValueError('Invalid class_mode:', class_mode,
                             '; expected one of "categorical", '
                             '"binary", "sparse", "segmentation", "detection" or None.')
        self.class_mode = class_mode
        self.has_gt_image = True if self.class_mode == 'segmentation' else False

        # Check class names
        if not classes:
            if self.class_mode == 'segmentation' or self.class_mode == 'detection':
                raise ValueError('You should input the class names')
            else:
                classes = list_subdirs(directory)
        else:
            classes = classes.values()
        self.nb_class = len(classes)
        self.class_indices = dict(zip(classes, range(len(classes))))

        self.nb_sample = 0
        self.filenames = []
        self.classes = []

        # Get filenames
        if self.class_mode == 'detection':
            for fname in os.listdir(directory):
                if has_valid_extension(fname):
                    self.filenames.append(fname)
                    # Look for the GT filename
                    gt_fname = os.path.join(directory,fname.replace('jpg','txt'))
                    if not os.path.isfile(gt_fname):
                        raise ValueError('GT file not found: ' + gt_fname)
            self.filenames = np.sort(self.filenames)

            if self.model_name == 'ssd':
              priors = pickle.load(open('weights/prior_boxes_ssd300.pkl', 'rb'))
              self.bbox_util = BBoxUtility(self.nb_class+1, priors)

        elif not self.class_mode == 'segmentation':
            for subdir in classes:
                subpath = os.path.join(directory, subdir)
                for fname in os.listdir(subpath):
                    if has_valid_extension(fname):
                        self.classes.append(self.class_indices[subdir])
                        self.filenames.append(os.path.join(subdir, fname))
            self.classes = np.array(self.classes)
        else:
            for fname in os.listdir(gt_directory):
                if has_valid_extension(fname):
                    self.filenames.append(fname)
                    # Look for the GT filename
                    gt_fname = os.path.join(gt_directory,
                                            os.path.split(fname)[1])
                    if not os.path.isfile(gt_fname):
                        raise ValueError('GT file not found: ' + gt_fname)
            self.filenames = np.sort(self.filenames)

        self.nb_sample = len(self.filenames)
        print('   Found %d images belonging to %d classes' % (self.nb_sample,
                                                            self.nb_class))

        super(DirectoryIterator, self).__init__(self.nb_sample, batch_size,
                                                shuffle, seed)
class DirectoryIterator(Iterator):

    def __init__(self, directory, image_data_generator,
                 resize=None, target_size=None, color_mode='rgb',
                 dim_ordering='default',
                 classes=None, class_mode='categorical',
                 batch_size=32, shuffle=True, seed=None, gt_directory=None,
                 save_to_dir=None, save_prefix='', save_format='jpeg', model_name=None):
        # Check dim order
        if dim_ordering == 'default':
            dim_ordering = K.image_dim_ordering()
        self.dim_ordering = dim_ordering

        self.directory = directory
        self.gt_directory = gt_directory
        self.image_data_generator = image_data_generator
        self.resize = resize
        self.save_to_dir = save_to_dir
        self.save_prefix = save_prefix
        self.save_format = save_format

        self.model_name = model_name

        # Check target size
        if target_size is None and batch_size > 1:
            raise ValueError('Target_size None works only with batch_size=1')
        self.target_size = (None, None) if target_size is None else tuple(target_size)

        # Check color mode
        if color_mode not in {'rgb', 'grayscale', 'bgr'}:
            raise ValueError('Invalid color mode:', color_mode,
                             '; expected "rgb" or "grayscale".')
        self.color_mode = color_mode
        if self.color_mode == 'rgb' or self.color_mode == 'bgr':
            self.grayscale = False
            if self.dim_ordering == 'tf':
                self.image_shape = self.target_size + (3,)
                self.gt_image_shape = self.target_size + (1,)
            else:
                self.image_shape = (3,) + self.target_size
                self.gt_image_shape = (1,) + self.target_size
        else:
            self.grayscale = True
            if self.dim_ordering == 'tf':
                self.image_shape = self.target_size + (1,)
                self.gt_image_shape = self.image_shape
            else:
                self.image_shape = (1,) + self.target_size
                self.gt_image_shape = self.image_shape

        # Check class mode
        if class_mode not in {'categorical', 'binary', 'sparse',
                              'segmentation', 'detection', None}:
            raise ValueError('Invalid class_mode:', class_mode,
                             '; expected one of "categorical", '
                             '"binary", "sparse", "segmentation", "detection" or None.')
        self.class_mode = class_mode
        self.has_gt_image = True if self.class_mode == 'segmentation' else False

        # Check class names
        if not classes:
            if self.class_mode == 'segmentation' or self.class_mode == 'detection':
                raise ValueError('You should input the class names')
            else:
                classes = list_subdirs(directory)
        else:
            classes = classes.values()
        self.nb_class = len(classes)
        self.class_indices = dict(zip(classes, range(len(classes))))

        self.nb_sample = 0
        self.filenames = []
        self.classes = []

        # Get filenames
        if self.class_mode == 'detection':
            for fname in os.listdir(directory):
                if has_valid_extension(fname):
                    self.filenames.append(fname)
                    # Look for the GT filename
                    gt_fname = os.path.join(directory,fname.replace('jpg','txt'))
                    if not os.path.isfile(gt_fname):
                        raise ValueError('GT file not found: ' + gt_fname)
            self.filenames = np.sort(self.filenames)

            if self.model_name == 'ssd':
              priors = pickle.load(open('weights/prior_boxes_ssd300.pkl', 'rb'))
              self.bbox_util = BBoxUtility(self.nb_class+1, priors)

        elif not self.class_mode == 'segmentation':
            for subdir in classes:
                subpath = os.path.join(directory, subdir)
                for fname in os.listdir(subpath):
                    if has_valid_extension(fname):
                        self.classes.append(self.class_indices[subdir])
                        self.filenames.append(os.path.join(subdir, fname))
            self.classes = np.array(self.classes)
        else:
            for fname in os.listdir(gt_directory):
                if has_valid_extension(fname):
                    self.filenames.append(fname)
                    # Look for the GT filename
                    gt_fname = os.path.join(gt_directory,
                                            os.path.split(fname)[1])
                    if not os.path.isfile(gt_fname):
                        raise ValueError('GT file not found: ' + gt_fname)
            self.filenames = np.sort(self.filenames)

        self.nb_sample = len(self.filenames)
        print('   Found %d images belonging to %d classes' % (self.nb_sample,
                                                            self.nb_class))

        super(DirectoryIterator, self).__init__(self.nb_sample, batch_size,
                                                shuffle, seed)

    def next(self):
        # Lock the generation of index only. The rest is not under thread
        # lock so it can be done in parallel
        with self.lock:
            index_array, current_index, current_batch_size = next(self.index_generator)

        # Create the batch_x and batch_y
        if current_batch_size > 1:
            batch_x = np.zeros((current_batch_size,) + self.image_shape)
            if self.has_gt_image:
                batch_y = np.zeros((current_batch_size,) + self.gt_image_shape)
            if self.class_mode == 'detection':
                batch_y = []

        # Build batch of image data
        for i, j in enumerate(index_array):
            # Load image
            fname = self.filenames[j]
            # print(fname)
            img = load_img(os.path.join(self.directory, fname),
                           grayscale=self.grayscale,
                           resize=self.resize, order=1)
            x = img_to_array(img, dim_ordering=self.dim_ordering)

            # Load GT image if segmentation
            if self.has_gt_image:
                # Load GT image
                gt_img = load_img(os.path.join(self.gt_directory, fname),
                                  grayscale=True,
                                  resize=self.resize, order=0)
                y = img_to_array(gt_img, dim_ordering=self.dim_ordering)
            else:
                y = None

            # Load GT image if detection
            if self.class_mode == 'detection':
                label_path = os.path.join(self.directory, fname).replace('jpg','txt')
                gt = np.loadtxt(label_path)
                if len(gt.shape) == 1:
                    gt = gt[np.newaxis,]
                y = gt.copy()
                y = y[((y[:,1] > 0.) & (y[:,1] < 1.))]
                y = y[((y[:,2] > 0.) & (y[:,2] < 1.))]
                y = y[((y[:,3] > 0.) & (y[:,3] < 1.))]
                y = y[((y[:,4] > 0.) & (y[:,4] < 1.))]
                if (y.shape != gt.shape) or (y.shape[0] == 0):
                    warnings.warn('DirectoryIterator: found an invalid annotation '
                                  'on GT file '+label_path)
                # shuffle gt boxes order
                np.random.shuffle(y)


            # Standarize image
            x = self.image_data_generator.standardize(x, y)

            # Data augmentation
            x, y = self.image_data_generator.random_transform(x, y)

            # Add images to batches
            if current_batch_size > 1:
                batch_x[i] = x
                if self.has_gt_image:
                    batch_y[i] = y
                elif self.class_mode == 'detection':
                    batch_y.append(y)
            else:
                batch_x = np.expand_dims(x, axis=0)
                if self.has_gt_image:
                    batch_y = np.expand_dims(y, axis=0)
                elif self.class_mode == 'detection':
                    batch_y = [y]

        # optionally save augmented images to disk for debugging purposes
        if self.save_to_dir:
            for i in range(current_batch_size):

                fname = '{prefix}_{index}_{hash}.{format}'.format(prefix=self.save_prefix,
                                                                  index=current_index + i,
                                                                  hash=np.random.randint(1e4),
                                                                  format=self.save_format)

                if self.class_mode == 'segmentation':
                    nclasses = self.classes  # TODO: Change
                    color_map = sns.hls_palette(nclasses+1)
                    void_label = nclasses
                    save_img2(batch_x[i], batch_y[i],
                              os.path.join(self.save_to_dir, fname), color_map,
                              void_label)

                else:
                    img = array_to_img(batch_x[i], self.dim_ordering,
                                       scale=True)
                    img.save(os.path.join(self.save_to_dir, fname))

        # Build batch of labels
        if self.class_mode == 'sparse':
            batch_y = self.classes[index_array]

        elif self.class_mode == 'binary':
            batch_y = self.classes[index_array].astype('float32')

        elif self.class_mode == 'categorical':
            batch_y = np.zeros((len(batch_x), self.nb_class), dtype='float32')
            for i, label in enumerate(self.classes[index_array]):
                batch_y[i, label] = 1.

        elif self.class_mode == 'detection':
            if 'yolo' in self.model_name:
                batch_y = yolo_build_gt_batch(batch_y, self.image_shape, self.nb_class)

            elif self.model_name == 'ssd':
                batch_y = self.bbox_util.ssd_build_gt_batch_v2(batch_y)

                # targets = []
                # for boxes in batch_y:
                #   boxes_corrected = np.zeros((boxes.shape[0], 4+self.nb_class))
                #   for b,box in enumerate(boxes):
                #     boxes_corrected[b,0] = box[1] - box[3]/2
                #     boxes_corrected[b,1] = box[2] - box[4]/2
                #     boxes_corrected[b,2] = box[1] + box[3]/2
                #     boxes_corrected[b,3] = box[2] + box[4]/2
                #     c = 4+int(box[0])
                #     boxes_corrected[b,c] = 1.
                #   boxes_corrected = self.bbox_util.assign_boxes(boxes_corrected)
                #   targets.append(boxes_corrected)
                # batch_y = np.array(targets)

        elif self.class_mode == None:
            return batch_x

        return batch_x, batch_y
Example #3
0
    def load(self):
        config_path = self.config_path
        exp_name = self.exp_name
        dataset_path = self.dataset_path
        shared_dataset_path = self.shared_dataset_path
        experiments_path = self.experiments_path
        shared_experiments_path = self.shared_experiments_path

        # Load configuration file
        print config_path
        cf = imp.load_source('config', config_path)

        # Save extra parameter
        cf.config_path = config_path
        cf.exp_name = exp_name

        # Create output folders
        cf.savepath = os.path.join(experiments_path, cf.dataset_name,
                                   cf.exp_name)
        cf.final_savepath = os.path.join(shared_experiments_path,
                                         cf.dataset_name, cf.exp_name)
        cf.log_file = os.path.join(cf.savepath, "logfile.log")
        if not os.path.exists(cf.savepath):
            os.makedirs(cf.savepath)
        cf.usr_path = self.usr_path

        # Copy config file
        shutil.copyfile(config_path, os.path.join(cf.savepath, "config.py"))

        # Load dataset configuration
        cf.dataset = self.load_config_dataset(cf.dataset_name, dataset_path,
                                              shared_dataset_path,
                                              cf.problem_type,
                                              'config_dataset')
        if cf.dataset_name2:
            cf.dataset2 = self.load_config_dataset(cf.dataset_name2,
                                                   dataset_path,
                                                   shared_dataset_path,
                                                   cf.problem_type,
                                                   'config_dataset2')

        # If in Debug mode use few images
        if cf.debug and cf.debug_images_train > 0:
            cf.dataset.n_images_train = cf.debug_images_train
        if cf.debug and cf.debug_images_valid > 0:
            cf.dataset.n_images_valid = cf.debug_images_valid
        if cf.debug and cf.debug_images_test > 0:
            cf.dataset.n_images_test = cf.debug_images_test
        if cf.debug and cf.debug_n_epochs > 0:
            cf.n_epochs = cf.debug_n_epochs

        # Define target sizes
        if cf.crop_size_train is not None:
            cf.target_size_train = cf.crop_size_train
        elif cf.resize_train is not None:
            cf.target_size_train = cf.resize_train
        else:
            cf.target_size_train = cf.dataset.img_shape

        if cf.crop_size_valid is not None:
            cf.target_size_valid = cf.crop_size_valid
        elif cf.resize_valid is not None:
            cf.target_size_valid = cf.resize_valid
        else:
            cf.target_size_valid = cf.dataset.img_shape

        if cf.crop_size_test is not None:
            cf.target_size_test = cf.crop_size_test
        elif cf.resize_test is not None:
            cf.target_size_test = cf.resize_test
        else:
            cf.target_size_test = cf.dataset.img_shape

        # Get training weights file name
        path, _ = os.path.split(cf.weights_file)
        if path == '':
            cf.weights_file = os.path.join(cf.savepath, cf.weights_file)

        # Get testing weights file name
        try:
            path_test, _ = os.path.split(cf.weights_test_file)
            if path_test == '':
                cf.weights_test_file = os.path.join(cf.savepath,
                                                    cf.weights_test_file)
        except:
            cf.weights_test_file = os.path.join(cf.savepath, 'weights.hdf5')

        # Plot metrics
        if cf.dataset.class_mode == 'segmentation':
            #cf.train_metrics = ['loss', 'acc', 'jaccard']
            #cf.valid_metrics = ['val_loss', 'val_acc', 'val_jaccard']
            #cf.best_metric = 'val_jaccard'
            class_weights_path = os.path.join(self.usr_path, 'extra',
                                              cf.dataset_name + '.pkl')

            if not os.path.exists(class_weights_path):
                cf.dataset.cb_weights2 = None
                print('No weights are available for weighted cross-entropy')
            else:
                cf.dataset.cb_weights2 = pickle.load(
                    open(class_weights_path, 'rb'))

            cf.train_metrics = ['loss', 'acc', 'jaccard_coef']
            cf.valid_metrics = ['val_loss', 'val_acc', 'val_jaccard_coef']
            cf.best_metric = 'val_jaccard_coef'
            cf.best_type = 'max'
        elif cf.dataset.class_mode == 'detection':
            # TODO detection : different nets may have other metrics
            cf.train_metrics = ['loss', 'avg_recall', 'avg_iou']
            cf.valid_metrics = ['val_loss', 'val_avg_recall', 'val_avg_iou']
            cf.best_metric = 'val_avg_recall'
            cf.best_type = 'max'
            if cf.model_name == 'ssd':
                cf.dataset.priors = pickle.load(
                    open(
                        os.path.join(self.usr_path, 'extra',
                                     'prior_boxes_ssd300.pkl'), 'rb'))
                cf.bbox_util = BBoxUtility(cf.dataset.n_classes,
                                           cf.dataset.priors)
        else:
            cf.train_metrics = ['loss', 'acc']
            cf.valid_metrics = ['val_loss', 'val_acc']
            cf.best_metric = 'val_acc'
            cf.best_type = 'max'

        self.configuration = cf
        return cf
        ])
        num_images_chunk = images.shape[0]
        net_out = model.predict(images, batch_size=8, verbose=1)

        # Store the predictions
        for ind in range(num_images_chunk):
            if model_name == 'yolo' or model_name == 'tiny-yolo':
                boxes_pred = yolo_postprocess_net_out(net_out[ind], priors,
                                                      classes,
                                                      detection_threshold,
                                                      nms_threshold)
            else:
                priors = pickle.load(open('prior_boxes_ssd300.pkl', 'rb'))
                real_num_classes = num_classes - 1  # Background is not included
                bbox_util = BBoxUtility(real_num_classes,
                                        priors=priors,
                                        nms_thresh=nms_threshold)
                boxes_pred = bbox_util.detection_out(
                    net_out[ind],
                    background_label_id=0,
                    confidence_threshold=detection_threshold)

            current_img = images[ind]
            if 'yolo' in model_name:
                current_img = np.transpose(current_img, (1, 2, 0))
            plt.imshow(current_img)
            currentAxis = plt.gca()

            # Compute number of predictions that match with GT with a minimum of 50% IoU
            for b in boxes_pred:
                pred_idx = np.argmax(b.probs)
Example #5
0
    print "ERR: path_to_images do not contain any jpg file"
    quit()

inputs = []
img_paths = []
chunk_size = 128 # we are going to process all image files in chunks

ok = 0.
total_true = 0.
total_pred = 0.
total_p = 0.
total_r = 0.
iters = 0
total_fps = 0.

bbox_util = BBoxUtility(NUM_CLASSES-1, nms_thresh=nms_threshold) # -1 because the void class is added inside

for i,img_path in enumerate(imfiles):
    img = image.load_img(img_path, target_size=(input_shape[0], input_shape[1]))
    img = image.img_to_array(img)
    img = img / 255.
    inputs.append(img.copy())
    img_paths.append(img_path)

    if len(img_paths)%chunk_size == 0 or i+1 == len(imfiles):
        inputs = np.array(inputs)
        start_time = time.time()
        net_out = model.predict(inputs, batch_size=16, verbose=1)
        print ('{} images predicted in {:.5f} seconds. {:.5f} fps').format(len(inputs),time.time() - start_time,(len(inputs)/(time.time() - start_time)))
        total_fps = total_fps + len(inputs)/(time.time() - start_time)
        # predicted boxes
Example #6
0
    def next(self):
        # Lock the generation of index only. The rest is not under thread
        # lock so it can be done in parallel
        with self.lock:
            index_array, current_index, current_batch_size = next(self.index_generator)

        # Create the batch_x and batch_y
        if current_batch_size > 1:
            batch_x = np.zeros((current_batch_size,) + self.image_shape)
            if self.has_gt_image:
                batch_y = np.zeros((current_batch_size,) + self.gt_image_shape)
            if self.class_mode == 'detection':
                batch_y = []

        # Build batch of image data
        for i, j in enumerate(index_array):
            # Load image
            fname = self.filenames[j]
            # print(fname)
            img = load_img(os.path.join(self.directory, fname),
                           grayscale=self.grayscale,
                           resize=self.resize, order=1)
            x = img_to_array(img, dim_ordering=self.dim_ordering)

            # Load GT image if segmentation
            if self.has_gt_image:
                # Load GT image
                gt_img = load_img(os.path.join(self.gt_directory, fname),
                                  grayscale=True,
                                  resize=self.resize, order=0)
                y = img_to_array(gt_img, dim_ordering=self.dim_ordering)
            else:
                y = None

            # Load GT image if detection
            if self.class_mode == 'detection':
                label_path = os.path.join(self.directory, fname).replace('jpg','txt')
                gt = np.loadtxt(label_path)
                if len(gt.shape) == 1:
                    gt = gt[np.newaxis,]
                y = gt.copy()
                y = y[((y[:,1] > 0.) & (y[:,1] < 1.))]
                y = y[((y[:,2] > 0.) & (y[:,2] < 1.))]
                y = y[((y[:,3] > 0.) & (y[:,3] < 1.))]
                y = y[((y[:,4] > 0.) & (y[:,4] < 1.))]
                if (y.shape != gt.shape) or (y.shape[0] == 0):
                    warnings.warn('DirectoryIterator: found an invalid annotation '
                                  'on GT file '+label_path)
                # shuffle gt boxes order
                np.random.shuffle(y)


            # Standarize image
            x = self.image_data_generator.standardize(x, y)

            # Data augmentation
            x, y = self.image_data_generator.random_transform(x, y)

            # Add images to batches
            if current_batch_size > 1:
                batch_x[i] = x
                if self.has_gt_image:
                    batch_y[i] = y
                elif self.class_mode == 'detection':
                    batch_y.append(y)
            else:
                batch_x = np.expand_dims(x, axis=0)
                if self.has_gt_image:
                    batch_y = np.expand_dims(y, axis=0)
                elif self.class_mode == 'detection':
                    batch_y = [y]

        # optionally save augmented images to disk for debugging purposes
        if self.save_to_dir:
            for i in range(current_batch_size):

                fname = '{prefix}_{index}_{hash}.{format}'.format(prefix=self.save_prefix,
                                                                  index=current_index + i,
                                                                  hash=np.random.randint(1e4),
                                                                  format=self.save_format)

                if self.class_mode == 'segmentation':
                    nclasses = self.classes  # TODO: Change
                    color_map = sns.hls_palette(nclasses+1)
                    void_label = nclasses
                    save_img2(batch_x[i], batch_y[i],
                              os.path.join(self.save_to_dir, fname), color_map,
                              void_label)

                else:
                    img = array_to_img(batch_x[i], self.dim_ordering,
                                       scale=True)
                    img.save(os.path.join(self.save_to_dir, fname))

        # Build batch of labels
        if self.class_mode == 'sparse':
            batch_y = self.classes[index_array]
        elif self.class_mode == 'binary':
            batch_y = self.classes[index_array].astype('float32')
        elif self.class_mode == 'categorical':
            batch_y = np.zeros((len(batch_x), self.nb_class), dtype='float32')
            for i, label in enumerate(self.classes[index_array]):
                batch_y[i, label] = 1.
        elif self.class_mode == 'detection':
            if self.model_name == 'ssd':
                bbox_util = BBoxUtility(self.nb_class)
                batch_y = bbox_util.ssd_build_gt_batch(batch_y)
            elif  self.model_name == 'yolo' or self.model_name == 'tiny-yolo':
                # TODO detection: check model, other networks may expect a different batch_y format and shape
                # YOLOLoss expects a particular batch_y format and shape
                batch_y = yolo_build_gt_batch(batch_y, self.image_shape, self.nb_class)
            else:
                print('Unknown detection model')
        elif self.class_mode == None:
            return batch_x

        return batch_x, batch_y