Skip to content

Commit

Permalink
feat: Add LabelMe to YOLO format conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
healthonrails committed Dec 2, 2024
1 parent bcaa3cd commit eef8d25
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 1 deletion.
2 changes: 1 addition & 1 deletion annolid/annotation/labelme2yolo.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class Labelme2YOLO:

def __init__(self,
json_dir,
yolo_dataset_name="YOLOV8_dataset"
yolo_dataset_name="YOLO_dataset"
):
self.json_file_dir = json_dir
self.label_to_id_dict = self.map_label_to_id(self.json_file_dir)
Expand Down
15 changes: 15 additions & 0 deletions annolid/gui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,15 @@ def __init__(self,
"Load SLEAP h5",
self.tr("Load SLEAP h5")
)

convert_labelme2yolo_format = action(
self.tr("&Convert Labelme to YOLO format"),
self.convert_labelme2yolo_format,
None,
"Convert Labelme to YOLO format",
self.tr("Convert Labelme to YOLO format")
)

place_perference = action(
self.tr("&Place Preference"),
self.place_preference_analyze,
Expand Down Expand Up @@ -467,6 +476,7 @@ def __init__(self,
utils.addActions(self.menus.file, (convert_csv,))
utils.addActions(self.menus.file, (extract_shape_keypoints,))
utils.addActions(self.menus.file, (convert_sleap,))
utils.addActions(self.menus.file, (convert_labelme2yolo_format,))
utils.addActions(self.menus.file, (place_perference,))
utils.addActions(self.menus.file, (advance_params,))

Expand Down Expand Up @@ -590,6 +600,11 @@ def convert_sleap_h5_to_labelme(self):
convert_sleap_h5_widget = ConvertSleapDialog()
convert_sleap_h5_widget.exec_()

def convert_labelme2yolo_format(self):
from annolid.gui.widgets import convert_labelme2yolo
convert_labelme2yolo_widget = convert_labelme2yolo.YOLOConverterWidget()
convert_labelme2yolo_widget.exec_()

def extract_and_save_shape_keypoints(self):
extract_shape_keypoints_dialog = ExtractShapeKeyPointsDialog()
extract_shape_keypoints_dialog.exec_()
Expand Down
99 changes: 99 additions & 0 deletions annolid/gui/widgets/convert_labelme2yolo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import os
from qtpy.QtWidgets import (
QDialog, QVBoxLayout, QLabel, QLineEdit, QPushButton, QFileDialog, QMessageBox, QProgressBar
)
from qtpy.QtCore import Qt
from annolid.annotation.labelme2yolo import Labelme2YOLO


class YOLOConverterWidget(QDialog):
def __init__(self, parent=None):
super(YOLOConverterWidget, self).__init__(parent)

# Layout
self.setWindowTitle("LabelMe to YOLO Converter")
self.layout = QVBoxLayout()

# Widgets for folder selection
self.json_dir_label = QLabel("Select JSON Directory:")
self.json_dir_input = QLineEdit()
self.browse_button = QPushButton("Browse")
self.browse_button.clicked.connect(self.select_json_directory)

self.layout.addWidget(self.json_dir_label)
self.layout.addWidget(self.json_dir_input)
self.layout.addWidget(self.browse_button)

# Validation and test size inputs
self.val_size_label = QLabel("Validation Size (0.0 to 1.0):")
self.val_size_input = QLineEdit("0.1") # Default value is 10%
self.test_size_label = QLabel("Test Size (0.0 to 1.0):")
self.test_size_input = QLineEdit("0.1") # Default value is 10%

self.layout.addWidget(self.val_size_label)
self.layout.addWidget(self.val_size_input)
self.layout.addWidget(self.test_size_label)
self.layout.addWidget(self.test_size_input)

# Convert button
self.convert_button = QPushButton("Convert to YOLO Format")
self.convert_button.clicked.connect(self.run_conversion)
self.layout.addWidget(self.convert_button)

# Progress bar and message label
self.progress_bar = QProgressBar()
self.progress_bar.setAlignment(Qt.AlignCenter)
self.layout.addWidget(self.progress_bar)

self.message_label = QLabel("")
self.layout.addWidget(self.message_label)

self.setLayout(self.layout)

def select_json_directory(self):
"""
Opens a file dialog to select the directory containing JSON files.
"""
json_dir = QFileDialog.getExistingDirectory(
self, "Select JSON Directory")
if json_dir:
self.json_dir_input.setText(json_dir)

def run_conversion(self):
"""
Runs the LabelMe to YOLO conversion script.
"""
json_dir = self.json_dir_input.text().strip()
val_size = self.val_size_input.text().strip()
test_size = self.test_size_input.text().strip()

if not os.path.isdir(json_dir):
QMessageBox.warning(
self, "Error", "Please select a valid JSON directory.")
return

try:
val_size = float(val_size)
test_size = float(test_size)
if not (0 <= val_size <= 1) or not (0 <= test_size <= 1):
raise ValueError(
"Validation and test sizes must be between 0.0 and 1.0.")
except ValueError:
QMessageBox.warning(
self, "Error", "Please enter valid numbers for validation and test sizes.")
return

self.progress_bar.setValue(10)
self.message_label.setText("Starting conversion...")

try:
converter = Labelme2YOLO(json_dir)
converter.convert(val_size=val_size, test_size=test_size)
self.progress_bar.setValue(100)
self.message_label.setText("Conversion successful!")
QMessageBox.information(
self, "Success", "YOLO dataset created successfully.")
except Exception as e:
self.progress_bar.setValue(0)
self.message_label.setText(f"Error: {str(e)}")
QMessageBox.critical(self, "Error", f"An error occurred: {str(e)}")

0 comments on commit eef8d25

Please sign in to comment.