Create Better Datasets for Object Detection Models |OpenCV GUI for Cleaning Datasets

→ OpenCV GUI for Cleaning Object Detection Datasets

siromer
5 min readMay 9, 2024

There are several important things in Deep Learning, and I believe Data is the most crucial thing. Without having proper data, it is very hard to get good results. Even if you train your models with powerful pretrained models and GPUs, your model may not be perform well.

  • In this article, I will cover how to obtain datasets, analyze datasets, and clean them with a simple OpenCV GUI application. I will use Python as a programming language.
Labeled Image

Best Websites for Data

There are 2 main methods to obtain data :

  1. The first method is to generate your own data. You can take photos using your phone’s camera, or scrape the internet. After obtaining images, you need to label them(for object detection), and this process may take a long time.
  2. Second method is way easier, you can get your data from websites, there are many dataset in internet for free.

Before selecting a dataset, I always check these 2 websites. If I can’t find a suitable dataset, then I use first method.

How to decide whether a dataset is ready to use or not ?

  • If you create your own dataset, you probably won’t need to clean it because you took the photos and labeled them yourself. You can clean it during the creation process, there is no need to additional step for cleaning.
  • If you download a dataset directly from internet, you will need to inspect it. There may be unrelated images, incorrect labels, or low-quality images.

I typically start by randomly inspecting the dataset. I just check the quality of images and observe the distribution of objects, I dont give much attention to dataset. If everything appears acceptable, I train a small model. After evaluating the result, I can usually understand whether the data needs to be cleaned or if it can be used for training.

  • If I decide the data is not ready to use, I clean it using the simple OpenCV GUI that I created. Now I will show you how you can create this GUI and use it for cleaning datasets.

I wrote two different articles about how you can process data for image classification tasks : Pytorch article , Tensorflow article

GUI For Cleaning Data

It is pretty simple to use and very effective. User can see labels, bounding boxes, image itself in one screen and decide whether it can be used in dataset or not.

  • If user decide image is appropriate, image and label are copied to another folder that will be used for training later. (pressing “s”)
  • If user don’t think image is appropriate, image and labels are deleted.(pressing space bar)

Actually, this is very effective because you can see the image, and upon that image, you can see the labels as well.

With this GUI , user can combine different datasets in one folder, and choose best images for his purpose

CODE

  • Import necessary libraries
import cv2
import os
import shutil
import random
  • Create folders for images and labels
# Define the path to your folder containing images

# folders for all images and labels
image_folder = 'original-images'
label_folder = 'original-labels'

# folders for selected images and labels
saved_images_folder= 'saved-images'
saved_labels_folder = 'saved-labels'
  • Take image file paths and shuffle them.

Note: In Object Detection datasets, each image file has a corresponding label file with matching names. This naming convention is universal. For example, if there is an image file named “image23.jpg” , there exist a “image23.txt” file containing information about labels and bounding boxes.

# Get a list of all image files in the folder
image_files = [f for f in os.listdir(image_folder) if f.endswith(('.jpg', '.png', '.jpeg'))]

# Randomly shuffle the list of image files
random.shuffle(image_files)
  • Function for displaying image,labels and bounding boxes
# Function to display image and handle keypress
def display_image(image_path, label_path):
img = cv2.imread(image_path)
with open(label_path, 'r') as f:
lines = f.readlines()

for line in lines:
class_id, x_center, y_center, width, height = map(float, line.strip().split())
# Convert YOLO format to pixel coordinates
img_h, img_w, _ = img.shape
x_center *= img_w
y_center *= img_h
width *= img_w
height *= img_h
x_min = int(x_center - (width / 2))
y_min = int(y_center - (height / 2))
x_max = int(x_center + (width / 2))
y_max = int(y_center + (height / 2))

# Draw bounding box
cv2.rectangle(img, (x_min, y_min), (x_max, y_max), (0, 255, 0), 2)

# Get class name based on class_id
class_names = ['black-bishop', 'black-king', 'black-knight', 'black-pawn', 'black-queen', 'black-rook', 'white-bishop', 'white-king', 'white-knight', 'white-pawn', 'white-queen', 'white-rook']
class_name = class_names[int(class_id)]

# Write class name
cv2.putText(img, class_name, (x_min, y_min - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)

cv2.imshow('Image', img)
key = cv2.waitKey(0)
return key
  • Main loop

# Main loop to display images and handle selection
for image_file in image_files:
image_path = os.path.join(image_folder, image_file)
label_path = os.path.join(label_folder, image_file.replace('.jpg', '.txt')) # Assuming label files have the same name as image files with a .txt extension

# Check if the label file exists
if os.path.exists(label_path):
key = display_image(image_path,label_path)

# Press 's' to save the image and its corresponding label file to the selected folder
if key == ord('s'):
selected_image_path = os.path.join(saved_images_folder, image_file)
selected_label_path = os.path.join(saved_labels_folder, image_file.replace('.jpg', '.txt'))

shutil.move(image_path, selected_image_path) # Move the image file to the selected folder
shutil.move(label_path, selected_label_path) # Move the label file to the saved labels folder

print(f"Image '{image_file}' and its corresponding label file saved.")

elif key == ord(' '):
os.remove(image_path)
os.remove(label_path)
continue # Move to the next image

elif key == ord('q'):
break

else:
print(f"No label file found for image '{image_file}'.")
continue # Skip to the next image

cv2.destroyAllWindows()
  • After pressing “q”, the GUI will closed. Users can then find the saved images and labels inside the “saved-images” and “saved-labels” folders.

--

--