Example #1
0
def dota_parse(label_file):
    """parse dota style dataset label file
    
    Arguments:
        label_file {str} -- label file path
    
    Returns:
        dict, {'bbox': [...], 'label': class_name} -- objects' location and class
    """
    with open(label_file, 'r') as f:
        lines = f.readlines()

    objects = []
    for line in lines:
        object_struct = dict()
        line = line.rstrip().split(' ')
        label = line[8]
        pointobb = [float(xy) for xy in line[:8]]
        bbox = wwtool.pointobb2bbox(pointobb)
        object_struct['bbox'] = bbox
        object_struct['label'] = label
        object_struct['pointobb'] = pointobb
        objects.append(object_struct)

    return objects
Example #2
0
    def __shp_parse__(self, label_file, image_file):
        """
        (xmin, ymin, xmax, ymax)
        """
        img_fn = os.path.splitext(os.path.basename(image_file))[0]

        if 'train' in imageset:
            geo_info_file = os.path.join(geopath, img_fn + '.png')
            geo_info = rio.open(geo_info_file)
            coord_flag = '4326'
        else:
            geo_info = rio.open(image_file)
            coord_flag = 'pixel'

        objects = []
        masks = shp_parser(label_file, geo_info, coord=coord_flag)
        total_object_num = len(masks)
        for mask in masks:
            object_struct = {}

            xmin, ymin, xmax, ymax = wwtool.pointobb2bbox(mask['segmentation'])
            bbox_w = xmax - xmin
            bbox_h = ymax - ymin

            object_struct['bbox'] = [xmin, ymin, bbox_w, bbox_h]
            object_struct['segmentation'] = mask['segmentation']
            object_struct['label'] = 1

            objects.append(object_struct)

        if total_object_num > self.max_object_num_per_image:
            self.max_object_num_per_image = total_object_num

        geo_info.close()
        return objects
Example #3
0
    def __call__(self, mask_image, category=(1, 3)):
        # assert(isinstance(mask_image, str), "Please input filename rather than np.array")
        if isinstance(mask_image, str):
            mask_file_name = mask_image
            mask_image = cv2.imread(mask_image)
        else:
            mask_file_name = "input is numpy array"

        if mask_image is None:
            print("Can not open this mask file: {}".format(mask_file_name))
            return []

        sub_mask_anno = self.generate_sub_mask_anno(mask_image, category=category)
        masks, polygons = self.generate_polygon(sub_mask_anno)

        objects = []
        for mask, polygon in zip(masks, polygons):
            if mask == []:
                continue
            object_struct = dict()

            xmin, ymin, xmax, ymax = wwtool.pointobb2bbox(mask)
            bbox_w = xmax - xmin
            bbox_h = ymax - ymin

            object_struct['segmentation'] = mask
            object_struct['bbox'] = [xmin, ymin, bbox_w, bbox_h]
            object_struct['polygon'] = polygon
            object_struct['label'] = "1"
            objects.append(object_struct)
        
        return objects
Example #4
0
    def __simpletxt_parse__(self, label_file, image_file):
        """
        (xmin, ymin, xmax, ymax)
        """
        with open(label_file, 'r') as f:
            lines = f.readlines()

        objects = []
        total_object_num = 0

        for line in lines:
            object_struct = {}
            line = line.rstrip().split(' ')
            label = " ".join(line[-1])
            mask = [float(_) for _ in line[0:-1]]

            xmin, ymin, xmax, ymax = wwtool.pointobb2bbox(mask)
            bbox_w = xmax - xmin
            bbox_h = ymax - ymin

            total_object_num += 1

            object_struct['bbox'] = [xmin, ymin, bbox_w, bbox_h]
            object_struct['segmentation'] = mask
            object_struct['label'] = 1

            objects.append(object_struct)

        return objects
Example #5
0
    def __simpletxt_parse__(self, label_file, image_file):
        """
        (xmin, ymin, xmax, ymax)
        """
        image_basename = wwtool.get_basename(image_file)
        origin_image_name = image_basename.split('__')[0].split(sub_fold +
                                                                '_')[1]
        # print(image_name_list, origin_image_name)
        if origin_image_name not in image_name_list:
            # print("===========================================")
            return []

        with open(label_file, 'r') as f:
            lines = f.readlines()

        objects = []
        total_object_num = 0

        for line in lines:
            object_struct = {}
            line = line.rstrip().split(' ')
            label = " ".join(line[-1])
            mask = [float(_) for _ in line[0:-1]]

            xmin, ymin, xmax, ymax = wwtool.pointobb2bbox(mask)
            bbox_w = xmax - xmin
            bbox_h = ymax - ymin

            total_object_num += 1

            object_struct['bbox'] = [xmin, ymin, bbox_w, bbox_h]
            object_struct['segmentation'] = mask
            object_struct['label'] = 1

            objects.append(object_struct)

        return objects
