Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solutions to 'make_dirs' problem in labelbox_json2yolo.py code #37

Closed
Leprechault opened this issue Jan 5, 2023 · 3 comments
Closed

Comments

@Leprechault
Copy link

Leprechault commented Jan 5, 2023

I'd like to convert my label file in *json to YOLO * txt with to class ('bsb','wsb') using the labelbox_json2yolo.py.

In my data (image and label file) I have:

file = "https://raw.githubusercontent.com/Leprechault/trash/main/YT_EMBRAPA_002.zip" # Patch to zip file in GitHub

import json
import os
from pathlib import Path

import requests
import yaml
from PIL import Image
from tqdm import tqdm

from utils import make_dirs


def convert(file, zip=True):
    # Convert Labelbox JSON labels to YOLO labels
    names = ['bsb','wsb']  # class names
    file = Path(file)
    save_dir = make_dirs(file.stem)
    with open(file) as f:
        data = json.load(f)  # load JSON

    for img in tqdm(data, desc=f'Converting {file}'):
        im_path = img['Labeled Data']
        im = Image.open(requests.get(im_path, stream=True).raw if im_path.startswith('http') else im_path)  # open
        width, height = im.size  # image size
        label_path = save_dir / 'labels' / Path(img['External ID']).with_suffix('.txt').name
        image_path = save_dir / 'images' / img['External ID']
        im.save(image_path, quality=95, subsampling=0)

        for label in img['Label']['objects']:
            # box
            top, left, h, w = label['bbox'].values()  # top, left, height, width
            xywh = [(left + w / 2) / width, (top + h / 2) / height, w / width, h / height]  # xywh normalized

            # class
            cls = label['value']  # class name
            if cls not in names:
                names.append(cls)

            line = names.index(cls), *xywh  # YOLO format (class_index, xywh)
            with open(label_path, 'a') as f:
                f.write(('%g ' * len(line)).rstrip() % line + '\n')

    # Save dataset.yaml
    d = {'path': f"../datasets/{file.stem}  # dataset root dir",
         'train': "images/train  # train images (relative to path) 128 images",
         'val': "images/val  # val images (relative to path) 128 images",
         'test': " # test images (optional)",
         'nc': len(names),
         'names': names}  # dictionary

    with open(save_dir / file.with_suffix('.yaml').name, 'w') as f:
        yaml.dump(d, f, sort_keys=False)

    # Zip
    if zip:
        print(f'Zipping as {save_dir}.zip...')
        os.system(f'zip -qr {save_dir}.zip {save_dir}')

    print('Conversion completed successfully!')


if __name__ == '__main__':
    convert('export-2021-06-29T15_25_41.934Z.json')

I have tried to run the script but I get the following error:

---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Cell In[6], line 10
      7 from PIL import Image
      8 from tqdm import tqdm
---> 10 from utils import make_dirs

ImportError: cannot import name 'make_dirs' from 'utils' (C:\Users\fores\anaconda3\lib\site-packages\utils\__init__.py)

Is possible to give a local directory in my machine and not call make_dirs(file.stem)? Please, any help with it?

@ichsan2895
Copy link

I'd like to convert my label file in *json to YOLO * txt with to class ('bsb','wsb') using the labelbox_json2yolo.py.

In my data (image and label file) I have:

file = "https://raw.githubusercontent.com/Leprechault/trash/main/YT_EMBRAPA_002.zip" # Patch to zip file in GitHub

import json
import os
from pathlib import Path

import requests
import yaml
from PIL import Image
from tqdm import tqdm

from utils import make_dirs


def convert(file, zip=True):
    # Convert Labelbox JSON labels to YOLO labels
    names = ['bsb','wsb']  # class names
    file = Path(file)
    save_dir = make_dirs(file.stem)
    with open(file) as f:
        data = json.load(f)  # load JSON

    for img in tqdm(data, desc=f'Converting {file}'):
        im_path = img['Labeled Data']
        im = Image.open(requests.get(im_path, stream=True).raw if im_path.startswith('http') else im_path)  # open
        width, height = im.size  # image size
        label_path = save_dir / 'labels' / Path(img['External ID']).with_suffix('.txt').name
        image_path = save_dir / 'images' / img['External ID']
        im.save(image_path, quality=95, subsampling=0)

        for label in img['Label']['objects']:
            # box
            top, left, h, w = label['bbox'].values()  # top, left, height, width
            xywh = [(left + w / 2) / width, (top + h / 2) / height, w / width, h / height]  # xywh normalized

            # class
            cls = label['value']  # class name
            if cls not in names:
                names.append(cls)

            line = names.index(cls), *xywh  # YOLO format (class_index, xywh)
            with open(label_path, 'a') as f:
                f.write(('%g ' * len(line)).rstrip() % line + '\n')

    # Save dataset.yaml
    d = {'path': f"../datasets/{file.stem}  # dataset root dir",
         'train': "images/train  # train images (relative to path) 128 images",
         'val': "images/val  # val images (relative to path) 128 images",
         'test': " # test images (optional)",
         'nc': len(names),
         'names': names}  # dictionary

    with open(save_dir / file.with_suffix('.yaml').name, 'w') as f:
        yaml.dump(d, f, sort_keys=False)

    # Zip
    if zip:
        print(f'Zipping as {save_dir}.zip...')
        os.system(f'zip -qr {save_dir}.zip {save_dir}')

    print('Conversion completed successfully!')


if __name__ == '__main__':
    convert('export-2021-06-29T15_25_41.934Z.json')
I have tried to run the script but I get the following error:

---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Cell In[6], line 10
      7 from PIL import Image
      8 from tqdm import tqdm
---> 10 from utils import make_dirs

ImportError: cannot import name 'make_dirs' from 'utils' (C:\Users\fores\anaconda3\lib\site-packages\utils\__init__.py)

Is possible to give a local directory in my machine and not call make_dirs(file.stem)? Please, any help with it?

if you download this repo, you will get utils.py which contains function make_dirs()

FYI, Take a look in this thread
ultralytics/yolov5#10621

@Leprechault
Copy link
Author

Thanks @ichsan2895 !!

@glenn-jocher
Copy link
Member

You're welcome! If you have any more questions or need further assistance, feel free to ask. Good luck with your project!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants