AarohiSingla / YOLOv7-POSE-on-Custom-Dataset

Keypoint detection on custom dataset. We have 1 class - Glass and it have 4 keypoints. Ithis this tutorial we will train our yolov7 model to detect these 4 custom keypoints
17 stars 10 forks source link

format conversion.py not found #1

Open aluds123 opened 1 year ago

aluds123 commented 1 year ago

Hi Aarohi @AarohiSingla : Thank you for your video about . Can you give me format conversion.py, because the link "https://github.com/WongKinYiu/yolov7/issues/1103" can't find the code, thank you.

AarohiSingla commented 1 year ago

import os import json

Path to the folder containing images

img_folder_path = 'path/to/images'

Path to the annotation file

ann_file_path = 'path/to/json'

Load the annotations from the JSON file

with open(ann_file_path, 'r') as f: annotations = json.load(f)

Process each image in the folder

for image in annotations['images']: image_id = image['id'] image_filename = image['file_name'] image_width = image['width'] image_height = image['height']

# Get the annotations for this image
image_annotations = [ann for ann in annotations['annotations'] if ann['image_id'] == image_id]

keypoint_values = []
bbox_values = []
for annotation in image_annotations:
    keypoints = annotation['keypoints']
    bbox = annotation['bbox']
    bbox = [float(val) for val in bbox]  # convert bbox values to float
    bbox_values.extend(bbox)

    for i in range(0, len(keypoints), 3):
        x = keypoints[i]
        y = keypoints[i+1]
        visibility = keypoints[i+2]        
    keypoint_values.extend([x, y, visibility])

# Save the normalized keypoints and bbox to a text file with the same name as the image
txt_filename = os.path.splitext(image_filename)[0] + '.txt'
with open(os.path.join(img_folder_path, txt_filename), 'w') as f:
    bbox_str = ' '.join([str(val) for val in bbox_values])
    keypoint_str = ' '.join([str(val) for val in keypoint_values])
    f.write('0 ' + bbox_str + ' ' + keypoint_str)
vaibhav030798 commented 1 year ago

i'm also facing same problem

aluds123 commented 1 year ago

@AarohiSingla The code seems doesn't do normalized to YOLO's format. Should I both devide image_width and devide image_height at last?

vaibhav030798 commented 1 year ago

@AarohiSingla after converting yolo format

