Example #1
0
def importCityscapes(c, args):
    if args.with_display:
        imreader = backendMedia.MediaReader(args.rootdir)

    logging.info('Will load splits: %s' % args.splits)
    logging.info('Will load json type: %s' % args.type)
    logging.info('Will load mask type: %s' % args.mask_type)

    if not op.exists(args.cityscapes_dir):
        raise Exception('Cityscape directory "%s" does not exist' %
                        args.cityscapes_dir)

    # Directory accessed by label type and by split.
    dirs_by_typesplit = {}

    for type_ in [args.type, 'leftImg8bit']:
        type_dir_template = op.join(args.cityscapes_dir, '%s*' % type_)
        for type_dir in [x for x in glob(type_dir_template) if op.isdir(x)]:
            logging.debug('Looking for splits in %s' % type_dir)
            for split in args.splits:
                typesplit_dir = op.join(type_dir, split)
                if op.exists(typesplit_dir):
                    logging.debug('Found split %s in %s' % (split, type_dir))
                    # Add the info into the main dictionary "dirs_by_typesplit".
                    if split not in dirs_by_typesplit:
                        dirs_by_typesplit[split] = {}
                    dirs_by_typesplit[split][type_] = typesplit_dir
    logging.info('Found the following directories: \n%s' %
                 pformat(dirs_by_typesplit))

    for split in args.splits:
        # List of cities.
        assert 'leftImg8bit' in dirs_by_typesplit[split]
        leftImg8bit_dir = dirs_by_typesplit[split]['leftImg8bit']
        cities = os.listdir(leftImg8bit_dir)
        cities = [x for x in cities if op.isdir(op.join(leftImg8bit_dir, x))]
        logging.info('Found %d cities in %s' % (len(cities), leftImg8bit_dir))

        for city in cities:
            image_names = os.listdir(op.join(leftImg8bit_dir, city))
            logging.info('In split "%s", city "%s" has %d images' %
                         (split, city, len(image_names)))

            for image_name in image_names:

                # Get the image path.
                image_path = op.join(leftImg8bit_dir, city, image_name)
                name_parts = op.splitext(image_name)[0].split('_')
                if len(name_parts) != 4:
                    raise Exception(
                        'Expect to have 4 parts in the name of image "%s"' %
                        image_name)
                if name_parts[0] != city:
                    raise Exception('The first part of name of image "%s" '
                                    'is expected to be city "%s".' %
                                    (image_name, city))
                if name_parts[3] != 'leftImg8bit':
                    raise Exception('The last part of name of image "%s" '
                                    'is expected to be city "leftImg8bit".' %
                                    image_name)
                imheight, imwidth = backendMedia.getPictureSize(image_path)
                imagefile = op.relpath(image_path, args.rootdir)
                c.execute(
                    'INSERT INTO images(imagefile,width,height) VALUES (?,?,?)',
                    (imagefile, imwidth, imheight))

                # Get the json label.
                if args.type in dirs_by_typesplit[split]:
                    city_dir = op.join(dirs_by_typesplit[split][args.type],
                                       city)
                    if op.exists(city_dir):

                        json_name = '_'.join(name_parts[:3] +
                                             [args.type, 'polygons']) + '.json'
                        json_path = op.join(city_dir, json_name)
                        if op.exists(json_path):
                            _importJson(c, json_path, imagefile, imheight,
                                        imwidth)

                        if args.mask_type is not None:
                            mask_name = '_'.join(
                                name_parts[:3] +
                                [args.type, args.mask_type]) + '.png'
                            mask_path = op.join(city_dir, mask_name)
                            if op.exists(mask_path):
                                maskfile = op.relpath(mask_path, args.rootdir)
                                c.execute(
                                    'UPDATE images SET maskfile=? WHERE imagefile=?',
                                    (maskfile, imagefile))

                if args.with_display:
                    img = imreader.imread(imagefile)
                    c.execute(
                        'SELECT objectid,name FROM objects WHERE imagefile=?',
                        (imagefile, ))
                    for objectid, name in c.fetchall():
                        # Draw polygon.
                        c.execute('SELECT x,y FROM polygons WHERE objectid=?',
                                  (objectid, ))
                        polygon = c.fetchall()
                        util.drawScoredPolygon(img, [(int(pt[0]), int(pt[1]))
                                                     for pt in polygon], name)
                    cv2.imshow('importCityscapes', img[:, :, ::-1])
                    if cv2.waitKey(-1) == 27:
                        args.with_display = False
                        cv2.destroyWindow('importCityscapes')

    # Statistics.
    c.execute('SELECT COUNT(1) FROM images')
    logging.info('Imported %d images' % c.fetchone()[0])
    c.execute('SELECT COUNT(1) FROM images WHERE maskfile IS NOT NULL')
    logging.info('Imported %d masks' % c.fetchone()[0])
    c.execute('SELECT COUNT(DISTINCT(imagefile)) FROM objects')
    logging.info('Objects are found in %d images' % c.fetchone()[0])
