|
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)
|
|
|