Example #6
0
    def __voc_parse__(self, label_file, image_file):
        objects = []
        if self.groundtruth:
            tree = ET.parse(label_file)
            root = tree.getroot()
            objects_handle = root.find('objects')
            total_object_num = 0
            for single_object in objects_handle.findall('object'):
                points = single_object.find('points')
                object_struct = {}

                pointobb = []
                for point in points[:-1]:
                    coords = [float(coord) for coord in point.text.split(',')]
                    pointobb += coords

                bbox = wwtool.pointobb2bbox(pointobb)
                bbox = wwtool.xyxy2xywh(bbox)

                object_struct['segmentation'] = pointobb
                object_struct['pointobb'] = pointobb_sort_function[
                    pointobb_sort_method](pointobb)
                object_struct['bbox'] = bbox
                object_struct['label'] = voc_class[single_object.find(
                    'possibleresult').find('name').text]

                objects.append(object_struct)

                total_object_num += 1

            if total_object_num > self.max_object_num_per_image:
                self.max_object_num_per_image = total_object_num

            return objects
        else:
            return []
Example #7
0
    def __call__(self, 
                shp_fn, 
                geom_img,
                ignore_file=None,
                return_ignore_index=False,
                show_ignored_polygons=False,
                coord='4326',
                merge_flag=False,
                merge_mode=2,
                connection_mode='floor',
                filter_small_size=0):
        """Parse shapefile of building change

        Arguments:
            shp_fn {str} -- file path of shapefile
            geom_img {rasterio class or string} -- png image contain coordinate information

        Keyword Arguments:
            coord {str} -- coordinate system (default: {'4326'})
            merge_flag {bool} -- False: skip the polygon merge, True: output objects after merging (default: {False})
            merge_mode {int} -- 1: merge by intersection, 2: merge by rule (default: {2})
            connection_mode {str} -- "line": merge by line intersection, "floor": merge by floor (default: {'floor'})

        Returns:
            [dict] -- dict which contains core information
        """
        try:
            shp = gpd.read_file(shp_fn, encoding='utf-8')
        except:
            print("Can't open this shp file: {}".format(shp_fn))
            return []

        # open geometry information file when input is string (file path)
        if isinstance(geom_img, str):
            geom_img = rio.open(geom_img)

        # open the ignore file
        if ignore_file:
            mask_parser = wwtool.MaskParse()
            objects = mask_parser(ignore_file, category=255)
            if objects == []:
                return []
            ignore_polygons = [obj['polygon'] for obj in objects]

        ori_polygon_list = []
        ori_floor_list = []
        ori_property_list = []

        for idx, row_data in shp.iterrows():
            polygon = row_data.geometry
            property_ = row_data[:-1]
            try:
                floor = row_data.Floor
            except:
                print("This file does not floor key: {}".format(shp_fn))
                # for processing beijing shapefile
                try:
                    floor = row_data.half_H
                except:
                    print("This file does not half_H key: {}".format(shp_fn))
                    return []

            if polygon == None:
                continue
            
            ori_polygon_list.append(polygon)
            ori_floor_list.append(floor)
            ori_property_list.append(property_)

        if merge_flag:
            # merge the splitted building when annotation
            merged_polygon_list, merged_property_list = self._merge_polygon(
                ori_polygon_list, 
                ori_floor_list,
                ori_property_list,
                merge_mode=merge_mode,
                connection_mode=connection_mode)
        else:
            merged_polygon_list = ori_polygon_list
            merged_property_list = ori_property_list

        # converted coordinate
        converted_polygons = []
        converted_properties = []

        # original coordinate, add these to handle multipolygons after merging
        merged_ori_polygons = []
        merged_ori_properties = []

        for polygon, property_ in zip(merged_polygon_list, merged_property_list):
            if polygon.geom_type == 'Polygon':
                if coord == '4326':
                    polygon_pixel = [(geom_img.index(c[0], c[1])[1], geom_img.index(c[0], c[1])[0]) for c in polygon.exterior.coords]
                    polygon_pixel = Polygon(polygon_pixel)
                    if polygon_pixel.area < filter_small_size:
                        continue
                    converted_polygons.append(polygon_pixel)
                    converted_properties.append(property_)
                else:
                    if polygon.area < filter_small_size:
                        continue
                    converted_polygons.append(polygon)
                    converted_properties.append(property_)
                merged_ori_polygons.append(polygon)
                merged_ori_properties.append(property_)

            elif polygon.geom_type == 'MultiPolygon':
                for sub_polygon in polygon:
                    if coord == '4326':
                        polygon_pixel = [(geom_img.index(c[0], c[1])[1], geom_img.index(c[0], c[1])[0]) for c in sub_polygon.exterior.coords]
                        polygon_pixel = Polygon(polygon_pixel)
                        if polygon_pixel.area < filter_small_size:
                            continue
                        converted_polygons.append(polygon_pixel)
                        converted_properties.append(property_)
                    else:
                        if sub_polygon.area < filter_small_size:
                            continue
                        converted_polygons.append(sub_polygon)
                        converted_properties.append(property_)
                    
                    merged_ori_polygons.append(sub_polygon)
                    merged_ori_properties.append(property_)
            else:
                raise(RuntimeError("type(polygon) = {}".format(type(polygon))))

        if isinstance(converted_polygons, (list, shapely.geometry.multipolygon.MultiPolygon)):
            pass
        else:
            converted_polygons = [converted_polygons]

        masks = []
        final_polygons = []
        final_properties = converted_properties
        for polygon_pixel in converted_polygons:
            final_polygons.append(polygon_pixel)
            wkt  = str(polygon_pixel)
            mask = self._wkt2coord(wkt)
            masks.append(mask)

        objects = []
        
        if ignore_file:
            _, ignore_indexes = wwtool.cleaning_polygon_by_polygon(final_polygons, ignore_polygons, show=show_ignored_polygons)
            if return_ignore_index:
                # keep full polygons, and return ignored indexes
                ignore_list = [0] * len(final_polygons)
                for ignore_index in ignore_indexes[::-1]:
                    ignore_list[ignore_index] = 1
            else:
                # return the ignored polygons
                for ignore_index in ignore_indexes[::-1]:
                    masks.pop(ignore_index)
                    final_polygons.pop(ignore_index)
                    final_properties.pop(ignore_index)
                    merged_ori_polygons.pop(ignore_index)
                    merged_ori_properties.pop(ignore_index)
            
        # ori -> original coordinate, converted -> converted coordinate
        for idx, (mask, converted_polygon, converted_property, ori_polygon, ori_property) in enumerate(zip(masks, final_polygons, final_properties, merged_ori_polygons, merged_ori_properties)):
            if mask == []:
                continue
            object_struct = dict()
            mask = [abs(_) for _ in mask]

            xmin, ymin, xmax, ymax = wwtool.pointobb2bbox(mask)
            bbox_w = xmax - xmin
            bbox_h = ymax - ymin

            object_struct['segmentation'] = mask
            object_struct['bbox'] = [xmin, ymin, bbox_w, bbox_h]
            object_struct['converted_polygon'] = converted_polygon
            object_struct['converted_property'] = converted_property
            object_struct['ori_polygon'] = ori_polygon
            object_struct['ori_property'] = ori_property
            object_struct['label'] = "1"
            if return_ignore_index:
                object_struct['ignore_index'] = ignore_list[idx]
            objects.append(object_struct)

        return objects
