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
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
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
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
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
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 []
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
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