Source code for src.quality.quality_tool_wrapper

import abc
import os
from pathlib import Path
from typing import Optional, Tuple, Union

from lfc_toolkit.src.converters.lightfield_converter import LightfieldConverter
from lfc_toolkit.src.data_handlers.lightfield import RAWLightFieldData


[docs] class QualityToolWrapper(abc.ABC): """Abstract base class for quality metric tool wrappers."""
[docs] def __init__(self, reports_path: Union[str, Path], required_format: str) -> None: """Initializes the quality tool wrapper with reports path and required format. :param reports_path: Path to store metric reports :type reports_path: Union[str, Path] :param required_format: Required lightfield format for the tool (e.g., "yuv") :type required_format: str :return: None :rtype: None """ self.__reports_path = reports_path os.makedirs(reports_path, exist_ok=True) self._required_format = required_format
@property def reports_path(self) -> Union[str, Path]: """Gets the path where quality reports are stored. :return: Reports path :rtype: Union[str, Path] """ return self.__reports_path def _ensure_compatible( self, original_lightfield: RAWLightFieldData, decoded_lightfield: RAWLightFieldData, ) -> None: """Ensures original and decoded light fields have compatible properties for metrics. :param original_lightfield: Original light field data :type original_lightfield: RAWLightFieldData :param decoded_lightfield: Decoded light field data :type decoded_lightfield: RAWLightFieldData :return: None :rtype: None """ assert original_lightfield.type == decoded_lightfield.type assert original_lightfield.name == decoded_lightfield.name assert original_lightfield.pix_fmt == decoded_lightfield.pix_fmt assert original_lightfield.colour_space == decoded_lightfield.colour_space assert original_lightfield.view_width == decoded_lightfield.view_width assert original_lightfield.view_height == decoded_lightfield.view_height assert original_lightfield.n_views_width == decoded_lightfield.n_views_width assert original_lightfield.n_views_height == decoded_lightfield.n_views_height def _get_raw_lfs_in_the_required_format( self, destination_type: str, original_lightfield: RAWLightFieldData, decoded_lightfield: RAWLightFieldData, remove_after_using: bool = False ) -> Tuple[RAWLightFieldData, RAWLightFieldData]: """Converts original and decoded light fields to the required format for metrics. :param destination_type: Target format type (e.g., "yuv", "pgx") :type destination_type: str :param original_lightfield: Original light field data :type original_lightfield: RAWLightFieldData :param decoded_lightfield: Decoded light field data :type decoded_lightfield: RAWLightFieldData :param remove_after_using: Whether to remove converted files after use, defaults to False :type remove_after_using: bool, optional :return: Tuple of (converted_original, converted_decoded) :rtype: Tuple[RAWLightFieldData, RAWLightFieldData] """ converted_original = original_lightfield converted_decoded = decoded_lightfield if original_lightfield.type.lower() != destination_type.lower(): print("converting original...", original_lightfield.type, destination_type) converted_original = LightfieldConverter.convert( source=original_lightfield, destination_type=destination_type, remove_after_using=remove_after_using ) print(original_lightfield.raw_path) if decoded_lightfield.type.lower() != destination_type.lower(): print("converting decoded...", decoded_lightfield.type, destination_type) converted_decoded = LightfieldConverter.convert( source=decoded_lightfield, destination_type=destination_type, remove_after_using=remove_after_using ) self._ensure_compatible(converted_original, converted_decoded) return ( converted_original, converted_decoded )
[docs] def get_metrics( self, original_lightfield: RAWLightFieldData, decoded_lightfield: RAWLightFieldData, remove_converted_lfs_after_using: bool = False ) -> Union[str, Path]: """Computes quality metrics between original and decoded light fields. :param original_lightfield: Original light field data :type original_lightfield: RAWLightFieldData :param decoded_lightfield: Decoded light field data :type decoded_lightfield: RAWLightFieldData :param remove_converted_lfs_after_using: Whether to remove converted files after use, defaults to False :type remove_converted_lfs_after_using: bool, optional :return: Path to the metrics report :rtype: Union[str, Path] """ ( converted_original, converted_decoded ) = self._get_raw_lfs_in_the_required_format( destination_type=self._required_format, original_lightfield=original_lightfield, decoded_lightfield=decoded_lightfield, remove_after_using=remove_converted_lfs_after_using ) report_path = self._call_metrics(converted_original, converted_decoded) return report_path
@abc.abstractmethod def _call_metrics( self, original_lightfield: RAWLightFieldData, decoded_lightfield: RAWLightFieldData, ) -> Union[str, Path]: """Computes metrics between original and decoded lightfields. Must be implemented by subclasses. :param original_lightfield: Original (reference) lightfield :type original_lightfield: RAWLightFieldData :param decoded_lightfield: Decoded lightfield to evaluate :type decoded_lightfield: RAWLightFieldData :return: Path to the metrics report file :rtype: Union[str, Path] """ pass