Example #2
0
def importKitti(c, args):
    if args.with_display:
        imreader = backendMedia.MediaReader(args.rootdir)

    image_paths = sorted(glob(op.join(args.images_dir, '*.png')))
    logging.info('Found %d PNG images in %s' %
                 (len(image_paths), args.images_dir))

    for image_path in progressbar(image_paths):
        filename = op.splitext(op.basename(image_path))[0]
        logging.debug('Processing image: "%s"' % filename)

        # Add image to the database.
        imheight, imwidth = backendMedia.getPictureSize(image_path)
        imagefile = op.relpath(image_path, args.rootdir)
        c.execute('INSERT INTO images(imagefile,width,height) VALUES (?,?,?)',
                  (imagefile, imwidth, imheight))

        if args.with_display:
            img = imreader.imread(imagefile)

        # Detection annotations.
        if args.detection_dir:
            detection_path = op.join(args.detection_dir, '%s.txt' % filename)
            if not op.exists(detection_path):
                raise FileNotFoundError('Annotation file not found at "%s".' %
                                        detection_path)

            # Read annotation file.
            with open(detection_path) as f:
                lines = f.read().splitlines()
            logging.debug('Read %d lines from detection file "%s"' %
                          (len(lines), detection_path))
            for line in lines:
                objectid = _parseObject(c, line, imagefile)

                if args.with_display:
                    c.execute('SELECT * FROM objects WHERE objectid=?',
                              (objectid, ))
                    object_entry = c.fetchone()
                    name = backendDb.objectField(object_entry, 'name')
                    roi = backendDb.objectField(object_entry, 'roi')
                    score = backendDb.objectField(object_entry, 'score')
                    util.drawScoredRoi(img, roi, name, score=score)

        # Segmentation annotations.
        if args.segmentation_dir:
            segmentation_path = op.join(args.segmentation_dir,
                                        '%s.png' % filename)
            if not op.exists(segmentation_path):
                raise FileNotFoundError('Annotation file not found at "%s".' %
                                        segmentation_path)

            # Add image to the database.
            maskfile = op.relpath(segmentation_path, args.rootdir)
            c.execute('UPDATE images SET maskfile=? WHERE imagefile=?',
                      (maskfile, imagefile))

            if args.with_display:
                mask = imreader.maskread(maskfile)
                img = util.drawMaskAside(img, mask, labelmap=None)

        # Maybe display.
        if args.with_display:
            cv2.imshow('importKitti', img[:, :, ::-1])
            if cv2.waitKey(-1) == 27:
                args.with_display = False
                cv2.destroyWindow('importKitti')
