Source code for src.ctc.lightfield_preprocessing

"""
Author: Ismael Seidel (ismael.seidel@ufsc.br)
Affiliation: Embedded Computing Lab (ECL), Federal University of Santa Catarina (UFSC)

Description:
    This module defines the LightfieldPreprocess class, which provides static methods for pre-processing
    Light Field data in different formats (e.g., PPM, PNG). The pre-processing includes tasks such as
    reordering views, resizing, and creating symbolic links for efficient data handling.
"""

import os
from pathlib import Path

from lfc_toolkit.src.configuration.configuration_reader import \
    ConfigurationReader
from lfc_toolkit.src.ctc.lightfield_factory import LightFieldFactory
from lfc_toolkit.src.data_handlers.encoding_orders import get_serpentine_scan_list
from lfc_toolkit.src.data_handlers.formatters import (
    get_sequential_view_name_with_leading_zeros,
    get_view_name_with_leading_zeros)
from lfc_toolkit.src.data_handlers.lightfield import (
    RAW_RGB_PNG_LightField_Data, RAW_RGB_PPM_LightField_Data,
    RAWLightFieldData)


[docs] class LightfieldPreprocess: """Class for pre-processing Light Field data in various formats."""
[docs] @staticmethod def get(configuration: ConfigurationReader, lightfield: RAWLightFieldData): """Pre-processes the given Light Field data based on its type. :param configuration: ConfigurationReader instance containing Light Field configurations :type configuration: ConfigurationReader :param lightfield: Light Field data to be pre-processed :type lightfield: RAWLightFieldData :return: Pre-processed Light Field data :rtype: RAWLightFieldData """ print(f"Pre-processing lightfield {lightfield.name}") if isinstance(lightfield, RAW_RGB_PPM_LightField_Data): return LightfieldPreprocess.get_ppm(configuration=configuration, lightfield=lightfield) if isinstance(lightfield, RAW_RGB_PNG_LightField_Data): return LightfieldPreprocess.get_png(configuration=configuration, lightfield=lightfield) raise Exception("Invalid state of LightfieldPreprocess get method...")
[docs] @staticmethod def get_ppm(configuration: ConfigurationReader, lightfield: RAW_RGB_PPM_LightField_Data): """Pre-processes PPM Light Field data by reordering views and creating symbolic links. :param configuration: ConfigurationReader instance containing Light Field configurations :type configuration: ConfigurationReader :param lightfield: PPM Light Field data to be pre-processed :type lightfield: RAW_RGB_PPM_LightField_Data :return: Pre-processed PPM Light Field data :rtype: RAW_RGB_PPM_LightField_Data """ print(f"Pre-processing PPM lightfield {lightfield.name}") lf_encoding_configuration = configuration.lightfield_configurations[lightfield.name]["encode-size"] scan_list_source = get_serpentine_scan_list( n_views_width=lightfield.n_views_width, n_views_height=lightfield.n_views_height, initial_width=lightfield.initial_width, initial_height=lightfield.initial_height, step_width=lightfield.step_width, step_height=lightfield.step_height, ) scan_list_destination = get_serpentine_scan_list( n_views_width=lf_encoding_configuration["number-of-columns"], n_views_height=lf_encoding_configuration["number-of-rows"] ) assert len(scan_list_source) == len(scan_list_destination) destination_path = Path(configuration["raw_paths"]["ppm"]) / lightfield.name destination_path.mkdir(parents=True, exist_ok=True) for source, destination in zip(scan_list_source, scan_list_destination): source_name_ppm = Path(lightfield.raw_path) / f"{get_view_name_with_leading_zeros(source[0], source[1])}.ppm" source_name_pgm = Path(lightfield.raw_path) / f"{get_view_name_with_leading_zeros(source[0], source[1])}.pgm" destination_name_ppm = destination_path / f"{get_view_name_with_leading_zeros(destination[0], destination[1])}.ppm" destination_name_pgm = destination_path / f"{get_view_name_with_leading_zeros(destination[0], destination[1])}.pgm" if os.path.islink(destination_name_ppm): os.unlink(destination_name_ppm) if os.path.islink(destination_name_pgm): os.unlink(destination_name_pgm) os.symlink(src=source_name_ppm, dst=destination_name_ppm) if source_name_pgm.exists(): os.symlink(src=source_name_pgm, dst=destination_name_pgm) return LightFieldFactory.get_raw_lightfield(configuration=configuration, lightfield_name=lightfield.name, raw_type="ppm")
[docs] @staticmethod def get_png(configuration: ConfigurationReader, lightfield: RAW_RGB_PNG_LightField_Data): """Pre-processes PNG Light Field data by resizing and creating symbolic links. :param configuration: ConfigurationReader instance containing Light Field configurations :type configuration: ConfigurationReader :param lightfield: PNG Light Field data to be pre-processed :type lightfield: RAW_RGB_PNG_LightField_Data :return: Pre-processed PNG Light Field data :rtype: RAW_RGB_PNG_LightField_Data """ print(f"Pre-processing lightfield {lightfield.name}") lf_encoding_configuration = configuration.lightfield_configurations[lightfield.name]["encode-size"] resizing_step_w = configuration.lightfield_configurations[lightfield.name]["pre-processing"]["resize"].get("step-width", 1) resizing_step_h = configuration.lightfield_configurations[lightfield.name]["pre-processing"]["resize"].get("step-height", 1) naming = configuration.lightfield_configurations[lightfield.name]["pre-processing"].get("naming", dict()) name_prefix = naming.get("prefix", "") leading_zeros = naming.get("leading-zeros", 5) scan_order = naming.get("scan-order", "raster") # right_to_left scan_function_name = f"get_{scan_order}_scan_list" scan_function = globals()[scan_function_name] scan_list_destination = scan_function( n_views_width=lf_encoding_configuration["number-of-columns"], n_views_height=lf_encoding_configuration["number-of-rows"] ) destination_path = Path(configuration["raw_paths"]["png-preprocessed"]) / lightfield.name destination_path.mkdir(parents=True, exist_ok=True) start = 0 source = start - resizing_step_w destination_old = scan_list_destination[0][1] for destination in scan_list_destination: if destination_old == destination[1]: source += resizing_step_w else: source += resizing_step_h source_name_png = ( Path(lightfield.raw_path) / f"{name_prefix}{get_sequential_view_name_with_leading_zeros(source, leading_zeros=leading_zeros)}.png" ) destination_name_png = destination_path / f"{get_view_name_with_leading_zeros(destination[0], destination[1])}.png" print(f"{source_name_png} -> {destination_name_png}") if os.path.islink(destination_name_png): os.unlink(destination_name_png) os.symlink(src=source_name_png, dst=destination_name_png) destination_old = destination[1] return LightFieldFactory.get_raw_lightfield( configuration=configuration, lightfield_name=lightfield.name, raw_type="png", raw_path=Path(configuration["raw_paths"]["png-preprocessed"]), )