Codice sorgente per disturbs.geometric

from typing import Union

import cv2
from networkx.algorithms.isolate import is_isolate

"""
Modulo per ruotare un'immagine sfruttando openCV2.
"""


[documenti] def rotate_image_and_label(image: cv2.typing.MatLike, labels: Union[list[str], str], angle: float) -> ( cv2.typing.MatLike, Union[list[str], str]): """ Questo metodo permette di ruotare l'immagine e la rispettiva label. La label deve essere nei seguenti formati (class x_1 y_1 x_2 y_2 ... x_n y_n) oppure (class centro_x centro_y height width). Eccetto class ciascun valore presente nella label deve essere normalizzato nell'intervallo [0, 1]. In base al formato della label verrà chiamato il metodo corretto. Args: image: l'immagine da ruotare. labels: la/le label da ruotare. angle: l'angolo di rotazione dell'immagine. Returns: l'immagine e la label ruotate. """ parts = labels[0].strip().split() coords = list(map(float, parts[1:])) if len(coords) == 4: return __rotate_image_and_label_bb(image, labels, angle) else: return __rotate_image_and_label_poly(image, labels, angle)
def __rotate_image_and_label_bb(image: cv2.typing.MatLike, labels: Union[list[str], str], angle: float) -> ( cv2.typing.MatLike, Union[list[str], str]): """ Questo metodo permette di ruotare le immagini che hanno una label quadrata o rettangolare, di conseguenza il formato della label sarà: (class centro_x centro_y height width). Parameters: image: l'immagine da ruotare. labels: la/le label da ruotare angle: l'angolo di rotazione. Returns: l'immagine e la label ruotate. """ (h, w) = image.shape[:2] center = (w // 2, h // 2) rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0) # Matrice di rotazione rotated_image = cv2.warpAffine(image, rotation_matrix, (w, h)) rotated_labels = [] for label in labels: parts = label.strip().split() if not parts: continue class_id = parts[0] coords = list(map(float, parts[1:])) x_n, y_n, w_n, h_n = coords x = x_n * w y = y_n * h x_new_pixel = rotation_matrix[0, 0] * x + rotation_matrix[0, 1] * y + rotation_matrix[0, 2] y_new_pixel = rotation_matrix[1, 0] * x + rotation_matrix[1, 1] * y + rotation_matrix[1, 2] x_new = x_new_pixel / w y_new = y_new_pixel / h rotated_label = [class_id] + list(map(str, [x_new, y_new, w_n, h_n])) rotated_labels.append(' '.join(rotated_label)) return rotated_image, rotated_labels def __rotate_image_and_label_poly(image: cv2.typing.MatLike, labels: Union[list[str], str], angle: float) -> ( cv2.typing.MatLike, Union[list[str], str]): """ Questo metodo permette di ruotare le immagini che hanno una label quadrata o rettangolare, di conseguenza il formato della label sarà: (class x_1 y_1 x_2 y_2 ... x_n y_n). Parameters: image: l'immagine da ruotare. labels: la/le label da ruotare angle: l'angolo di rotazione. Returns: l'immagine e la label ruotate. """ # cerco parametri rotazione (h, w) = image.shape[:2] center = (w // 2, h // 2) rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0) # Matrice di rotazione # applico all'immagine la matrice rotated_image = cv2.warpAffine(image, rotation_matrix, (w, h)) # ruoto le possibili label rotated_labels = [] for label in labels: parts = label.strip().split() if not parts: continue class_id = parts[0] coords = list(map(float, parts[1:])) x_coords = [coords[i] * w for i in range(0, len(coords), 2)] y_coords = [coords[i + 1] * h for i in range(0, len(coords), 2)] # applico rotazione a ogni coppia di coordinate rotated_coords = [] for x, y in zip(x_coords, y_coords): # applico matrice di rotazione alle coordinate della label in modo da ottenere la stessa rotazione # dell'immagine x_new_pixel = rotation_matrix[0, 0] * x + rotation_matrix[0, 1] * y + rotation_matrix[0, 2] y_new_pixel = rotation_matrix[1, 0] * x + rotation_matrix[1, 1] * y + rotation_matrix[1, 2] # rinormalizzo i punti x_new = x_new_pixel / w y_new = y_new_pixel / h rotated_coords.extend([x_new, y_new]) rotated_label = [class_id] + list(map(str, rotated_coords)) rotated_labels.append(' '.join(rotated_label)) return rotated_image, rotated_labels