Example #3
0
    def addImage(self, image_dict):
        '''
        Add the image path to the database and (maybe) write an image to disk.
        Args:
          image_dict:   A dict that should have some of the following keys:
                        * "image", "imagefile" (one of the two is required.)

                          "image" is a numpy array standing for an image.
                          If specified, the image will be recorded on disk as
                          a file or a video frame based on "media" argument of
                          the constructor. It will also be written as an entry
                          to "images" table.
                          If not specified, we consider that the image already
                          exists on disk.

                          "imagefile" is a path of the image on disk.
                          If specified, we consider that the image already
                          exists on disk, and this path will be recorded as an
                          entry to the "images" table.
                          If not specified, it is generated automoatically.

                        * "mask" or "maskfile" (at most one of the two.)

                          Same behavior as for "image" or "imagefile".
                          If skipped, no maskfile is written to "images" table.

                        * "timestamp" is an object of datetime.datetime type,
                          defines the time the image was created. If skipped,
                          the "now" time is recorded.

                        * "name" is a name/class of the image.

                        * "height", "width" define image dimensions in case
                          images are passed through imagefile/maskfile and were
                          recorded as video frames (media = "video")
        Returns:
          imagefile:    The path of the image relative to "rootdir"
        '''

        if not isinstance(image_dict, Mapping):
            raise TypeError('image_dict should be a dict, not %s' %
                            type(image_dict))

        ### Writing image.

        if ('image' in image_dict) == ('imagefile' in image_dict):
            raise ValueError(
                'Exactly one of "image" or "imagefile" must be specified.')

        if 'image' in image_dict:
            image = image_dict['image']
            # TODO: add namehint, so the behavior will change.
            imagefile = self.imwriter.imwrite(image)
            height, width = image.shape[0:2]

        elif 'imagefile' in image_dict:
            imagefile = image_dict['imagefile']

            # Check image on disk, and get its dimensions.
            if self.media == 'pictures':
                imagepath = op.join(self.rootdir, imagefile)
                if not op.exists(imagepath):
                    raise ValueError('Got imagefile "%s" with rootdir "%s", '
                                     'but cant find an image at "%s"' %
                                     (imagefile, self.rootdir, imagepath))
                height, width = getPictureSize(imagepath)
            # Check video on disk, and get the dimensions from user's input.
            elif self.media == 'video':
                videopath = op.join(self.rootdir, op.dirname(imagefile))
                if not op.exists(videopath):
                    raise ValueError('Got imagefile "%s" with rootdir "%s", '
                                     'but cant find the video at "%s"' %
                                     (imagefile, self.rootdir, videopath))
                if 'height' not in image_dict or 'width' not in image_dict:
                    # TODO: get the dimensions once for every video and store them,
                    #       instead of asking user to provide it. Do it only if anybody
                    #       is interested in this scenario.
                    raise KeyError(
                        '"height" and "width" should be specified in image_dict.'
                    )
                height = image_dict['height']
                width = image_dict['width']
                self._checkValueIsNoneOrType(value=height,
                                             type_=int,
                                             name='height')
                self._checkValueIsNoneOrType(value=width,
                                             type_=int,
                                             name='width')
            else:
                assert False  # No other type of "media" for now.

        else:
            assert False  # Either "image" or "imagefile" must be provided.

        ### Writing mask.

        if 'mask' in image_dict and 'maskfile' in image_dict:
            raise ValueError(
                'Only one of "mask" or "maskfile" can be specified.')

        if 'mask' in image_dict:
            mask = image_dict['mask']
            maskfile = self.imwriter.maskwrite(mask)

        elif 'maskfile' in image_dict:
            maskfile = image_dict['maskfile']

            # Check image on disk, and get its dimensions.
            if self.media == 'pictures':
                maskpath = op.join(self.rootdir, maskfile)
                if not op.exists(maskpath):
                    raise ValueError('Got maskfile "%s" with rootdir "%s", '
                                     'but cant find an image at "%s"' %
                                     (maskfile, self.rootdir, maskpath))
            # Check video on disk, and get the dimensions from user's input.
            elif self.media == 'video':
                videopath = op.join(self.rootdir, op.dirname(maskfile))
                if not op.exists(videopath):
                    raise ValueError('Got maskfile "%s" with rootdir "%s", '
                                     'but cant find the video at "%s"' %
                                     (maskfile, self.rootdir, videopath))
            else:
                assert False  # No other type of "media" for now.

        else:
            maskfile = None

        ### Timestamp.

        if 'timestamp' in image_dict:
            timestamp = image_dict['timestamp']
            if not isinstance(timestamp, datetime):
                raise TypeError(
                    'Timestamp should be an object of datetime.datetime class. '
                    'Instead got %s' % timestamp)
        else:
            timestamp = makeTimeString(datetime.now())

        ### Name and score.

        name = image_dict['name'] if 'name' in image_dict else None
        score = image_dict['score'] if 'score' in image_dict else None

        ### Record.

        entry = (imagefile, width, height, maskfile, timestamp, name, score)
        s = 'images(imagefile,width,height,maskfile,timestamp,name,score)'
        logging.debug('Writing %s to %s', entry, s)

        self.c.execute('INSERT OR IGNORE INTO %s VALUES (?,?,?,?,?,?,?)' % s,
                       entry)
        return imagefile
Example #4
0
 def test_png(self):
     height, width = backendMedia.getPictureSize(
         'testdata/cars/masks/000000.png')
     self.assertEqual(width, 800)
     self.assertEqual(height, 700)
Example #5
0
 def test_jpg(self):
     height, width = backendMedia.getPictureSize(
         'testdata/cars/images/000000.jpg')
     self.assertEqual(width, 800)
     self.assertEqual(height, 700)
