Fixel Algorithms

yoloWRKSHP box formats#

Notebook by:

Revision History#

Version

Date

User

Content / Changes

1.0.000

16/06/2024

Royi Avital

First version

Open In Colab

# Import Packages

# General Tools
import numpy as np
import scipy as sp
import pandas as pd

# Machine Learning


# Deep Learning


# Miscellaneous
from enum import auto, Enum, unique
import math
import os
from platform import python_version
import random

import time

# Typing
from typing import Callable, Dict, Generator, List, Optional, Self, Set, Tuple, Union

# Visualization
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns

# Jupyter
from IPython import get_ipython
from IPython.display import HTML, Image
from IPython.display import display
from ipywidgets import Dropdown, FloatSlider, interact, IntSlider, Layout, SelectionSlider
from ipywidgets import interact

Notations#

  • (?) Question to answer interactively.

  • (!) Simple task to add code for the notebook.

  • (@) Optional / Extra self practice.

  • (#) Note / Useful resource / Food for thought.

Code Notations:

someVar    = 2; #<! Notation for a variable
vVector    = np.random.rand(4) #<! Notation for 1D array
mMatrix    = np.random.rand(4, 3) #<! Notation for 2D array
tTensor    = np.random.rand(4, 3, 2, 3) #<! Notation for nD array (Tensor)
tuTuple    = (1, 2, 3) #<! Notation for a tuple
lList      = [1, 2, 3] #<! Notation for a list
dDict      = {1: 3, 2: 2, 3: 1} #<! Notation for a dictionary
oObj       = MyClass() #<! Notation for an object
dfData     = pd.DataFrame() #<! Notation for a data frame
dsData     = pd.Series() #<! Notation for a series
hObj       = plt.Axes() #<! Notation for an object / handler / function handler

Code Exercise#

  • Single line fill

vallToFill = ???
  • Multi Line to Fill (At least one)

# You need to start writing
????
  • Section to Fill

#===========================Fill This===========================#
# 1. Explanation about what to do.
# !! Remarks to follow / take under consideration.
mX = ???

???
#===============================================================#
# Configuration
# %matplotlib inline

seedNum = 512
np.random.seed(seedNum)
random.seed(seedNum)

# Matplotlib default color palette
lMatPltLibclr = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf']
# sns.set_theme() #>! Apply SeaBorn theme

runInGoogleColab = 'google.colab' in str(get_ipython())
# Constants

FIG_SIZE_DEF    = (8, 8)
ELM_SIZE_DEF    = 50
CLASS_COLOR     = ('b', 'r')
EDGE_COLOR      = 'k'
MARKER_SIZE_DEF = 10
LINE_WIDTH_DEF  = 2
# Download Auxiliary Modules for Google Colab
# Courses Packages
# General Auxiliary Functions

@unique
class BBoxFormat(Enum):
    # Bounding Box Format, See https://albumentations.ai/docs/getting_started/bounding_boxes_augmentation
    COCO        = auto()
    PASCAL_VOC  = auto()
    YOLO        = auto()

Box Standards Conversion#

There are 3

  • COCO Style: [x, y, width, height].

  • PASCAL VOC Style: [x_min, y_min, x_max, y_max].

  • YOLO Style: [x_center, y_center, width, height].

  • (#) The YOLO style is normalized to the image dimensions.

This notebook implements the conversion between all standards.

# Parameters

# Data

Implementation#

The data is synthetic data.
Each image includes Ellipses where its color is the class (R, G, B) and the bounding rectangle.

  • (#) The label, per object, is a vector of 5: [Class, xCenter, yCenter, boxWidth, boxHeight].

  • (#) The label is in YOLO format, hence it is normalized to [0, 1].

# Box Standard Conversion

def ConvertBBoxFormat( vBox: np.ndarray, tuImgSize: Tuple[int, int], boxFormatIn: BBoxFormat, boxFormatOut: BBoxFormat ) -> np.ndarray:
    # tuImgSize = (numRows, numCols) <=> (imgHeight, imgWidth)

    imgHeight, imgWidth = tuImgSize
    
    if boxFormatIn == boxFormatOut:
        return vBox

    # Convert input box to PASCAL VOC format as an intermediate format
    if boxFormatIn == BBoxFormat.COCO:
        x_min = vBox[0]
        y_min = vBox[1]
        x_max = vBox[0] + vBox[2]
        y_max = vBox[1] + vBox[3]
    elif boxFormatIn == BBoxFormat.YOLO:
        x_center = vBox[0] * imgWidth
        y_center = vBox[1] * imgHeight
        width = vBox[2] * imgWidth
        height = vBox[3] * imgHeight
        x_min = x_center - width / 2
        y_min = y_center - height / 2
        x_max = x_center + width / 2
        y_max = y_center + height / 2
    elif boxFormatIn == BBoxFormat.PASCAL_VOC:
        x_min = vBox[0]
        y_min = vBox[1]
        x_max = vBox[2]
        y_max = vBox[3]

    # Convert from PASCAL VOC format to the output format
    if boxFormatOut == BBoxFormat.COCO:
        vB = np.array([x_min, y_min, x_max - x_min, y_max - y_min])
    elif boxFormatOut == BBoxFormat.YOLO:
        x_center = (x_min + x_max) / 2 / imgWidth
        y_center = (y_min + y_max) / 2 / imgHeight
        width = (x_max - x_min) / imgWidth
        height = (y_max - y_min) / imgHeight
        vB = np.array([x_center, y_center, width, height])
    elif boxFormatOut == BBoxFormat.PASCAL_VOC:
        vB = np.array([x_min, y_min, x_max, y_max])
    
    
    return vB
# Test

vBox_yolo = np.array([0.5, 0.5, 0.2, 0.2])  # YOLO format (normalized)
tuImgSize = (100, 100)  # Image size (height, width)
boxFormatIn = BBoxFormat.YOLO
boxFormatOut = BBoxFormat.COCO

converted_box = ConvertBBoxFormat(vBox_yolo, tuImgSize, boxFormatIn, boxFormatOut)
print("Converted Box:", converted_box)
Converted Box: [40. 40. 20. 20.]