I’m working on a project to visualize annotations made using LabelImg on a set of images. However, when I display these images with the annotated bounding boxes using OpenCV in Python, the bounding boxes appear to be consistently offset from their correct positions.
I’ve verified that the coordinates printed from the JSON files are correct and match the annotations as seen in LabelImg. But when these coordinates are used to draw bounding boxes on the images, there’s a noticeable offset.
Here’s a sample of the JSON data from LabelImg:
[
{
"image": "rtu.JPG",
"annotations": [
{
"label": "fan",
"coordinates": {
"x": 608.6441717791412,
"y": 243.26993865030676,
"width": 135.0,
"height": 108.0
}
}
]
}
]
And screenshot from inside the labellmg
tool with correct coordinates around the fan
.
And here is the Python code I’m using to load the images and draw the bounding boxes:
import os
import json
import numpy as np
import cv2
import matplotlib.pyplot as plt
from tensorflow.keras.preprocessing.image import load_img, img_to_array
# Define the directory path
directory = r'C:Usersdataahu'
# Function to load data with annotations
def load_data_with_annotations(src_dir):
images = []
annotations = []
for file in os.listdir(src_dir):
if file.endswith('.json'):
json_path = os.path.join(src_dir, file)
with open(json_path, 'r') as f:
annotation_data = json.load(f)
for annotation in annotation_data:
img_file = annotation['image']
img_path = os.path.join(src_dir, img_file)
if not os.path.exists(img_path):
print(f"Image {img_file} not found.")
continue
# Load image
img = load_img(img_path)
img_array = img_to_array(img)
img_cv2 = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
# Store images and annotations
images.append(img_cv2)
annotations.append(annotation['annotations'])
return images, annotations
images, annotations = load_data_with_annotations(directory)
# Display images with annotations
def display_images_with_annotations(images, annotations):
num_images = len(images)
for i in range(num_images):
original_img = images[i]
plt.figure(figsize=(10, 10))
# Display the original image with annotations
plt.subplot(1, 1, 1)
if annotations[i]:
for item in annotations[i]:
label = item['label']
x = int(item['coordinates']['x'])
y = int(item['coordinates']['y'])
width = int(item['coordinates']['width'])
height = int(item['coordinates']['height'])
# Debugging: Print the coordinates and label
print(f"Image {i+1} - Label: {label}, Coordinates: (x={x}, y={y}, width={width}, height={height})")
cv2.rectangle(original_img, (x, y), (x + width, y + height), (0, 255, 0), 2)
cv2.putText(original_img, label, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
plt.imshow(cv2.cvtColor(original_img, cv2.COLOR_BGR2RGB))
plt.title(f"Annotated Image {i+1}")
plt.axis('off')
plt.show()
display_images_with_annotations(images, annotations)
And somewhere in my code the annotation is getting scewed by about 40 pixels in the X and Y directions. Any tips to try greatly appreciated. This snip screenshot below is being displayed in IPython notebook cell with opencv.