def create_annotations(meta, predictions, logger, category_ids, save=True, experiment_dir='./'): ''' :param meta: pd.DataFrame with metadata :param predictions: list of labeled masks or numpy array of size [n_images, im_height, im_width] :param logger: :param save: True, if one want to save submission, False if one want to return it :param experiment_dir: path to save submission :return: submission if save==False else True ''' annotations = [] logger.info('Creating submission') for image_id, prediction in zip(meta["ImageId"].values, predictions): score = 1.0 for category_nr, category_instances in enumerate(prediction): if category_ids[category_nr] != None: masks = decompose(category_instances) for mask_nr, mask in enumerate(masks): annotation = {} annotation["image_id"] = int(image_id) annotation["category_id"] = category_ids[category_nr] annotation["score"] = score annotation["segmentation"] = rle_from_binary( mask.astype('uint8')) annotation['segmentation']['counts'] = annotation[ 'segmentation']['counts'].decode("UTF-8") annotation["bbox"] = bounding_box_from_rle( rle_from_binary(mask.astype('uint8'))) annotations.append(annotation) if save: submission_filepath = os.path.join(experiment_dir, 'submission.json') with open(submission_filepath, "w") as fp: fp.write(str(json.dumps(annotations))) logger.info("Submission saved to {}".format(submission_filepath)) logger.info('submission head \n\n{}'.format(annotations[0])) return True else: return annotations
def largest_connected_component(mask): mask = mask.astype(np.uint8) n_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(mask, 4, cv2.CV_32S) areas = stats[1:, -1] if len(areas) < 1: return mask, np.array([0, 0, 0, 0]) largest_area_label = 1 + np.argsort(areas)[-1] obj_mask = np.uint8(labels == largest_area_label) obj_box = stats[largest_area_label, :4] return obj_mask, np.array(obj_box)
def visualize(self): #COCO """ Visualize mask and bounding box coordinates for COCO annotated object """ mask = img_mask == object_uid mask = np.expand_dims(mask, axis=2) mask = 255 * mask.astype('uint8') cv2.imshow('image', im) cv2.waitKey(1) if self.too_small_obj: cv2.imshow('Too small object', mask) else: cv2.imshow('Labeled object', mask) print("Object class: {}".format(class_name)) cv2.waitKey(1000)
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("input_dir", help="input annotated directory") parser.add_argument("output_dir", help="output dataset directory") parser.add_argument("--labels", help="labels file", required=True) parser.add_argument("--noviz", help="no visualization", action="store_true") args = parser.parse_args() if osp.exists(args.output_dir): print("Output directory already exists:", args.output_dir) sys.exit(1) os.makedirs(args.output_dir) os.makedirs(osp.join(args.output_dir, "JPEGImages")) if not args.noviz: os.makedirs(osp.join(args.output_dir, "Visualization")) print("Creating dataset:", args.output_dir) now = datetime.datetime.now() data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime("%Y-%m-%d %H:%M:%S.%f"), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type="instances", annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) class_name_to_id = {} for i, line in enumerate(open(args.labels).readlines()): class_id = i - 1 # starts with -1 class_name = line.strip() if class_id == -1: assert class_name == "__ignore__" continue class_name_to_id[class_name] = class_id data["categories"].append( dict( supercategory=None, id=class_id, name=class_name, )) out_ann_file = osp.join(args.output_dir, "annotations.json") label_files = glob.glob(osp.join(args.input_dir, "*.json")) for image_id, filename in enumerate(label_files): print("Generating dataset from:", filename) label_file = labelme.LabelFile(filename=filename) base = osp.splitext(osp.basename(filename))[0] out_img_file = osp.join(args.output_dir, "JPEGImages", base + ".jpg") img = labelme.utils.img_data_to_arr(label_file.imageData) imgviz.io.imsave(out_img_file, img) data["images"].append( dict( license=0, url=None, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) masks = {} # for area segmentations = collections.defaultdict(list) # for segmentation for shape in label_file.shapes: points = shape["points"] label = shape["label"] group_id = shape.get("group_id") shape_type = shape.get("shape_type", "polygon") mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask if shape_type == "rectangle": (x1, y1), (x2, y2) = points x1, x2 = sorted([x1, x2]) y1, y2 = sorted([y1, y2]) points = [x1, y1, x2, y1, x2, y2, x1, y2] else: points = np.asarray(points).flatten().tolist() segmentations[instance].append(points) segmentations = dict(segmentations) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() data["annotations"].append( dict( id=len(data["annotations"]), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, )) if not args.noviz: viz = img if masks: labels, captions, masks = zip( *[(class_name_to_id[cnm], cnm, msk) for (cnm, gid), msk in masks.items() if cnm in class_name_to_id]) viz = imgviz.instances2rgb( image=img, labels=labels, masks=masks, captions=captions, font_size=15, line_width=2, ) out_viz_file = osp.join(args.output_dir, "Visualization", base + ".jpg") imgviz.io.imsave(out_viz_file, viz) with open(out_ann_file, "w") as f: json.dump(data, f)
def generate_coco_file(results): now = datetime.datetime.now() data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime('%Y-%m-%d %H:%M:%S.%f'), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type='instances', annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) # class_name_to_id = {} # for i, line in enumerate(open(args.labels).readlines()): # class_id = i - 1 # starts with -1 # class_name = line.strip() # if class_id == -1: # assert class_name == '__ignore__' # continue # class_name_to_id[class_name] = class_id # data['categories'].append(dict( # supercategory=None, # id=class_id, # name=class_name, # )) out_ann_file = osp.join('./', 'annotations.json') print(results) exit() for image_id, label_file in enumerate(label_files): print('Generating dataset from:', label_file) with open(label_file) as f: label_data = json.load(f) base = osp.splitext(osp.basename(label_file))[0] out_img_file = osp.join( args.output_dir, 'JPEGImages', base + '.jpg' ) img_file = osp.join( osp.dirname(label_file), label_data['imagePath'] ) img = np.asarray(PIL.Image.open(img_file)) PIL.Image.fromarray(img).save(out_img_file) data['images'].append(dict( license=0, url=None, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) masks = {} # for area segmentations = collections.defaultdict(list) # for segmentation labels_indices = {} for shape in label_data['shapes']: points = shape['points'] label = shape['label'] shape_type = shape.get('shape_type', None) mask = labelme.utils.shape_to_mask( img.shape[:2], points, shape_type ) if label in masks: labels_indices[label] += 1 label=label+"-"+str(labels_indices[label]) else: labels_indices[label]=0 masks[label] = mask points = np.asarray(points).flatten().tolist() segmentations[label].append(points) for label, mask in masks.items(): cls_name = label.split('-')[0] if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() data['annotations'].append(dict( id=len(data['annotations']), image_id=image_id, category_id=cls_id, segmentation=segmentations[label], area=area, bbox=bbox, iscrowd=0, )) with open(out_ann_file, 'w') as f: json.dump(data, f)
def Labelme2Yolo(ym='det'): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('input_dir', help='input annotated directory') parser.add_argument('output_dir', help='output dataset directory') parser.add_argument('--labels', help='labels file', required=True) parser.add_argument('--viz', help='visualize', action='store_true') args = parser.parse_args() output_dir = args.output_dir assert not osp.exists(output_dir) os.makedirs(output_dir) if args.viz: os.makedirs(osp.join(output_dir, 'Viz')) os.makedirs(osp.join(output_dir, 'images')) os.makedirs(osp.join(output_dir, 'labels')) print('Creating dataset:', output_dir) cls_to_id = {} ofs = 0 for i, line in enumerate(open(args.labels).readlines()): cls_name = line.strip() if cls_name.startswith('_'): ofs = 1 continue class_id = i - ofs # start with -1 or 0 cls_to_id[cls_name] = class_id label_files = glob(osp.join(args.input_dir, '*.json')) for image_id, jsonfile in enumerate(tqdm(label_files)): label_file = labelme.LabelFile(filename=jsonfile) img = labelme.utils.img_data_to_arr(label_file.imageData) base = osp.splitext(osp.basename(jsonfile))[0] + '.jpg' dst_img = osp.join(output_dir, 'images', base).replace('\\', '/') if label_file.imagePath.endswith('.jpg'): #copy(osp.join(args.input_dir, label_file.imagePath), dst_img) copyfile(osp.join(args.input_dir, label_file.imagePath), dst_img) else: imgviz.io.imsave(dst_img, img) #Image.fromarray(img).save(dst_img) masks = {} # for area for shape in label_file.shapes: points = shape['points'] label = shape['label'] group_id = shape.get('group_id') shape_type = shape.get('shape_type', 'polygon') mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask H, W = img.shape[:2] box = [] res = '' for (cls_name, group_id), mask in masks.items(): mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) bbox = pycocotools.mask.toBbox(mask).ravel() bbox[0] += bbox[2] / 2 bbox[1] += bbox[3] / 2 bbox[::2] /= W bbox[1::2] /= H box += [bbox] if cls_name not in cls_to_id: continue cls_id = cls_to_id[cls_name] # top_left->center res += '%d %.6f %.6f %.6f %.6f\n' % (cls_id, *bbox) dst_txt = osp.join(output_dir, 'labels', base[:-4]) with open(dst_txt + '.txt', 'w') as f: f.write(res) if args.viz and box: # center->top_left x, y, w, h = np.array(box).transpose() x -= w / 2 y -= h / 2 box = np.array([y * H, x * W, (y + h) * H, (x + w) * W]).transpose() c2i = lambda x: cls_to_id[x] if x in cls_to_id else len(cls_to_id) lab, cap, mk = zip(*[(c2i(c), c, mk) for (c, g), mk in masks.items()]) viz = imgviz.instances2rgb( image=img, labels=lab, bboxes=list(box), #masks=mk, captions=cap, font_size=12, line_width=2) imgviz.io.imsave(osp.join(output_dir, 'Viz', base), viz) res = dict(train=f'../{output_dir}/images/', val=f'../{output_dir}/images/', nc=len(cls_to_id), names=[i for i in cls_to_id]) with open(osp.join(output_dir, ym + '.yaml'), 'w') as f: yaml.dump(res, f, sort_keys=False)
def process(image_ids, label_file, output_dir, class_name_to_id): #print('Generating dataset from:', label_file) deg_range = 15 with open(label_file) as f: label_data = json.load(f) base = osp.splitext(osp.basename(label_file))[0] # NOTE: copy the image file img_file = osp.join(osp.dirname(label_file), label_data['imagePath']) orig_img = np.asarray(PIL.Image.open(img_file)) imgs = [] out_img_files = [] annotations = [] img_center = tuple(np.array(orig_img.shape[1::-1]) / 2) for i, image_id in zip(range(VARS), image_ids): angle = random.uniform(deg_range * -1, deg_range) if i == 0: angle = 0. print('doing image', i, angle) m = cv2.getRotationMatrix2D(img_center, angle, 1.0) img = cv2.warpAffine(orig_img, m, orig_img.shape[1::-1], flags=cv2.INTER_LINEAR) # NOTE: gather polygons polygons = [] out_img_file = osp.join(output_dir, 'JPEGImages', base + '_' + str(i) + '.jpg') #masks = {} for shape in label_data['shapes']: points = shape['points'] label = shape['label'] if 'name' not in label: continue shape_type = shape.get('shape_type', None) mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) mask = np.asfortranarray(mask.astype(np.uint8)) if shape['shape_type'] == 'polygon': coords = [coord for coords in points for coord in coords] elif shape['shape_type'] == 'rectangle': x1, y1 = points[0] x2, y2 = points[1] coords = [x1, y1, x1, y2, x2, y2, x2, y1] else: raise Exception('unknown shape type') coords = np.array(coords) x = coords[0::2] y = coords[1::2] #print(m) #print(x) #print(y) coords[0::2] = m[0][0] * x + m[0][1] * y + m[0][2] coords[1::2] = m[1][0] * x + m[1][1] * y + m[1][2] polygons.append((label, mask, coords.tolist())) annotation = [] for label, mask, polygon in polygons: #print label, polygons[label] #print(label, polygon) cls_name = label.split('-')[0] if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] segmentation = pycocotools.mask.encode(mask) segmentation['counts'] = segmentation['counts'].decode() area = float(pycocotools.mask.area(segmentation)) bbox = list(pycocotools.mask.toBbox(segmentation)) annotation.append( dict( segmentation=[polygon], #segmentation = segmentation, area=area, iscrowd=0, #iscrowd = 1, image_id=image_id, category_id=cls_id, id=-1, bbox=bbox, )) #annot_count += 1 PIL.Image.fromarray(img).save(out_img_file) imgs.append(img.shape) out_img_files.append(out_img_file) annotations.append(annotation) return imgs, out_img_files, annotations
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter ) parser.add_argument('input_dir', help='input annotated directory') parser.add_argument('output_dir', help='output dataset directory') args = parser.parse_args() if osp.exists(args.output_dir): print('Output directory already exists:', args.output_dir) sys.exit(1) os.makedirs(args.output_dir) os.makedirs(osp.join(args.output_dir, 'images')) os.makedirs(osp.join(args.output_dir, 'annotations')) print('Creating dataset:', args.output_dir) now = datetime.datetime.now() # coco data format data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime('%Y-%m-%d %H:%M:%S.%f'), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type='instances', annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) class_name_to_id = {} supercategory_name = "None" # TODO ## get label dict cat_id_map = labelmeutils.get_labelme_categories_id_map(args.input_dir, args.output_dir) for class_name in cat_id_map.keys(): class_id = cat_id_map[class_name][0] class_name_to_id[class_name] = class_id data['categories'].append(dict( supercategory=supercategory_name, id=class_id, name=class_name, )) print('class_name_to_id:', class_name_to_id) # write json and image label_files = glob.glob(osp.join(args.input_dir, '**/*.json'), recursive=True) for image_id, label_file in enumerate(label_files): #print('Generating dataset from:', label_file) print('Generating dataset --- {} / {}'.format(image_id+1, len(label_files))) with open(label_file) as f: label_data = json.load(f) base = osp.splitext(osp.basename(label_file))[0] out_img_file = osp.join( args.output_dir, 'images', base + '.jpg' ) out_ann_file = osp.join(args.output_dir, 'annotations',base+'.json') img_file = osp.join( osp.dirname(label_file), label_data['imagePath'] ) img = np.asarray(PIL.Image.open(img_file)) PIL.Image.fromarray(img).save(out_img_file) #data['images'].append(dict( # license=0, # url=None, # file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)), # height=img.shape[0], # width=img.shape[1], # date_captured=None, # id=image_id, #)) data['images'] = [dict( license=0, url=None, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )] masks = {} # for area segmentations = collections.defaultdict(list) # for segmentation for shape in label_data['shapes']: points = shape['points'] label = shape['label'] shape_type = shape.get('shape_type', None) mask = labelmeutils.shape_to_mask( img.shape[:2], points, shape_type ) if label in masks: masks[label] = masks[label] | mask else: masks[label] = mask points = np.asarray(points).flatten().tolist() segmentations[label].append(points) for label, mask in masks.items(): cls_name = label.split('-')[0] if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() #data['annotations'].append(dict( # id=len(data['annotations']), # image_id=image_id, # category_id=cls_id, # segmentation=segmentations[label], # area=area, # bbox=bbox, # iscrowd=0, #)) data['annotations'] = [dict( id=len(data['annotations']), image_id=image_id, category_id=cls_id, segmentation=segmentations[label], area=area, bbox=bbox, iscrowd=0, )] with open(out_ann_file, 'w') as f: json.dump(data, f) print('save json and image done:', args.output_dir)
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--name', type=str, help='name of the project') parser.add_argument('--csv_data', type=str, help='path to csv from rhymes') parser.add_argument('--csv_cat', type=str, help='path to csv containing category labels') parser.add_argument('--output_dir', type=str, help='path to save annotation.json output and image') parser.add_argument('--labels', help='labels file', required=True) parser.add_argument('--test_size', help='percentage of test size', required=True) args = parser.parse_args() if osp.exists(args.output_dir): print('Output directory already exists:', args.output_dir) sys.exit(1) os.makedirs(args.output_dir) os.makedirs(osp.join(args.output_dir, 'Train', 'JPEGImages')) os.makedirs(osp.join(args.output_dir, 'Val', 'JPEGImages')) print('Creating dataset:', args.output_dir) # convert dataset to dataframe df1 = pd.read_csv(args.csv_data) df2 = pd.read_csv(args.csv_cat) print('\n\nNumber of input is {}\n\n'.format(len(df1))) now = datetime.datetime.now() ## split the dataset in 2 parts print(f'\n\nsplit the dataset in 2 parts\n\n') train, test = train_test_split(df1, test_size=float(args.test_size)) train = train.reset_index(drop=True) # rest index and drop old index test = test.reset_index(drop=True) # rest index and drop old index dataset = [train, test] counter = 0 for sample in dataset: output_content = sample['output_content'] cdn_url = sample['image_url'] cat = df2['category_image'] cat_list = cat.values.tolist() coco_data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime('%Y-%m-%d %H:%M:%S.%f'), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type='instances', annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) class_name_to_id = {} for i, line in enumerate(open(args.labels).readlines()): class_id = i - 1 # starts with -1 class_name = line.strip() if class_id == -1: assert class_name == '__ignore__' continue class_name_to_id[class_name] = class_id coco_data['categories'].append( dict( supercategory=None, id=class_id, name=class_name, )) if counter == 0: print(f'\n\nProcessing Train data\n\n') json_save_path = osp.join(args.output_dir, 'Train') sample_name = args.name + '_' + 'train2019' else: print(f'\n\nProcessing Val data\n\n') json_save_path = osp.join(args.output_dir, 'Val') sample_name = args.name + '_' + 'val2019' counter += 1 # counter for sample_name out_ann_file = osp.join(json_save_path, 'annotations.json') for i in range( len(output_content)): #for i in range(len(output_content)): data = dict(imagePath=None, shapes=[], imageData=None, lineColor=[0, 255, 0, 128], fillColor=[255, 0, 0, 128]) a = eval(output_content[i]) image_url = cdn_url[i] json_name = sample_name + '_' + str(i) + ".json" image_name = sample_name + '_' + str(i) + ".jpg" print(f'\nProcessing {image_name} data\n') data['imagePath'] = image_name image_id = i if 'identifications' in a: # make the if statement here to avoid saving image and json without annotation for point in a['identifications']: if point['type'] == 'polygon': polygone = point['data'] if point['category'] in cat_list: category = point['category'] data['shapes'].append( dict(line_color=None, points=polygone, fill_color=None, label=category)) out_img_file = osp.join(json_save_path, 'JPEGImages', image_name) with urllib.request.urlopen(image_url) as url: f = io.BytesIO(url.read()) img = Image.open(f) img.save(out_img_file, 'JPEG') img_array = np.asarray(img) coco_data['images'].append( dict( license=0, url=image_url, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)), height=img.size[1], width=img.size[0], date_captured=None, id=image_id, )) ## masks = {} # for area ## segmentations = collections.defaultdict(list) # for segmentation for indx, shape in enumerate(data['shapes']): nested_list = [] points = shape['points'] label = shape['label'] shape_type = shape.get('shape_type', None) mask = shape_to_mask(img_array.shape[:2], points, shape_type) ## if label in masks: ## masks[label] = masks[label] | mask ## else: ## masks[label] = mask points = np.asarray(points).flatten().tolist() ## segmentations[label].append(points) nested_list.append(points) ## for label, mask in masks.items(): cls_name = label.split('-')[0] if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() coco_data['annotations'].append( dict( id=len(coco_data['annotations']), image_id=image_id, category_id=cls_id, segmentation=nested_list, area=area, bbox=bbox, iscrowd=0, )) with open(out_ann_file, 'w') as f: json.dump(coco_data, f, indent=4)
def encode_mask(mask): return pycocotools.mask.encode(np.asfortranarray(mask.astype(np.uint8)))
pixels = np.sum(mask) if pixels<50: continue cls = label_map[mask][0] if cls == 0 or cls == 3: continue y_list, x_list = np.where(id_map==instance) bbox = [ np.amin(x_list), np.amin(y_list), np.amax(x_list), np.amax(y_list)] # x1, y1, x2, y2 x1, y1, x2, y2 = bbox width = max(0, x2 - x1) height = max(0, y2 - y1) contours = measure.find_contours(mask.astype(np.uint8), 0.5) seg = [] for contour in contours: contour = np.flip(contour, axis=1) segmentation = contour.ravel().tolist() seg.append(segmentation) dataset['annotations'].append({ 'area': width * height, 'bbox': [x1, y1, width, height], 'category_id': int(cls), 'id': instance, 'image_id': id, 'iscrowd': 0, 'segmentation': seg })
def process(image_id, label_file, output_dir, class_name_to_id): #print('Generating dataset from:', label_file) with open(label_file) as f: label_data = json.load(f) base = osp.splitext(osp.basename(label_file))[0] out_img_file = osp.join( output_dir, 'JPEGImages', base + '.jpg' ) # NOTE: copy the image file img_file = osp.join( osp.dirname(label_file), label_data['imagePath'] ) img = np.asarray(PIL.Image.open(img_file)) # NOTE: gather polygons polygons = [] fields = { 'name_col_field': [], 'occupation_col_industry_field': [], 'occupation_col_occupation_field': [], 'veteran_col_war_or_expedition': [], 'veteran_col_yes_or_no': [], } veteran_col = [] name_col = [] occupation_col = [] tkps = Counter() #masks = {} for shape in label_data['shapes']: points = shape['points'] label = shape['label'] shape_type = shape.get('shape_type', None) mask = labelme.utils.shape_to_mask( img.shape[:2], points, shape_type ) mask = np.asfortranarray(mask.astype(np.uint8)) if shape['shape_type'] == 'polygon': coords = [coord for coords in points for coord in coords] if len(coords) > 8: print("WARNING! polygon has more points than expeted in {}, {}".format(img_file, coords)) coords = coords[:8] elif shape['shape_type'] == 'rectangle': x1, y1 = points[0] x2, y2 = points[1] coords = [x1, y1, x1, y2, x2, y2, x2, y1] else: raise Exception('unknown shape type') for i in coords: assert not math.isnan(i), "ERROR! NaN found! {}, {}".format(img_file, coords) ys = [coords[i] for i in range(1, len(coords), 2)] y_center = int((min(ys) + max(ys)) // 2) xs = [coords[i] for i in range(0, len(coords), 2)] x_center = int((min(xs) + max(xs)) // 2) #print(label, y_center) #coords = [ # [coords[0], coords[1]], # [coords[2], coords[3]], # [coords[4], coords[5]], # [coords[6], coords[7]], #] coords = list(map(int, coords)) polygon = (x_center, y_center, 2, label, mask, coords) if label in fields: fields[label].append(polygon) tkps[label] += 1 elif 'header' in label: if 'occupation' in label: tkps['occupation_col'] += 1 occupation_col.append(polygon) elif 'name' in label: tkps['name_col'] += 1 name_col.append(polygon) elif 'veteran' in label: tkps['veteran_col'] += 1 veteran_col.append(polygon) else: polygons.append((label, mask, coords)) for key, vals in fields.items(): #print("before") #print(list([(i[0], i[1]) for i in vals])) vals.sort(key = lambda x: x[0]) #print("after") #print(list([(i[0], i[1]) for i in vals])) #print('before', tkps) label = 'name_col_field' tkps['name_col'] += tkps[label] if len(fields[label]) < 50: #print('padding name', 50 - len(fields[label])) pad = list([(0, 0, 0, None, None, None) for i in range(50 - len(fields[label]))]) fields[label] = fields[label] + pad label = 'veteran_col_yes_or_no' tkps['veteran_col'] += tkps[label] if len(fields[label]) < 50: pad = list([(0, 0, 0, None, None, None) for i in range(50 - len(fields[label]))]) fields[label] = fields[label] + pad label = 'veteran_col_war_or_expedition' tkps['veteran_col'] += tkps[label] if len(fields[label]) < 50: pad = list([(0, 0, 0, None, None, None) for i in range(50 - len(fields[label]))]) fields[label] = fields[label] + pad label = 'occupation_col_industry_field' tkps['occupation_col'] += tkps[label] if len(fields[label]) < 50: pad = list([(0, 0, 0, None, None, None) for i in range(50 - len(fields[label]))]) fields[label] = fields[label] + pad label = 'occupation_col_occupation_field' tkps['occupation_col'] += tkps[label] if len(fields[label]) < 50: pad = list([(0, 0, 0, None, None, None) for i in range(50 - len(fields[label]))]) fields[label] = fields[label] + pad name_col += fields['name_col_field'] veteran_col += fields['veteran_col_yes_or_no'] + fields['veteran_col_war_or_expedition'] occupation_col += fields['occupation_col_occupation_field'] + fields['occupation_col_industry_field'] #print(len(polygons)) #print(list([(i[0], i[1], i[2]) for i in name_col])) #print(tkps) #print(tkps) annotations = [] for label, mask, polygon in polygons: #print(label) #if label != 'name_col': # continue nkps = tkps[label] #print('total kps', nkps) if label == 'name_col': kps = name_col exp = expected_name_kps elif label == 'occupation_col': kps = occupation_col exp = expected_occupation_kps elif label == 'veteran_col': kps = veteran_col exp = expected_veteran_kps fkps = [] fkps_bbox = [] #print(kps) for kp in kps: #print(kp) x, y, v, _, _, coords = kp fkps.append(x) fkps.append(y) fkps.append(v) # NOTE: convert coord to box if coords is None: #fkps_bbox.append([[0, 0]] * 4) for i in range(8): fkps.append(0) else: assert len(coords) == 8, 'coords for field is incorrect {}'.format(coords) for i in coords: fkps.append(i) #fkps_bbox.append(coords) #print(label, polygon) cls_name = label.split('-')[0] if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] segmentation = pycocotools.mask.encode(mask) segmentation['counts'] = segmentation['counts'].decode() area = float(pycocotools.mask.area(segmentation)) bbox = list(pycocotools.mask.toBbox(segmentation)) annotations.append(dict( segmentation = [polygon], num_keypoints = nkps, keypoints = fkps, #keypoint_bboxes = fkps_bbox, #segmentation = segmentation, area=area, iscrowd = 0, #iscrowd = 1, image_id=image_id, category_id=cls_id, id=-1, bbox=bbox, )) #annot_count += 1 #PIL.Image.fromarray(img).save(out_img_file) return img, out_img_file, annotations
def do_instance_segmentation_coco(self): try: import pycocotools.mask except ImportError: diag = QMessageBox() diag.setText("Please install pycocotools:\n\n pip install pycocotools\n") diag.exec() return output_dir = self.output_directory.line_edit.text() input_dir = self.input_directory.line_edit.text() labels = self.labels_file.line_edit.text() noviz = not self.output_visualization.isChecked() if '' in [output_dir, input_dir, labels]: return if len(os.listdir(output_dir)) > 0: diag = QMessageBox() diag.setText("Output directory must be empty") diag.exec() return os.makedirs(osp.join(output_dir, "JPEGImages")) if not noviz: os.makedirs(osp.join(output_dir, "Visualization")) print("Creating dataset:", output_dir) now = datetime.datetime.now() data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime("%Y-%m-%d %H:%M:%S.%f"), ), licenses=[dict(url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type="instances", annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) labels = open(labels).readlines() # ensure that the labels start with ignore and background try: labels.remove('__ignore__') except ValueError: pass try: labels.remove('_background_') except ValueError: pass new_labels = ['__ignore__', '_background_'] new_labels.extend(labels) class_name_to_id = {} for i, line in enumerate(new_labels): class_id = i - 1 # starts with -1 class_name = line.strip() if class_id == -1: assert class_name == "__ignore__" continue class_name_to_id[class_name] = class_id data["categories"].append( dict(supercategory=None, id=class_id, name=class_name, ) ) out_ann_file = osp.join(output_dir, "annotations.json") label_files = glob.glob(osp.join(input_dir, "*.json")) for image_id, filename in enumerate(label_files): print("Generating dataset from:", filename) label_file = labelme.LabelFile(filename=filename) base = osp.splitext(osp.basename(filename))[0] out_img_file = osp.join(output_dir, "JPEGImages", base + ".jpg") img = labelme.utils.img_data_to_arr(label_file.imageData) imgviz.io.imsave(out_img_file, img) data["images"].append( dict( license=0, url=None, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, ) ) masks = {} # for area segmentations = collections.defaultdict(list) # for segmentation for shape in label_file.shapes: points = shape["points"] label = shape["label"] group_id = shape.get("group_id") shape_type = shape.get("shape_type", "polygon") mask = labelme.utils.shape_to_mask( img.shape[:2], points, shape_type ) if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask if shape_type == "rectangle": (x1, y1), (x2, y2) = points x1, x2 = sorted([x1, x2]) y1, y2 = sorted([y1, y2]) points = [x1, y1, x2, y1, x2, y2, x1, y2] else: points = np.asarray(points).flatten().tolist() segmentations[instance].append(points) segmentations = dict(segmentations) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() data["annotations"].append( dict( id=len(data["annotations"]), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, ) ) if not noviz: try: labels, captions, masks = zip( *[ (class_name_to_id[cnm], cnm, msk) for (cnm, gid), msk in masks.items() if cnm in class_name_to_id ] ) viz = imgviz.instances2rgb( image=img, labels=labels, masks=masks, captions=captions, font_size=15, line_width=2, ) out_viz_file = osp.join( output_dir, "Visualization", base + ".jpg" ) imgviz.io.imsave(out_viz_file, viz) except ValueError as e: print(f'Failed to create visualization for {base}.jpg') with open(out_ann_file, "w") as f: json.dump(data, f) self.hide()
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter ) parser.add_argument('raw_labelme_dir', help='Path to input `raw_labelme` directory') args = parser.parse_args() if os.path.exists(OUT_DIR): print('Output directory already exists:' + OUT_DIR) sys.exit(1) labels_filepath = os.path.join(args.raw_labelme_dir, 'labels.txt') if not os.path.exists(labels_filepath): print('Labels file does not exist') sys.exit(1) print('Creating dataset:', OUT_DIR) os.makedirs(OUT_DIR) os.makedirs(ANNOT_DIR) partitions = ["train", "val"] now = datetime.datetime.now() # Run for "train" and "val" partitions. for partition in partitions: IMG_DIR_IN = os.path.join(args.raw_labelme_dir, f"{partition}_images") IMG_DIR_OUT = os.path.join(OUT_DIR, f"{partition}2014") ANN_DIR_IN = os.path.join(args.raw_labelme_dir, f"{partition}_annotations") ANN_FILEPATH = os.path.join(ANNOT_DIR, f"instances_{partition}2014.json") os.makedirs(IMG_DIR_OUT) class_name_to_id = {} data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime('%Y-%m-%d %H:%M:%S.%f'), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type='instances', annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) for class_id, line in enumerate(open(labels_filepath).readlines()): class_name = line.strip() if class_id == 0: assert class_name == '__ignore__' continue class_name_to_id[class_name] = class_id data['categories'].append(dict( supercategory=None, id=class_id, name=class_name, )) label_files = glob.glob(os.path.join(ANN_DIR_IN, '*.json')) for image_id, filename in enumerate(label_files): print('Generating dataset from:', filename) label_file = labelme.LabelFile(filename=filename) base = os.path.splitext(os.path.basename(filename))[0] out_img_file = os.path.join(IMG_DIR_OUT, base + ".jpg") img = labelme.utils.img_data_to_arr(label_file.imageData) PIL.Image.fromarray(img).save(out_img_file) data['images'].append(dict( license=0, url=None, file_name=os.path.basename(out_img_file), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) masks = {} # for area segmentations = collections.defaultdict(list) # for segmentation for shape in label_file.shapes: points = shape['points'] label = shape['label'] group_id = shape.get('group_id') shape_type = shape.get('shape_type') mask = labelme.utils.shape_to_mask( img.shape[:2], points, shape_type ) if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask points = np.asarray(points).flatten().tolist() segmentations[instance].append(points) segmentations = dict(segmentations) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() data['annotations'].append(dict( id=len(data['annotations']), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, )) with open(ANN_FILEPATH, 'w') as f: json.dump(data, f)
def process(image_id, label_file, output_dir, class_name_to_id): #print('Generating dataset from:', label_file) with open(label_file) as f: label_data = json.load(f) base = osp.splitext(osp.basename(label_file))[0] out_img_file = osp.join(output_dir, 'JPEGImages', base + '.jpg') # NOTE: copy the image file img_file = osp.join(osp.dirname(label_file), label_data['imagePath']) img = np.asarray(PIL.Image.open(img_file)) # NOTE: gather polygons polygons = [] #masks = {} for shape in label_data['shapes']: points = shape['points'] label = shape['label'] shape_type = shape.get('shape_type', None) mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) mask = np.asfortranarray(mask.astype(np.uint8)) if shape['shape_type'] == 'polygon': coords = [coord for coords in points for coord in coords] elif shape['shape_type'] == 'rectangle': x1, y1 = points[0] x2, y2 = points[1] coords = [x1, y1, x1, y2, x2, y2, x2, y1] else: raise Exception('unknown shape type') polygons.append((label, mask, coords)) annotations = [] for label, mask, polygon in polygons: #print label, polygons[label] #print(label, polygon) cls_name = label.split('-')[0] if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] segmentation = pycocotools.mask.encode(mask) segmentation['counts'] = segmentation['counts'].decode() area = float(pycocotools.mask.area(segmentation)) bbox = list(pycocotools.mask.toBbox(segmentation)) annotations.append( dict( segmentation=[polygon], #segmentation = segmentation, area=area, iscrowd=0, #iscrowd = 1, image_id=image_id, category_id=cls_id, id=-1, bbox=bbox, )) #annot_count += 1 PIL.Image.fromarray(img).save(out_img_file) return img, out_img_file, annotations
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter ) parser.add_argument('input_dir', help='input annotated directory') parser.add_argument('output_dir', help='output dataset directory') parser.add_argument('--labels', help='labels file', required=True) args = parser.parse_args() if osp.exists(args.output_dir): print('Output directory already exists:', args.output_dir) sys.exit(1) os.makedirs(args.output_dir) os.makedirs(osp.join(args.output_dir, 'JPEGImages')) print('Creating dataset:', args.output_dir) now = datetime.datetime.now() data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime('%Y-%m-%d %H:%M:%S.%f'), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type='instances', annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) class_name_to_id = {} for i, line in enumerate(open(args.labels).readlines()): class_id = i - 1 # starts with -1 class_name = line.strip() if class_id == -1: assert class_name == '__ignore__' continue class_name_to_id[class_name] = class_id data['categories'].append(dict( supercategory=None, id=class_id, name=class_name, )) out_ann_file = osp.join(args.output_dir, 'annotations.json') label_files = glob.glob(osp.join(args.input_dir, '*.json')) for image_id, label_file in enumerate(label_files): print('Generating dataset from:', label_file) with open(label_file) as f: label_data = json.load(f) base = osp.splitext(osp.basename(label_file))[0] out_img_file = osp.join( args.output_dir, 'JPEGImages', base + '.jpg' ) img_file = osp.join( osp.dirname(label_file), label_data['imagePath'] ) img = np.asarray(PIL.Image.open(img_file)) PIL.Image.fromarray(img).save(out_img_file) data['images'].append(dict( license=0, url=None, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) masks = {} # for area segmentations = collections.defaultdict(list) # for segmentation for shape in label_data['shapes']: points = shape['points'] label = shape['label'] shape_type = shape.get('shape_type', None) mask = labelme.utils.shape_to_mask( img.shape[:2], points, shape_type ) if label in masks: masks[label] = masks[label] | mask else: masks[label] = mask points = np.asarray(points).flatten().tolist() segmentations[label].append(points) for label, mask in masks.items(): cls_name = label.split('-')[0] if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() data['annotations'].append(dict( id=len(data['annotations']), image_id=image_id, category_id=cls_id, segmentation=segmentations[label], area=area, bbox=bbox, iscrowd=0, )) with open(out_ann_file, 'w') as f: json.dump(data, f)
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("--input_dir", nargs='*', help="input annotated directory") parser.add_argument("--output_dir", help="output dataset directory") parser.add_argument("--labels", help="labels file", required=True) parser.add_argument("--noviz", help="no visualization", action="store_true") parser.add_argument('--split', type=float, nargs='?', default=0.9, help="Train set size; a number in (0, 1)") args = parser.parse_args() if osp.exists(args.output_dir): print("Output directory already exists:", args.output_dir) sys.exit(1) os.makedirs(args.output_dir) os.makedirs(osp.join(args.output_dir, "JPEGImages")) if not args.noviz: os.makedirs(osp.join(args.output_dir, "Visualization")) print("Creating dataset:", args.output_dir) now = datetime.datetime.now() data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime("%Y-%m-%d %H:%M:%S.%f"), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type="instances", annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) class_name_to_id = {} for i, line in enumerate(open(args.labels).readlines()): class_id = i - 1 # starts with -1 class_name = line.strip() if class_id == -1: assert class_name == "__ignore__" continue class_name_to_id[class_name] = class_id data["categories"].append( dict( supercategory=None, id=class_id, name=class_name, )) out_ann_file_all = osp.join(args.output_dir, "_coco.json") out_ann_file_train = osp.join(args.output_dir, "_train.json") out_ann_file_test = osp.join(args.output_dir, "_test.json") print("working directory is:", os.getcwd()) label_files_per_dir = [] # label_files is a list of lists if args.input_dir is None: args.input_dir = [x[0] for x in os.walk(os.getcwd())] args.input_dir.sort(key=lambda f: int(regex.sub('\D', '', f))) print("input dir(s) are:", args.input_dir) if isinstance(args.input_dir, list): # multiple dirs were given: for dir in args.input_dir: label_files_per_dir.append(glob.glob(osp.join(dir, "*.json"))) else: label_files_per_dir = [glob.glob(osp.join(args.input_dir, "*.json"))] data_train = copy.deepcopy(data) data_test = copy.deepcopy(data) image_id = 0 for label_files in label_files_per_dir: # train, test split if len(label_files) > 0: train, test = train_test_split(label_files, train_size=args.split) for set_name, split_set in [("train", train), ("test", test)]: print("generating set:", set_name) for filename in split_set: print("Generating dataset from:", filename) label_file = labelme.LabelFile(filename=filename) base = osp.splitext(osp.basename(filename))[0] out_img_file = osp.join(args.output_dir, "JPEGImages", base + ".jpg") img = labelme.utils.img_data_to_arr(label_file.imageData) imgviz.io.imsave(out_img_file, img) image_data = dict( license=0, url=None, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file_all)), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, ) masks = {} # for area segmentations = collections.defaultdict( list) # for segmentation for shape in label_file.shapes: points = shape["points"] label = shape["label"] group_id = shape.get("group_id") shape_type = shape.get("shape_type", "polygon") mask = labelme.utils.shape_to_mask( img.shape[:2], points, shape_type) if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask if shape_type == "rectangle": (x1, y1), (x2, y2) = points x1, x2 = sorted([x1, x2]) y1, y2 = sorted([y1, y2]) points = [x1, y1, x2, y1, x2, y2, x1, y2] else: points = np.asarray(points).flatten().tolist() segmentations[instance].append(points) segmentations = dict(segmentations) if len(masks.keys()) > 0: # image contains annotations, so add it. data["images"].append(image_data) if set_name == "train": data_train["images"].append(image_data) if set_name == "test": data_test["images"].append(image_data) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() annotation_data = dict( id=len(data["annotations"]), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, ) data["annotations"].append(annotation_data) if set_name == "train": data_train["annotations"].append(annotation_data) if set_name == "test": data_test["annotations"].append(annotation_data) if not args.noviz: labels, captions, masks = zip( *[(class_name_to_id[cnm], cnm, msk) for (cnm, gid), msk in masks.items() if cnm in class_name_to_id]) viz = imgviz.instances2rgb( image=img, labels=labels, masks=masks, captions=captions, font_size=15, line_width=2, ) out_viz_file = osp.join(args.output_dir, "Visualization", base + ".jpg") imgviz.io.imsave(out_viz_file, viz) # increment image counter image_id += 1 with open(out_ann_file_all, "w") as f: json.dump(data, f) with open(out_ann_file_train, "w") as f: json.dump(data_train, f) with open(out_ann_file_test, "w") as f: json.dump(data_test, f)
def main(): os.makedirs(args.output_dir, exist_ok=True) os.makedirs(osp.join(args.output_dir, "JPEGImages"), exist_ok=True) if not args.noviz: os.makedirs(osp.join(args.output_dir, "Visualization"), exist_ok=True) print("Creating dataset:", args.output_dir) now = datetime.datetime.now() data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime("%Y-%m-%d %H:%M:%S.%f"), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type="instances", annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) class_name_to_id = {} for i, line in enumerate(open(args.labels).readlines()): print(line, i) class_id = i - 1 # starts with -1 class_name = line.strip() if class_id == -1: continue class_name_to_id[class_name] = class_id keypointsNm = ['c' + str(no) for no in range(1, 11, 1)] skeleton = [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10]] data["categories"].append( dict( supercategory=None, id=class_id, keypoints=keypointsNm, name=class_name, skeleton=skeleton, )) out_ann_file = osp.join(args.output_dir, "annotations.json") print('op', out_ann_file) label_files = glob.glob(osp.join(args.input_dir, "*.json")) for image_id, filename in enumerate(label_files): print("Generating dataset from:", filename) label_file = labelme.LabelFile(filename=filename) base = osp.splitext(osp.basename(filename))[0] out_img_file = osp.join(args.output_dir, "JPEGImages", base + ".jpg") img = labelme.utils.img_data_to_arr(label_file.imageData) imgviz.io.imsave(out_img_file, img) data["images"].append( dict( license=0, url=None, file_name=osp.basename( osp.relpath(out_img_file, osp.dirname(out_ann_file))), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) masks = {} # for area segmentations = collections.defaultdict(list) # for segmentation allckeypoints = [] allrkeypoints = [] for shape in label_file.shapes: points = shape["points"] label = shape["label"] group_id = shape.get("group_id") shape_type = shape.get("shape_type", "polygon") mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask if shape_type == "rectangle": (x1, y1), (x2, y2) = points x1, x2 = sorted([x1, x2]) y1, y2 = sorted([y1, y2]) points = [x1, y1, x2, y1, x2, y2, x1, y2] elif shape_type == "point": (x1, y1) = points[0] if label == 'c': allckeypoints.append([x1, y1]) if label == 'r': allrkeypoints.append([x1, y1]) else: points = np.asarray(points).flatten().tolist() segmentations[instance].append(points) segmentations = dict(segmentations) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() ckeypoints = [] for kp in allckeypoints: if pointInRect(kp, bbox): ckeypoints.append([kp[0], kp[1], 2]) # rkeypoints=[] # for kp in allrkeypoints: # if pointInRect(kp,bbox): # rkeypoints.append([kp[0],kp[1],2]) ckeypoints = np.array( sorted(ckeypoints, key=lambda x: x[0], reverse=False)) # rkeypoints=np.array(sorted(rkeypoints, key=lambda y: y[1], reverse=False)) c_num_keypoints = int(ckeypoints.shape[0]) # r_num_keypoints=int(rkeypoints.shape[0]) if c_num_keypoints > 0: keypoints_empty = np.zeros((10, 3)) keypoints_empty[0:ckeypoints.shape[0], 0:ckeypoints.shape[1]] = ckeypoints ckeypoints = keypoints_empty.ravel().tolist() else: keypoints_empty = np.zeros((10, 3)) ckeypoints = keypoints_empty.ravel().tolist() # if r_num_keypoints>0: # keypoints_empty=b = np.zeros((25,3)) # keypoints_empty[0:rkeypoints.shape[0],0:rkeypoints.shape[1]]=rkeypoints # rkeypoints=keypoints_empty.ravel().tolist() # else: # rkeypoints=[] # keypoints = np.hstack((ckeypoints,rkeypoints)).tolist() keypoints = ckeypoints kdict = dict( id=len(data["annotations"]), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, #r_num_keypoints=r_num_keypoints ) if len(keypoints) > 0: kdict['keypoints'] = keypoints kdict['c_num_keypoints'] = c_num_keypoints data["annotations"].append(kdict) if not args.noviz: labels, captions, masks = zip(*[(class_name_to_id[cnm], cnm, msk) for (cnm, gid), msk in masks.items() if cnm in class_name_to_id]) viz = imgviz.instances2rgb( image=img, labels=labels, masks=masks, captions=captions, font_size=15, line_width=2, ) out_viz_file = osp.join(args.output_dir, "Visualization", base + ".jpg") imgviz.io.imsave(out_viz_file, viz) with open(out_ann_file, "w") as f: json.dump(data, f) print(out_ann_file)
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter ) parser.add_argument("input_dir", help="input annotated directory") parser.add_argument("--labels", help="labels file", required=True) parser.add_argument( "--noviz", help="no visualization", action="store_true" ) args = parser.parse_args() now = datetime.datetime.now() ########################## f=open('annotation_mask.txt', 'w') count=0 class_name_to_id = {} for i, line in enumerate(open(args.labels).readlines()): class_id = i - 1 # starts with -1 class_name = line.strip() if class_id == -1: assert class_name == "__ignore__" continue class_name_to_id[class_name] = class_id label_files = glob.glob(osp.join(args.input_dir, "*.json")) for image_id, filename in enumerate(label_files): label_file = labelme.LabelFile(filename=filename) base = osp.splitext(osp.basename(filename))[0] img = labelme.utils.img_data_to_arr(label_file.imageData) masks = {} # for area segmentations = collections.defaultdict(list) # for segmentation for shape in label_file.shapes: points = shape["points"] label = shape["label"] group_id = shape.get("group_id") shape_type = shape.get("shape_type", "polygon") mask = labelme.utils.shape_to_mask( img.shape[:2], points, shape_type ) if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask if shape_type == "rectangle": (x1, y1), (x2, y2) = points x1, x2 = sorted([x1, x2]) y1, y2 = sorted([y1, y2]) points = [x1, y1, x2, y1, x2, y2, x1, y2] else: points = np.asarray(points).flatten().tolist() segmentations[instance].append(points) segmentations = dict(segmentations) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) if not args.noviz: labels, captions, masks = zip( *[ (class_name_to_id[cnm], cnm, msk) for (cnm, gid), msk in masks.items() if cnm in class_name_to_id ] ) ###########333 f.write(str(base)) f.write("\n") f.write(str((masks))) f.write("\n") mask = [np.where(m == 1, 255, m) for m in masks[0]] #f.write(str((mask))) for i in mask: for k in i: if k==255 : count=count+1 f.write(str(count)) f.write("\n\n") count=0 ########## f.close()
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('input_dir', help='input annotated directory') parser.add_argument('output_dir', help='output dataset directory') parser.add_argument('--labels', help='labels file', required=True) args = parser.parse_args() if osp.exists(args.output_dir): print('Output directory already exists:', args.output_dir) sys.exit(1) os.makedirs(args.output_dir) os.makedirs(osp.join(args.output_dir, 'JPEGImages')) print('Creating dataset:', args.output_dir) now = datetime.datetime.now() data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime('%Y-%m-%d %H:%M:%S.%f'), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type='instances', annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) class_name_to_id = {} for i, line in enumerate(open(args.labels).readlines()): class_id = i - 1 # starts with -1 class_name = line.strip() if class_id == -1: assert class_name == '__ignore__' continue elif class_id == 0: assert class_name == '_background_' class_name_to_id[class_name] = class_id data['categories'].append( dict( supercategory=None, id=class_id, name=class_name, )) out_ann_file = osp.join(args.output_dir, 'annotations.json') label_files = glob.glob(osp.join(args.input_dir, '*.json')) for image_id, label_file in enumerate(label_files): print('Generating dataset from:', label_file) with open(label_file) as f: label_data = json.load(f) base = osp.splitext(osp.basename(label_file))[0] out_img_file = osp.join(args.output_dir, 'JPEGImages', base + '.jpg') img_file = osp.join(osp.dirname(label_file), label_data['imagePath']) img = np.asarray(PIL.Image.open(img_file)) PIL.Image.fromarray(img).save(out_img_file) data['images'].append( dict( license=0, url=None, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) masks = {} for shape in label_data['shapes']: points = shape['points'] label = shape['label'] shape_type = shape.get('shape_type', None) mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) mask = np.asfortranarray(mask.astype(np.uint8)) if label in masks: masks[label] = masks[label] | mask else: masks[label] = mask for label, mask in masks.items(): cls_name = label.split('-')[0] if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] segmentation = pycocotools.mask.encode(mask) segmentation['counts'] = segmentation['counts'].decode() area = float(pycocotools.mask.area(segmentation)) data['annotations'].append( dict( segmentation=segmentation, area=area, iscrowd=None, image_id=image_id, category_id=cls_id, )) with open(out_ann_file, 'w') as f: json.dump(data, f)
def get_boxdata_dicts(img_dir): img_idx = -1 print(os.listdir(img_dir)) dataset_dicts = [] for dir_ in os.listdir(img_dir): print(dir_) dir_ = os.path.join(img_dir, dir_) rgb_dir = os.path.join(dir_, 'rgb') hha_dir = os.path.join(dir_, 'hha') depth_dir = os.path.join(dir_, 'depth') for rgb_name in os.listdir(rgb_dir): if '.png' not in rgb_name: continue img_idx += 1 rgb_file = os.path.join(rgb_dir, rgb_name) json_file = rgb_file[:-3] + 'json' hha_file = os.path.join(hha_dir, rgb_name) depth_file = os.path.join(depth_dir, rgb_name) # print(rgb_file, json_file, hha_file, depth_file,'\n') with open(json_file) as f: img_ann = json.load(f) img = cv2.imread(rgb_file) height, width = img.shape[:2] record = {} record["file_name"] = rgb_file record["hha_name"] = hha_file record["depth_name"] = depth_file record['image_id'] = img_idx record['height'] = height record['width'] = width annos = img_ann['shapes'] segmentations = collections.defaultdict(list) # for segmentation masks = {} # for area objs = [] for anno in annos: points = anno["points"] label = anno["label"] group_id = anno.get('group_id') mask = labelme.utils.shape_to_mask(img.shape[:2], points, 'polygon') if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask points = np.asarray(points).flatten().tolist() segmentations[instance].append(points) segmentations = dict(segmentations) # print(segmentations) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() obj = dict( category_id=0, # category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, bbox_mode=BoxMode.XYWH_ABS, ) if __name__ == '__main__': obj.update({'mask': pycocotools.mask.decode(mask)}) objs.append(obj) record['annotations'] = objs dataset_dicts.append(record) return dataset_dicts
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('input_dir', help='input annotated directory') parser.add_argument('output_dir', help='output dataset directory') parser.add_argument('--labels', help='labels file', required=True) args = parser.parse_args() if osp.exists(args.output_dir): print('Output directory already exists:', args.output_dir) sys.exit(1) os.makedirs(args.output_dir) os.makedirs(osp.join(args.output_dir, 'JPEGImages/input')) print('Creating dataset:', args.output_dir) now = datetime.datetime.now() data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime('%Y-%m-%d %H:%M:%S.%f'), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type='instances', annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) class_name_to_id = {} # read label class name(class_name) from labels.txt for i, line in enumerate(open(args.labels).readlines()): class_id = i - 1 # starts with -1 class_name = line.strip() # print("class_name: ", class_name) if class_id == -1: assert class_name == '__ignore__' continue class_name_to_id[class_name] = class_id data['categories'].append( dict( supercategory=None, id=class_id, name=class_name, )) out_ann_file = osp.join(args.output_dir, 'annotations.json') label_files = glob.glob(osp.join(args.input_dir, '*.xml')) for image_id, label_file in enumerate(label_files): print('Generating dataset from:', label_file) tree = XET.parse(label_file) root = tree.getroot() filename = get_and_check(root, 'filename', 1).text # <filename> to {images: file_name} if filename == "0" or filename == "1": continue # folder = get_and_check(root, 'folder', 1).text # <filename> not be used # imagesize = get_and_check(root, 'imagesize', 1) # <imagesize> not be used # nrows = int(get_and_check(imagesize, 'nrows', 1).text) # <imagesize> <nrows> not be used # ncols = int(get_and_check(imagesize, 'ncols', 1).text) # <imagesize> <ncols> not be used objectname = get( root, 'object') # <object> contain label info, like classname, point filename = label_file.replace("xml", "jpg") out_img_file = osp.join(args.output_dir, 'JPEGImages', filename) img_file = filename img = np.asarray(PIL.Image.open(img_file).convert('RGB')) PIL.Image.fromarray(img).save(out_img_file) data['images'].append( dict( license=0, url=None, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)), height=img.shape[0], # height=nrows, width=img.shape[1], # width=ncols, date_captured=None, id=image_id, )) masks = {} # for {annotations: area} segmentations = collections.defaultdict( list) # for {annotations: segmentation} for obj in objectname: label_name = get_and_check( obj, 'name', 1).text # <object> <name> get the label class shape_type = 'polygon' # for mask shape_to_mask polygon = get_and_check(obj, 'polygon', 1) # <object> <polygon> pts = get(polygon, 'pt') # <object> <polygon> <pt> points = [] for pt in pts: pt_x = float(get_and_check( pt, 'x', 1).text) # <object> <polygon> <pt> <x> pt_y = float(get_and_check( pt, 'y', 1).text) # <object> <polygon> <pt> <y> points.append([pt_x, pt_y]) group_id = uuid.uuid1() instance = (label_name, group_id) mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) points = np.asarray(points).flatten().tolist() masks[instance] = mask segmentations[instance].append( points ) # label points convert <object> <polygon> <pt> to {annotations: segmentation} segmentations = dict(segmentations) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() data['annotations'].append( dict( id=len(data['annotations']), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, )) with open(out_ann_file, 'w') as f: json.dump(data, f)
images = [] annotations = [] for i, name in enumerate(names): img_name = img_name_fmt % name ann_path = os.path.join(inst_path, ann_name_fmt % name) ann = scipy.io.loadmat(ann_path)['GTinst'][0][0] classes = [int(x[0]) for x in ann[2]] seg = ann[0] for idx in range(len(classes)): mask = (seg == (idx + 1)).astype(np.float) rle = pycocotools.mask.encode(np.asfortranarray(mask.astype(np.uint8))) rle['counts'] = rle['counts'].decode('ascii') annotations.append({'id': ann_id, 'image_id': image_id, 'category_id': classes[idx], 'segmentation': rle, 'area': float(mask.sum()), 'bbox': [int(x) for x in mask2bbox(mask)], 'iscrowd': 0}) ann_id += 1 img_name = img_name_fmt % name img = cv2.imread(os.path.join(img_path, img_name))
def _getAnno(self, label_file, img, image_id): """ Extract all annotations from single labeled json file. Arguments: label_file: label_file object img: img_arr image_id (int): """ masks = {} # for area segmentations = collections.defaultdict(list) # for segmentation keypoints = {} self._extractAnno(label_file, masks, segmentations, keypoints, img.shape[:2]) # sort keypoints to get ordered value for _, kp in keypoints.items(): kp.sort(key=lambda x: x[0]) segmentations = dict(segmentations) if self.debug: print("\nShapes len: ", len(label_file.shapes)) print("Mask: ", len(masks), masks.keys()) print("Segm", len(segmentations)) # for segclass, items in keypoints.items(): # print("Keypoints: ", segclass, items) self.masks = masks annotations = self.data["annotations"] if len(masks) > 0: for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in self.class_name_to_id: continue cls_id = self.class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = self.cocomask.encode(mask) bbox = self.cocomask.toBbox(mask).flatten().tolist() # it calculates mask area, not box area that torch needs area = float(self.cocomask.area(mask)) # following is the area that torch needs # area = float(bbox[2] * bbox[3]) # bbox = [bbox[0], bbox[1], bbox[0], bbox[1]] # format for torch anno = dict( id=len(annotations), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, ) if cls_name in keypoints: kps = keypoints[cls_name] # 3-element-tuple list kplist = [] num = 0 # print(kps, "========") for kp in kps: # kp is the 3-element-tuple list k = kp[2] kplist.append(k[0]) kplist.append(k[1]) kplist.append(2) num += 1 anno.update({ "keypoints": kplist, # [[kp[0], kp[1], 1] for kp in kps ], # format for torch "num_keypoints": num, }) annotations.append(anno) else: ## TODO tmp solution for my task # print("No mask found\n\n") # print(keypoints) cls_name = list(keypoints.keys())[0] cls_id = self.class_name_to_id[cls_name] anno = dict( id=len(annotations), image_id=image_id, category_id=cls_id, segmentation=[], area=0, bbox=[0., 0., 256., 256.], iscrowd=0, ) if cls_name in keypoints: kps = keypoints[cls_name] # 3-element-tuple list kplist = [] num = 0 # print(kps, "========") for kp in kps: # kp is the 3-element-tuple list k = kp[2] kplist.append(k[0]) kplist.append(k[1]) kplist.append(2) num += 1 anno.update({ "keypoints": kplist, # [[kp[0], kp[1], 1] for kp in kps ], # format for torch "num_keypoints": num, }) annotations.append(anno) if self.debug: print(annotations)
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('input_dir', help='input annotated directory') parser.add_argument('output_dir', help='output dataset directory') parser.add_argument('--labels', help='labels file', required=True) args = parser.parse_args() if osp.exists(args.output_dir): print('Output directory already exists:', args.output_dir) sys.exit(1) os.makedirs(args.output_dir) #os.makedirs(osp.join(args.output_dir, 'JPEGImages')) anno_path = osp.join(args.output_dir, 'annotations') imgs_path = osp.join(args.output_dir, 'images', 'train2014') valimgs_path = osp.join(args.output_dir, 'images', 'val2014') print(imgs_path) os.makedirs(anno_path) os.makedirs(imgs_path) os.makedirs(valimgs_path) print('Creating dataset:', args.output_dir) now = datetime.datetime.now() data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime('%Y-%m-%d %H:%M:%S.%f'), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type='instances', annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) class_name_to_id = {} for i, line in enumerate(open(args.labels).readlines()): class_id = i - 1 # starts with -1 class_name = line.strip() if class_id == -1: assert class_name == '__ignore__' continue class_name_to_id[class_name] = class_id data['categories'].append( dict( supercategory=None, id=class_id, name=class_name, )) #out_ann_file = osp.join(args.output_dir, 'annotations.json') out_ann_file = osp.join(args.output_dir, 'annotations', 'instances_train2014.json') out_valann_file = osp.join(args.output_dir, 'annotations', 'instances_minival2014.json') label_files = glob.glob(osp.join(args.input_dir, '*.json')) for image_id, label_file in enumerate(label_files): #Arnold file_name_str = os.path.basename(label_file) file_name_str = file_name_str.split(".")[0] if file_name_str.isdigit(): image_id = int(file_name_str) print('Generating dataset from:', label_file) with open(label_file) as f: label_data = json.load(f) #base = osp.splitext(osp.basename(label_file))[0] image_id_str = "{0:0>12}".format(image_id) base = 'COCO_train2014_' + image_id_str out_img_file = osp.join( #args.output_dir, 'JPEGImages', base + '.jpg' imgs_path, base + '.jpg') base_val = 'COCO_val2014_' + image_id_str out_valimg_file = osp.join(valimgs_path, base_val + '.jpg') img_file = osp.join(osp.dirname(label_file), label_data['imagePath']) img = np.asarray(PIL.Image.open(img_file)) PIL.Image.fromarray(img).save(out_img_file) PIL.Image.fromarray(img).save(out_valimg_file) data['images'].append( dict( license=0, url=None, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)).replace( "\\", "/"), #Arnold height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) masks = {} # for area segmentations = collections.defaultdict(list) # for segmentation for shape in label_data['shapes']: points = shape['points'] label = shape['label'] shape_type = shape.get('shape_type', None) mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) if label in masks: masks[label] = masks[label] | mask else: masks[label] = mask points = np.asarray(points).flatten().tolist() segmentations[label].append(points) for label, mask in masks.items(): cls_name = label.split('-')[0] if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() data['annotations'].append( dict( id=len(data['annotations']), image_id=image_id, category_id=cls_id, segmentation=segmentations[label], area=area, bbox=bbox, iscrowd=0, )) with open(out_ann_file, 'w') as f: json_str = json.dumps(data, indent=4, cls=MyEncoder) f.write(json_str) shutil.copyfile(out_ann_file, out_valann_file)
def convert(input_annotated_dir, output_annotated_dir, labels_file='labels.txt', vis=False, save_mask=True, train_valid_split=0.7): assert os.path.isfile( labels_file), "Please provide the correct label file." assert os.path.exists(input_annotated_dir), "Please check the input dir." class_instance_counter = {} train_class_instance_counter = {} if not osp.exists(output_annotated_dir): os.makedirs(output_annotated_dir) os.makedirs(osp.join(output_annotated_dir, 'train', "JPEGImages")) os.makedirs(osp.join(output_annotated_dir, 'valid', "JPEGImages")) if vis: train_vis_dir = osp.join(output_annotated_dir, 'train', 'Visualization') _create_dirs(train_vis_dir) valid_vis_dir = osp.join(output_annotated_dir, 'valid', 'Visualization') _create_dirs(valid_vis_dir) if save_mask and vis: train_mask_dir = osp.join(output_annotated_dir, 'train', 'Masks') _create_dirs(train_mask_dir) valid_mask_dir = osp.join(output_annotated_dir, 'valid', 'Masks') _create_dirs(valid_mask_dir) print("Creating dataset:", output_annotated_dir) training_examples_sofar = 0 now = datetime.datetime.now() train_data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime("%Y-%m-%d %H:%M:%S.%f"), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type="instances", annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) valid_data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime("%Y-%m-%d %H:%M:%S.%f"), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type="instances", annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) class_name_to_id = {} with open(labels_file, 'r') as lf: for i, line in enumerate(lf.readlines()): class_id = i - 1 # starts with -1 class_name = line.strip() if class_id == -1: assert class_name == "__ignore__" continue if class_name != '_background_': class_instance_counter[class_name] = 0 train_class_instance_counter[class_name] = 0 class_name_to_id[class_name] = class_id train_data["categories"].append( dict( supercategory=None, id=class_id, name=class_name, )) valid_data["categories"].append( dict( supercategory=None, id=class_id, name=class_name, )) train_out_ann_file = osp.join(output_annotated_dir, 'train', "annotations.json") valid_out_ann_file = osp.join(output_annotated_dir, 'valid', "annotations.json") label_files = glob.glob(osp.join(input_annotated_dir, "*.json")) num_label_files = len(label_files) training_percentage = 0.7 if train_valid_split > 1 and train_valid_split <= num_label_files: training_percentage = train_valid_split / num_label_files if train_valid_split > num_label_files: # if the provided number is not valid # e.g. with too many frames # each image has the 0.7 probaility # to be assigned for training train_valid_split = 0.7 _angles = [ 0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225, 240, 255, 270, 285, 300, 315, 330, 345, 360 ] for image_id, filename in enumerate(label_files): yield ((image_id + 1) / num_label_files) * 100, filename label_file = labelme.LabelFile(filename=filename) base = osp.splitext(osp.basename(filename))[0] train_out_img_file = osp.join(output_annotated_dir, 'train', "JPEGImages", base + ".jpg") valid_out_img_file = osp.join(output_annotated_dir, 'valid', "JPEGImages", base + ".jpg") img = labelme.utils.img_data_to_arr(label_file.imageData) is_train = 0 # for area masks = {} # for segmentation segmentations = collections.defaultdict(list) for shape in label_file.shapes: points = shape["points"] label = shape["label"] group_id = shape.get("group_id") shape_type = shape.get("shape_type", "polygon") if train_valid_split > 1: if training_examples_sofar < train_valid_split: train_class_instance_counter[ label] = train_class_instance_counter.get(label, 0) if train_class_instance_counter[label] == 0: is_train = 1 elif train_class_instance_counter[label] <= ( train_valid_split / len(train_class_instance_counter)) + 1: is_train = 1 # make sure very instances in the class is covered # before random sampling elif 0 not in train_class_instance_counter.values(): is_train = 1 else: is_train = np.random.choice( [0, 1], p=[1 - training_percentage, training_percentage]) elif train_valid_split < 1: is_train = np.random.choice( [0, 1], p=[1 - train_valid_split, train_valid_split]) elif train_valid_split == 1: is_train = 1 try: class_instance_counter[label] += 1 except KeyError: class_instance_counter[label] = 1 if is_train == 1: try: train_class_instance_counter[label] += 1 except KeyError: train_class_instance_counter[label] = 1 if shape_type == 'point': try: cx, cy = points[0] radius = 10.0 + np.random.choice(np.arange(0, 1, 0.1)) xs = cx + (radius * np.cos(np.array(_angles) * np.pi / 180)) ys = cy + (radius * np.sin(np.array(_angles) * np.pi / 180)) points = np.asarray([list(p) for p in zip(xs, ys)]) shape_type = "polygon" except IndexError: continue print(f"{filename} has a invalid point {points}.") mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask if shape_type == "rectangle": (x1, y1), (x2, y2) = points x1, x2 = sorted([x1, x2]) y1, y2 = sorted([y1, y2]) points = np.asarray([x1, y1, x2, y1, x2, y2, x1, y2]) segmentations[instance].append(points.flatten().tolist()) elif shape_type == "circle": (x1, y1), (x2, y2) = points radius = int(((x1 - x2)**2 + (y1 - y2)**2)**(1 / 2)) xs = x1 + (radius * np.cos(np.array(_angles) * np.pi / 180)) ys = y1 + (radius * np.sin(np.array(_angles) * np.pi / 180)) points = np.asarray([list(p) for p in zip(xs, ys)]) points = np.asarray(points).flatten().tolist() shape_type = "polygon" segmentations[instance].append(points) else: points = np.asarray(points).flatten().tolist() segmentations[instance].append(points) segmentations = dict(segmentations) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() if is_train: train_data["annotations"].append( dict( id=len(train_data["annotations"]), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, )) else: valid_data["annotations"].append( dict( id=len(valid_data["annotations"]), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, )) if is_train == 1: training_examples_sofar += 1 imgviz.io.imsave(train_out_img_file, img) else: imgviz.io.imsave(valid_out_img_file, img) if is_train == 1: train_data["images"].append( dict( license=0, url=None, # handle windows backward slash issue file_name=osp.relpath( train_out_img_file, osp.dirname(train_out_ann_file)).replace("\\", '/'), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) else: valid_data["images"].append( dict( license=0, url=None, file_name=osp.relpath( valid_out_img_file, osp.dirname(valid_out_ann_file)).replace("\\", '/'), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) if save_mask and vis: lbl, _ = labelme.utils.shapes_to_label(img.shape, label_file.shapes, class_name_to_id) if is_train == 1: out_mask_file = osp.join(train_mask_dir, base + '_mask.png') else: out_mask_file = osp.join(valid_mask_dir, base + '_mask.png') labelme.utils.lblsave(out_mask_file, lbl) if vis: labels, captions, masks = zip(*[(class_name_to_id[cnm], cnm, msk) for (cnm, gid), msk in masks.items() if cnm in class_name_to_id]) viz = imgviz.instances2rgb( image=img, labels=labels, masks=masks, captions=captions, font_size=15, line_width=2, ) if is_train: out_viz_file = osp.join(output_annotated_dir, "train", "Visualization", base + ".jpg") else: out_viz_file = osp.join(output_annotated_dir, "valid", "Visualization", base + ".jpg") imgviz.io.imsave(out_viz_file, viz) with open(train_out_ann_file, "w") as f: json.dump(train_data, f) with open(valid_out_ann_file, "w") as f: json.dump(valid_data, f) # create a data.yaml config file categories = [] for c in train_data["categories"]: # exclude backgroud with id 0 if not c['id'] == 0: categories.append(c['name']) data_yaml = Path(f"{output_annotated_dir}/data.yaml") names = list(categories) input_annotated_dir_name = os.path.basename(input_annotated_dir) output_annotated_dir_name = os.path.basename(output_annotated_dir) # dataset folder is in same dir as the yolov5 folder with open(data_yaml, 'w') as dy: dy.write(f"DATASET:\n") dy.write(f" name: '{input_annotated_dir_name}'\n") dy.write( f""" train_info: '{data_yaml.parent /"train"/"annotations.json"}'\n""" ) dy.write(f""" train_images: '{data_yaml.parent /"train"}'\n""") dy.write( f""" valid_info: '{data_yaml.parent /"valid"/"annotations.json"}'\n""" ) dy.write(f""" valid_images: '{data_yaml.parent /"valid"}'\n""") dy.write(f" class_names: {names}\n") dy.write(f"YOLACT:\n") dy.write(f" name: '{input_annotated_dir_name}'\n") dy.write(f" dataset: 'dataset_{input_annotated_dir_name}_coco'\n") dy.write(f" max_size: 512\n") print('Done.') print("All: ", class_instance_counter) print("Training set: ", train_class_instance_counter)
def __getitem__(self, id): data = self.data[id] keypoints = data['keypoints'] if 'keypoints' in data else '' bbox = data['bbox'] score = data['score'] if 'score' in data else 1 index = data['index'] file_name = data['file_name'] image_id = data['image_id'] mask = data['mask'] if 'mask' in data else '' image_path = self.get_image_path(file_name) input_data = cv2.imread(image_path) #(h,w,3) info = {} info['index'] = index # rotation and rescale augmentation if self.mode == 'train' and self.augment == True: s = self.aug_scale r = self.aug_rotation aug_scale = np.clip(np.random.randn() * s + 1, 1 - s, 1 + s) # 1-s,1+s aug_rotation = np.clip(np.random.randn() * r, -2 * r, 2 * r) if random.random() <= 0.6 else 0 else: aug_scale = 1 aug_rotation = 0 # transform the image to adapt input size affine_matrix = make_affine_matrix( bbox, self.input_size, margin=self.margin_to_border, aug_scale=aug_scale, aug_rotation=aug_rotation, ) input_data = cv2.warpAffine( input_data, affine_matrix[[0, 1], :], self.input_size, ) if self.transform is not None: # torchvision.transforms.ToTensor() and normalize() # (H,W,3) range [0,255] numpy.ndarray ==> (c,h,w) [0.0,1.0] =>[-1.0,1.0] torch.FloatTensor input_data = self.transform(input_data) # add mask information to dataset if mask is not '': mask = cv2.warpAffine( mask, affine_matrix[[0, 1], :], self.input_size) #note! mask:(h_,w_,1)->(h,w) mask = cv2.resize(mask, self.heatmap_size) mask = mask.astype(np.float32) mask = mask[np.newaxis, :, :] #(1,h,w,x) or(1,h,w) # mask may be divided into several parts( ndim =4) we make them into a singel heatmap if mask.ndim == 4: mask = np.amax(mask, axis=3) # train mode if self.mode == 'train': keypoints = self.kpt_affine(keypoints, affine_matrix) # flip with 0.5 probability if self.augment and self.flip and np.random.random( ) <= 0.5 and self.transform is not None: input_data = input_data.flip( [2]) # dataloader does not support negative numpy index keypoints[:, 0] = self.input_size[0] - 1 - keypoints[:, 0] keypoints = symmetric_exchange_after_flip(keypoints, self.name) if mask is not '': #mask = np.flip(mask,2) # dataloader does not support negative numpy index mask = torch.from_numpy(mask).flip([2]).numpy() # Random Occlusion Augmentation strategy if self.random_occlusion: input_data, keypoints = Random_Occlusion_Augmentation( input_data, keypoints, self.name, probability=self.occlusion_prob, size=self.occlusion_size, block_nums=self.occlusion_nums, mode="specified_occlusion") heatmap_gt, kpt_visible = self.make_gt_heatmaps(keypoints) info['keypoints'] = keypoints info['prior_mask'] = mask return input_data, heatmap_gt, kpt_visible, info # valid or test mode if self.mode == 'val' or self.mode == 'dt': info['prior_mask'] = mask #info['area'] = area return input_data, image_id, score, np.linalg.inv( affine_matrix), np.array(bbox), info
annotations = [] for name in names: img_name = img_name_fmt % name ann_path = os.path.join(inst_path, ann_name_fmt % name) ann = scipy.io.loadmat(ann_path)['GTinst'][0][0] classes = [int(x[0]) for x in ann[2]] seg = ann[0] for idx in range(len(classes)): mask = (seg == (idx + 1)).astype(np.float) rle = pycocotools.mask.encode( np.asfortranarray(mask.astype(np.uint8))) rle['counts'] = rle['counts'].decode('ascii') annotations.append({ 'id': ann_id, 'image_id': image_id, 'category_id': classes[idx], 'segmentation': rle, 'area': float(mask.sum()), 'bbox': [int(x) for x in mask2bbox(mask)], 'iscrowd': 0 }) ann_id += 1 img_name = img_name_fmt % name
def labelme2coco(input_dir, output_dir, annotations_file, trainval_percent, train_percent): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--input_dir', default=input_dir, help='input annotated directory') parser.add_argument('--output_dir', default=output_dir, help='output dataset directory') parser.add_argument('--labels', default=annotations_file, help='labels file', required=False) args = parser.parse_args() if osp.exists(args.output_dir): shutil.rmtree(args.output_dir) os.makedirs(args.output_dir) os.makedirs(osp.join(args.output_dir, 'train')) os.makedirs(osp.join(args.output_dir, 'val')) os.makedirs(osp.join(args.output_dir, 'test')) print('Creating dataset:', args.output_dir) # print('Output directory already exists:', args.output_dir) # sys.exit(1) now = datetime.datetime.now() data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime('%Y-%m-%d %H:%M:%S.%f'), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type='instances', annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) class_names = [] class_name_to_id = {} for i, line in enumerate(open(args.labels).readlines()): class_id = i - 1 # starts with -1 class_name = line.strip() if class_id == -1: assert class_name == '__ignore__' continue class_name_to_id[class_name] = class_id data['categories'].append( dict( supercategory=None, id=class_id, name=class_name, )) class_names.append(class_name) # save class_names.txt class_names = tuple(class_names) print("class_names:", class_names) out_class_names_file = osp.join(output_dir, "class_names.txt") with open(out_class_names_file, "w") as f: f.writelines("\n".join(class_names)) print("Saved class_names:", out_class_names_file) out_annotations = osp.join(args.output_dir, 'annotations') if not os.path.exists(out_annotations): os.makedirs(out_annotations) label_files = glob.glob(osp.join(args.input_dir, '*.json')) num_total = len(label_files) num_trainval = int(num_total * trainval_percent) num_train = int(num_trainval * train_percent) trainval = random.sample(range(num_total), num_trainval) train = random.sample(trainval, num_train) train_files = [] val_files = [] test_files = [] for i in range(num_total): if i in trainval: if i in train: train_files.append(label_files[i]) else: val_files.append(label_files[i]) else: test_files.append(label_files[i]) for i in range(3): temp_file = [] dir_name = None if i == 0: out_ann_file = osp.join(args.output_dir, "annotations", 'train.json') temp_file = train_files dir_name = "train" for image_id, label_file in enumerate(temp_file): print('Generating dataset from:', label_file) with open(label_file) as f: label_data = json.load(f) base = osp.splitext(osp.basename(label_file))[0] out_img_file = osp.join(args.output_dir, dir_name, base + '.jpg') img_file = osp.join(osp.dirname(label_file), label_data['imagePath']) img = np.asarray(PIL.Image.open(img_file).convert('RGB')) PIL.Image.fromarray(img).save(out_img_file) data['images'].append( dict( license=0, url=None, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) masks = {} # for area segmentations = collections.defaultdict( list) # for segmentation for shape in label_data['shapes']: points = shape['points'] label = shape['label'] group_id = shape.get('group_id') shape_type = shape.get('shape_type') mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask points = np.asarray(points).flatten().tolist() segmentations[instance].append(points) segmentations = dict(segmentations) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() data['annotations'].append( dict( id=len(data['annotations']), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, )) with open(out_ann_file, 'w') as f: json.dump(data, f) elif i == 1: out_ann_file = osp.join(args.output_dir, "annotations", 'val.json') temp_file = val_files dir_name = "val" for image_id, label_file in enumerate(temp_file): print('Generating dataset from:', label_file) with open(label_file) as f: label_data = json.load(f) base = osp.splitext(osp.basename(label_file))[0] out_img_file = osp.join(args.output_dir, dir_name, base + '.jpg') img_file = osp.join(osp.dirname(label_file), label_data['imagePath']) img = np.asarray(PIL.Image.open(img_file).convert('RGB')) PIL.Image.fromarray(img).save(out_img_file) data['images'].append( dict( license=0, url=None, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) masks = {} # for area segmentations = collections.defaultdict( list) # for segmentation for shape in label_data['shapes']: points = shape['points'] label = shape['label'] group_id = shape.get('group_id') shape_type = shape.get('shape_type') mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask points = np.asarray(points).flatten().tolist() segmentations[instance].append(points) segmentations = dict(segmentations) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() data['annotations'].append( dict( id=len(data['annotations']), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, )) with open(out_ann_file, 'w') as f: json.dump(data, f) elif i == 2: out_ann_file = osp.join(args.output_dir, "annotations", 'test.json') temp_file = test_files dir_name = "test" for image_id, label_file in enumerate(temp_file): print('Generating dataset from:', label_file) with open(label_file) as f: label_data = json.load(f) base = osp.splitext(osp.basename(label_file))[0] out_img_file = osp.join(args.output_dir, dir_name, base + '.jpg') img_file = osp.join(osp.dirname(label_file), label_data['imagePath']) img = np.asarray(PIL.Image.open(img_file).convert('RGB')) PIL.Image.fromarray(img).save(out_img_file) data['images'].append( dict( license=0, url=None, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) masks = {} # for area segmentations = collections.defaultdict( list) # for segmentation for shape in label_data['shapes']: points = shape['points'] label = shape['label'] group_id = shape.get('group_id') shape_type = shape.get('shape_type') mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask points = np.asarray(points).flatten().tolist() segmentations[instance].append(points) segmentations = dict(segmentations) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() data['annotations'].append( dict( id=len(data['annotations']), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, )) with open(out_ann_file, 'w') as f: json.dump(data, f)
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('input_dir', help='input annotated directory') parser.add_argument('output_dir', help='output dataset directory') parser.add_argument('--labels', help='labels file', required=True) args = parser.parse_args() if osp.exists(args.output_dir): print('Output directory already exists:', args.output_dir) sys.exit(1) os.makedirs(args.output_dir) os.makedirs(osp.join(args.output_dir, 'JPEGImages')) print('Creating dataset:', args.output_dir) now = datetime.datetime.now() data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime('%Y-%m-%d %H:%M:%S.%f'), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type='instances', annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) class_name_to_id = {} for i, line in enumerate(open(args.labels).readlines()): class_id = i - 1 # starts with -1 class_name = line.strip() if class_id == -1: assert class_name == '__ignore__' continue class_name_to_id[class_name] = class_id data['categories'].append( dict( supercategory=None, id=class_id, name=class_name, )) out_ann_file = osp.join(args.output_dir, 'annotations.json') label_files = glob.glob(osp.join(args.input_dir, '*.json')) for image_id, filename in enumerate(label_files): print('Generating dataset from:', filename) label_file = labelme.LabelFile(filename=filename) base = osp.splitext(osp.basename(filename))[0] out_img_file = osp.join(args.output_dir, 'JPEGImages', base + '.jpg') img = labelme.utils.img_data_to_arr(label_file.imageData) PIL.Image.fromarray(img).save(out_img_file) data['images'].append( dict( license=0, url=None, file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)), height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) masks = {} # for area segmentations = collections.defaultdict(list) # for segmentation for shape in label_file.shapes: points = shape['points'] label = shape['label'] group_id = shape.get('group_id') shape_type = shape.get('shape_type') mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask points = np.asarray(points).flatten().tolist() segmentations[instance].append(points) segmentations = dict(segmentations) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() data['annotations'].append( dict( id=len(data['annotations']), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, )) with open(out_ann_file, 'w') as f: json.dump(data, f)
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument( "--input_dir", default= 'C:/Users/62349/Desktop/labelme/examples/instance_segmentation/pear_4_train', help="input annotated directory") parser.add_argument( "--output_dir", default= 'C:/Users/62349/Desktop/labelme/examples/instance_segmentation/train', help="output dataset directory") parser.add_argument( "--labels", default= 'C:/Users/62349/Desktop/labelme/examples/instance_segmentation/labels.txt', help="labels file") # 标签,其中含有每个类别的名字 parser.add_argument("--noviz", help="no visualization", action="store_true") args = parser.parse_args() if osp.exists(args.output_dir): print("Output directory already exists:", args.output_dir) sys.exit(1) os.makedirs(args.output_dir) os.makedirs(osp.join(args.output_dir, "JPEGImages")) if not args.noviz: os.makedirs(osp.join(args.output_dir, "Visualization")) print("Creating dataset:", args.output_dir) now = datetime.datetime.now() data = dict( info=dict( description=None, url=None, version=None, year=now.year, contributor=None, date_created=now.strftime("%Y-%m-%d %H:%M:%S.%f"), ), licenses=[dict( url=None, id=0, name=None, )], images=[ # license, url, file_name, height, width, date_captured, id ], type="instances", annotations=[ # segmentation, area, iscrowd, image_id, bbox, category_id, id ], categories=[ # supercategory, id, name ], ) class_name_to_id = {} for i, line in enumerate(open(args.labels).readlines()): class_id = i - 1 # starts with -1 class_name = line.strip() if class_id == -1: assert class_name == "__ignore__" continue class_name_to_id[class_name] = class_id data["categories"].append( dict( supercategory=None, id=class_id, name=class_name, )) out_ann_file = osp.join(args.output_dir, "annotations.json") #label_files = glob.glob(osp.join(args.input_dir, "*.json")) ### clw modify label_files = [] for root, dirs, files in os.walk(args.input_dir): for file in files: if os.path.splitext(file)[1] == '.json': # 想要保存的文件格式 label_files.append(os.path.join(root, file)) ### #print('clw:', label_files) for image_id, filename in enumerate(label_files): print("Generating dataset from:", filename) label_file = labelme.LabelFile(filename=filename) base = osp.splitext(osp.basename(filename))[0] #print('clw:base=', base) out_img_file = osp.join(args.output_dir, "JPEGImages", base + ".jpg") img = labelme.utils.img_data_to_arr(label_file.imageData) imgviz.io.imsave(out_img_file, img) data["images"].append( dict( license=0, url=None, file_name=base + ".jpg", # clw modify: origin is osp.relpath(out_img_file, osp.dirname(out_ann_file)), not fit the windows height=img.shape[0], width=img.shape[1], date_captured=None, id=image_id, )) masks = {} # for area segmentations = collections.defaultdict(list) # for segmentation for shape in label_file.shapes: points = shape["points"] label = shape["label"] group_id = shape.get("group_id") shape_type = shape.get("shape_type", "polygon") mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type) if group_id is None: group_id = uuid.uuid1() instance = (label, group_id) if instance in masks: masks[instance] = masks[instance] | mask else: masks[instance] = mask if shape_type == "rectangle": (x1, y1), (x2, y2) = points x1, x2 = sorted([x1, x2]) y1, y2 = sorted([y1, y2]) points = [x1, y1, x2, y1, x2, y2, x1, y2] else: points = np.asarray(points).flatten().tolist() segmentations[instance].append(points) segmentations = dict(segmentations) for instance, mask in masks.items(): cls_name, group_id = instance if cls_name not in class_name_to_id: continue cls_id = class_name_to_id[cls_name] mask = np.asfortranarray(mask.astype(np.uint8)) mask = pycocotools.mask.encode(mask) area = float(pycocotools.mask.area(mask)) bbox = pycocotools.mask.toBbox(mask).flatten().tolist() ### clw note: 考虑扩边处理,比如用YOLACT检测水果圆度,如果没有扩边,可能矩形标注框和梨贴合过于紧密,导致回归的时候, # 有时框并不那么准确,因此会有部分梨超出bbox范围,这样在crop_mask的时候,会有部分mask被bbox的直线截取, # 导致圆度的测量会不准确! ### if cls_name == 'pear': border = 200 bbox[0] -= border bbox[1] -= border bbox[2] += border * 2 # bbox[2]和[3]是wh,因此需要扩2倍 bbox[3] += border * 2 ### data["annotations"].append( dict( id=len(data["annotations"]), image_id=image_id, category_id=cls_id, segmentation=segmentations[instance], area=area, bbox=bbox, iscrowd=0, )) if not args.noviz: labels, captions, masks = zip(*[(class_name_to_id[cnm], cnm, msk) for (cnm, gid), msk in masks.items() if cnm in class_name_to_id]) viz = imgviz.instances2rgb( image=img, labels=labels, masks=masks, captions=captions, font_size=15, line_width=2, ) out_viz_file = osp.join(args.output_dir, "Visualization", base + ".jpg") imgviz.io.imsave(out_viz_file, viz) with open(out_ann_file, "w") as f: json.dump(data, f)