Example #8
0
    def __sn6_parse__(self, label_file, image_file):
        """
        (xmin, ymin, xmax, ymax)
        """
        objects = []
        if self.groundtruth:
            image_file_name = os.path.splitext(os.path.basename(image_file))[0]

            image_name_postfix = image_file_name + '.tif'
            if imageset == 'val':
                if image_name_postfix in valset_image_names:
                    pass
                else:
                    return []

            if imageset == 'train':
                if image_name_postfix in valset_image_names:
                    return []
                else:
                    pass

            save_image = wwtool.generate_image(800, 800, color=(0, 0, 0))
            img = cv2.imread(image_file)
            img_height, img_width, _ = img.shape

            image_name = os.path.basename(image_file).split(
                'SN6_{}_AOI_11_Rotterdam_{}_'.format(
                    imageset_file_name, data_source))[1].split('.tif')[0]
            masks = sn6_parse.sn6_parse(image_name)
            objects_small_save = []
            total_object_num = len(masks)
            small_object_num = 0
            large_object_num = 0
            total_object_num = 0
            for mask in masks:
                object_struct = {}
                object_struct_small = {}
                xmin, ymin, xmax, ymax = wwtool.pointobb2bbox(
                    mask['segmentation'])
                bbox_w = xmax - xmin
                bbox_h = ymax - ymin

                total_object_num += 1
                if bbox_h * bbox_w <= small_size:
                    small_object_num += 1
                if bbox_h * bbox_w >= large_object_size:
                    large_object_num += 1

                object_struct['bbox'] = [xmin, ymin, bbox_w, bbox_h]
                object_struct['segmentation'] = mask['segmentation']
                object_struct['label'] = 1

                object_struct_small = object_struct.copy()
                object_struct_small['bbox'] = [xmin, ymin, xmax, ymax]
                object_struct_small['label'] = 'building'

                objects_small_save.append(object_struct_small)
                objects.append(object_struct)

            if total_object_num > self.max_object_num_per_image:
                self.max_object_num_per_image = total_object_num

            if just_keep_small or generate_small_dataset:
                if small_object_num >= total_object_num * small_object_rate and large_object_num < 1 and len(
                        objects_small_save) > 0:
                    # print(os.path.join(dst_image_path, image_file_name + '.png'))
                    save_image[0:img_height, 0:img_width, :] = img
                    cv2.imwrite(
                        os.path.join(dst_image_path, image_file_name + '.png'),
                        save_image)
                    anno_file = os.path.join(dst_label_path,
                                             image_file_name + '.txt')
                    wwtool.simpletxt_dump(objects_small_save, anno_file)
                    return objects
                else:
                    return []
            else:
                return objects
        else:
            obj_struct = {}
            obj_struct['segmentation'] = [0, 0, 0, 0, 0, 0, 0, 0]
            obj_struct['bbox'] = [0, 0, 0, 0]
            obj_struct['label'] = 0

            objects.append(obj_struct)

            return objects