| | import os
|
| | import json
|
| | import numpy as np
|
| | import cv2
|
| | import shutil
|
| | from tqdm import tqdm
|
| |
|
| |
|
| | def labelme2mask_single_img(img_path, labelme_json_path, class_info):
|
| | '''
|
| | Convert a single image's LabelMe annotation to a mask.
|
| | '''
|
| | img_bgr = cv2.imread(img_path)
|
| | img_mask = np.zeros(img_bgr.shape[:2], dtype=np.uint8)
|
| |
|
| | with open(labelme_json_path, 'r', encoding='utf-8') as f:
|
| | labelme = json.load(f)
|
| |
|
| | for one_class in class_info:
|
| | for each in labelme['shapes']:
|
| | if each['label'] == one_class['label']:
|
| | if one_class['type'] == 'polygon':
|
| | points = [np.array(each['points'], dtype=np.int32).reshape((-1, 1, 2))]
|
| | img_mask = cv2.fillPoly(img_mask, points, color=one_class['color'])
|
| | elif one_class['type'] == 'line' or one_class['type'] == 'linestrip':
|
| | points = [np.array(each['points'], dtype=np.int32).reshape((-1, 1, 2))]
|
| | img_mask = cv2.polylines(img_mask, points, isClosed=False, color=one_class['color'],
|
| | thickness=one_class.get('thickness', 1))
|
| | elif one_class['type'] == 'circle':
|
| | points = np.array(each['points'], dtype=np.int32)
|
| | center_x, center_y = points[0][0], points[0][1]
|
| | edge_x, edge_y = points[1][0], points[1][1]
|
| | radius = int(np.linalg.norm([center_x - edge_x, center_y - edge_y]))
|
| | img_mask = cv2.circle(img_mask, (center_x, center_y), radius, one_class['color'], -1)
|
| | else:
|
| | print('Unknown annotation type:', one_class['type'])
|
| |
|
| | return img_mask
|
| |
|
| |
|
| | def convert_labelme_to_mask(Dataset_Path):
|
| | '''
|
| | Convert all LabelMe annotations in the dataset to mask images.
|
| | '''
|
| |
|
| | img_dir = os.path.join(Dataset_Path, 'images')
|
| | ann_dir = os.path.join(Dataset_Path, 'labelme_jsons')
|
| |
|
| |
|
| | class_info = [
|
| | {'label': 'panicle', 'type': 'polygon', 'color': 1}
|
| | ]
|
| |
|
| |
|
| | images_target_dir = os.path.join(Dataset_Path, 'img_dir')
|
| | ann_target_dir = os.path.join(Dataset_Path, 'ann_dir')
|
| |
|
| |
|
| | os.makedirs(images_target_dir, exist_ok=True)
|
| | os.makedirs(ann_target_dir, exist_ok=True)
|
| |
|
| |
|
| | for img_name in tqdm(os.listdir(img_dir), desc="Converting images to masks"):
|
| | try:
|
| | img_path = os.path.join(img_dir, img_name)
|
| | labelme_json_path = os.path.join(ann_dir, f'{os.path.splitext(img_name)[0]}.json')
|
| |
|
| | if os.path.exists(labelme_json_path):
|
| |
|
| | img_mask = labelme2mask_single_img(img_path, labelme_json_path, class_info)
|
| |
|
| |
|
| | mask_path = os.path.join(ann_target_dir, f'{os.path.splitext(img_name)[0]}.png')
|
| | cv2.imwrite(mask_path, img_mask)
|
| |
|
| |
|
| | shutil.move(img_path, os.path.join(images_target_dir, img_name))
|
| | else:
|
| | print(f"Annotation file missing for {img_name}")
|
| |
|
| | except Exception as e:
|
| | print(f"Failed to convert {img_name}: {e}")
|
| |
|
| |
|
| | shutil.rmtree(img_dir, ignore_errors=True)
|
| | shutil.rmtree(ann_dir, ignore_errors=True)
|
| |
|
| | print("Conversion completed.")
|
| |
|
| |
|
| | if __name__ == '__main__':
|
| | Dataset_Path = 'CVRP'
|
| | convert_labelme_to_mask(Dataset_Path)
|
| |
|