openvinotoolkit / anomalib

An anomaly detection library comprising state-of-the-art algorithms and features such as experiment management, hyper-parameter optimization, and edge inference.
https://anomalib.readthedocs.io/en/latest/
Apache License 2.0
3.4k stars 615 forks source link

Labelme Conversion script #2105

Open monkeycc opened 1 month ago

monkeycc commented 1 month ago
dataset
├── anomalous
│  ├── 00.jpg
│  ├── 01.jpg
│  ...
├── masks
│  ├── 00.jpg
│  ├── 01.jpg
│  ...

I hope the official Labelme conversion script is available

samet-akcay commented 1 month ago

@monkeycc, can you please provide more information? I'm not sure if I understand what exactly you want to achieve

monkeycc commented 1 month ago

labelme datasets

1.jpg
1.json
2.jpg
2.json
....
  1. Convert labelme annotation images to custom datasets
  2. Convert labelme annotation images to the MVTecAD dataset

Hope the official has a dataset conversion script

alexriedel1 commented 1 month ago

Info: A script that converts segmentation annotations created using labelme to binary label masks that can be processed by anomalibs dataset structures.

You are very lucky :D I wrote it and will provide it to you :) It assumes your folder structure is:

dataset
├── anomalous
│  ├── 00.jpg
│  ├── 00.json
│  ├── 01.jpg
│  ├── 01.json
│  ...

But can change the names of the anomalous dir and the mask dir as you wish

import json
import labelme
import glob
from pathlib import Path
import cv2
import warnings
import os

dataset_dir = Path("dataset")
anomalous_dir = dataset_dir / "anomalous"
ground_truth_dir = dataset_dir / "ground_truth"

if not os.path.isdir(dataset_dir):
    raise FileNotFoundError(f"Dataset dir {dataset_dir} not found")

if not os.path.isdir(anomalous_dir):
    raise FileNotFoundError(f"Anomalous dir {anomalous_dir} not found")

ground_truth_dir.mkdir(parents=True, exist_ok=True)
json_masks = glob.glob(f"{anomalous_dir}/*.json")

if len(json_masks) < 1:
    raise ValueError(f"Could not find any json masks in {anomalous_dir}")

for mask_path in json_masks:
    print(f"Processing {mask_path}")
    with open(mask_path, "r",encoding="utf-8") as f:
        dj = json.load(f)

    if len(dj['shapes']) < 1:
        warnings.warn(f"Could not find any mask shapes in file {mask_path}")
        continue

    mask = 0
    for i, shape in enumerate(dj['shapes']):
        mask += labelme.utils.shape.shape_to_mask((dj['imageHeight'],dj['imageWidth']), dj['shapes'][i]['points'], shape_type=None,line_width=1, point_size=1)

    file = Path(mask_path).stem
    save_file = f"{ground_truth_dir}/{file}.png"
    mask_img = mask.astype(int)
    os.remove(mask_path)
    cv2.imwrite(save_file, mask_img * 255)