Example #6
0
def importBdd(c, args):
    if args.with_display:
        imreader = backendMedia.MediaReader(args.rootdir)

    image_paths = sorted(glob(op.join(args.images_dir, '*.jpg')))
    logging.info('Found %d JPG images in %s' %
                 (len(image_paths), args.images_dir))

    if args.detection_json:
        if not op.exists(args.detection_json):
            raise FileNotFoundError('Annotation file not found at "%s".' %
                                    args.detection_json)
        logging.info(
            'Loading the json with annotations. This may take a few seconds.')
        with open(args.detection_json) as f:
            detections = json.load(f)
            # Dict with image name as the key.
            detections = {d['name']: d for d in detections}

    for image_path in progressbar(image_paths):
        filename = op.splitext(op.basename(image_path))[0]
        logging.debug('Processing image: "%s"' % filename)

        # Add image to the database.
        imheight, imwidth = backendMedia.getPictureSize(image_path)
        imagefile = op.relpath(image_path, args.rootdir)
        c.execute('INSERT INTO images(imagefile,width,height) VALUES (?,?,?)',
                  (imagefile, imwidth, imheight))

        if args.with_display:
            img = imreader.imread(imagefile)

        # Detection annotations.
        if args.detection_json:
            imagename = op.basename(imagefile)
            if imagename not in detections:
                logging.error('Cant find image name "%s" in "%s"',
                              args.detection_json, imagename)
                continue

            detections_for_image = detections[imagename]
            image_properties = detections_for_image['attributes']
            for object_ in detections_for_image['labels']:

                object_bddid = object_['id']
                object_name = object_['category']
                object_properties = {
                    key: value
                    for key, value in object_['attributes'].items()
                    if value != 'none'
                }
                object_properties.update(image_properties)

                # Skip 3d object. TODO: import it to properties.
                if 'box3d' in object_:
                    logging.warning('Will skip 3D object %d.' % object_bddid)
                    continue

                # Get the bbox if exists.
                x1 = y1 = width = height = None
                if 'box2d' in object_:
                    box2d = object_['box2d']
                    x1 = int(float(box2d['x1']))
                    y1 = int(float(box2d['y1']))
                    width = int(float(box2d['x2']) - x1)
                    height = int(float(box2d['y2']) - y1)
                    if args.with_display:
                        roi = utilBoxes.bbox2roi((x1, y1, width, height))
                        util.drawScoredRoi(img, roi, object_name)

                c.execute(
                    'INSERT INTO objects(imagefile,x1,y1,width,height,name) '
                    'VALUES (?,?,?,?,?,?)',
                    (imagefile, x1, y1, width, height, object_name))
                objectid = c.lastrowid

                # Get the polygon if it exists.
                if 'poly2d' in object_:
                    if len(object_['poly2d']) > 1:
                        assert 0, len(object_['poly2d'])
                    polygon = object_['poly2d'][0]
                    polygon_name = None if polygon['closed'] else 'open_loop'
                    for pt in polygon['vertices']:
                        c.execute(
                            'INSERT INTO polygons(objectid,x,y,name) '
                            'VALUES (?,?,?,?)',
                            (objectid, pt[0], pt[1], polygon_name))
                    if args.with_display:
                        util.drawScoredPolygon(img,
                                               [(int(x[0]), int(x[1]))
                                                for x in polygon['vertices']],
                                               object_name)

                # Insert image-level and object-level attributes into
                # "properties" table.
                for key, value in object_properties.items():
                    c.execute(
                        'INSERT INTO properties(objectid,key,value) VALUES (?,?,?)',
                        (objectid, key, value))

        # Segmentation annotations.
        if args.segmentation_dir:
            segmentation_path = op.join(args.segmentation_dir,
                                        '%s_train_id.png' % filename)
            if not op.exists(segmentation_path):
                raise FileNotFoundError('Annotation file not found at "%s".' %
                                        segmentation_path)

            # Add image to the database.
            maskfile = op.relpath(segmentation_path, args.rootdir)
            c.execute('UPDATE images SET maskfile=? WHERE imagefile=?',
                      (maskfile, imagefile))

            if args.with_display:
                mask = imreader.maskread(maskfile)
                img = util.drawMaskAside(img, mask, labelmap=None)

        # Maybe display.
        if args.with_display:
            cv2.imshow('importKitti', img[:, :, ::-1])
            if cv2.waitKey(-1) == 27:
                args.with_display = False
                cv2.destroyWindow('importKitti')