Optimizer groups: 155 .bias, 155 conv.weight, 155 other train: Scanning 'final_dataset/labels/train.cache' images and labels... 15 found, 0 missing, 0 empty, 15 corrupted: 100%|██████████████████████████████████████████████████████████████████| 15/15 [00:00<?, ?it/s] Traceback (most recent call last): File "/home/ubuntu-ogmen/coco-annotator/datasets/YOLOv7-POSE-on-Custom-Dataset/train.py", line 568, in train(hyp, opt, device, tb_writer) File "/home/ubuntu-ogmen/coco-annotator/datasets/YOLOv7-POSE-on-Custom-Dataset/train.py", line 206, in train dataloader, dataset = create_dataloader(train_path, imgsz, batch_size, gs, opt, File "/home/ubuntu-ogmen/coco-annotator/datasets/YOLOv7-POSE-on-Custom-Dataset/utils/datasets.py", line 65, in create_dataloader dataset = LoadImagesAndLabels(path, imgsz, batch_size, File "/home/ubuntu-ogmen/coco-annotator/datasets/YOLOv7-POSE-on-Custom-Dataset/utils/datasets.py", line 423, in init labels, shapes, self.segments = zip(*cache.values()) ValueError: not enough values to unpack (expected 3, got 0)

aluds123 commented 1 year ago

@AarohiSingla @vaibhav030798 If the object has 2 keypoints, then the label format will be like "class_id, box_center_x, box_center_y, with, height, keypoint_1_x, keypoint_1_y, 2, keypoint_2_x, keypoint_2_y, 2" ?
(And x, y, center_x, center_y will devide the image' width or the image' height just like YOLO's format, right?

Is the above statement correct?

aluds123 commented 1 year ago

@AarohiSingla after converting yolo format

Optimizer groups: 155 .bias, 155 conv.weight, 155 other train: Scanning 'final_dataset/labels/train.cache' images and labels... 15 found, 0 missing, 0 empty, 15 corrupted: 100%|██████████████████████████████████████████████████████████████████| 15/15 [00:00<?, ?it/s] Traceback (most recent call last): File "/home/ubuntu-ogmen/coco-annotator/datasets/YOLOv7-POSE-on-Custom-Dataset/train.py", line 568, in train(hyp, opt, device, tb_writer) File "/home/ubuntu-ogmen/coco-annotator/datasets/YOLOv7-POSE-on-Custom-Dataset/train.py", line 206, in train dataloader, dataset = create_dataloader(train_path, imgsz, batch_size, gs, opt, File "/home/ubuntu-ogmen/coco-annotator/datasets/YOLOv7-POSE-on-Custom-Dataset/utils/datasets.py", line 65, in create_dataloader dataset = LoadImagesAndLabels(path, imgsz, batch_size, File "/home/ubuntu-ogmen/coco-annotator/datasets/YOLOv7-POSE-on-Custom-Dataset/utils/datasets.py", line 423, in init labels, shapes, self.segments = zip(*cache.values()) ValueError: not enough values to unpack (expected 3, got 0)

@vaibhav030798 @AarohiSingla Do you solve it?

AarohiSingla commented 1 year ago

Normalize x and y:

    # normalize x and y coordinates of keypoints
    normalized_keypoints = []
    for i in range(0, len(keypoints), 3):
        x = keypoints[i]
        y = keypoints[i+1]
        visibility = keypoints[i+2]
        normalized_x = round(x / image_width, 6)  # normalize x coordinate
        normalized_y = round(y / image_height, 6)  # normalize y coordinate
        normalized_keypoints.extend([normalized_x, normalized_y, visibility])
AarohiSingla commented 1 year ago

cted 3, got 0)

# normalize x and y coordinates of keypoints
normalized_keypoints = []
for i in range(0, len(keypoints), 3):
    x = keypoints[i]
    y = keypoints[i+1]
    visibility = keypoints[i+2]
    normalized_x = round(x / image_width, 6)  # normalize x coordinate
    normalized_y = round(y / image_height, 6)  # normalize y coordinate
    normalized_keypoints.extend([normalized_x, normalized_y, visibility])
vaibhav030798 commented 1 year ago

@AarohiSingla

thankyou for sharing information but after running this scripts my txt file is blank can you share whole conversion.py scripts ?

saim212 commented 1 year ago
import json
import os

def convert_coco_to_yolo(coco_json_path, output_dir):
    # Load COCO JSON file
    with open(coco_json_path, 'r') as f:
        coco_data = json.load(f)

    # Create output directory if it doesn't exist
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # Iterate over each image in the dataset
    for image_data in coco_data['images']:
        image_id = image_data['id']
        image_name = image_data['file_name']
        image_width = image_data['width']
        image_height = image_data['height']
        keypoints_list = []

        # Find annotations for the current image
        for annotation in coco_data['annotations']:
            if annotation['image_id'] == image_id:
                keypoints = annotation['keypoints']
                keypoints_list.append(keypoints)

        # Skip images without annotations
        if not keypoints_list:
            continue

        # Create YOLO annotation file
        annotation_file_name = os.path.splitext(image_name)[0] + '.txt'
        annotation_file_path = os.path.join(output_dir, annotation_file_name)
        with open(annotation_file_path, 'w') as f:
            for keypoints in keypoints_list:
                # Find bounding box coordinates
                x_min = min(keypoints[0::3])
                y_min = min(keypoints[1::3])
                x_max = max(keypoints[0::3])
                y_max = max(keypoints[1::3])

                # Normalize bounding box coordinates to range [0, 1]
                x_center = (x_min + x_max) / (2 * image_width)
                y_center = (y_min + y_max) / (2 * image_height)
                width = (x_max - x_min) / image_width
                height = (y_max - y_min) / image_height

                # Write the annotation to the YOLO file
                f.write(f'{0} {round(x_center,6)} {round(y_center,6)} {round(width,6)} {round(height, 6)} ')

                # Append normalized keypoints to the annotation
                for i in range(0, len(keypoints), 3):
                    x = round(keypoints[i] / image_width, 6)
                    y = round(keypoints[i + 1] / image_height, 6)
                    v = round(keypoints[i + 2], 6)
                    f.write(f'{x} {y} {v} ')
                f.write('\n')

    print('Conversion complete.')

# Example usage
coco_json_path = 'path of coco file'
output_dir = 'output dir path'
convert_coco_to_yolo(coco_json_path, output_dir)