"""
Author: Ismael Seidel (ismael.seidel@ufsc.br)
Affiliation: Embedded Computing Lab (ECL), Federal University of Santa Catarina (UFSC)
Description:
This module contains the implementation of PGX->YUV conversion.
"""
from pathlib import Path
from typing import Union
import yuvio
from lfc_toolkit.src.data_handlers.encoding_orders import (
ScanFunctionType,
get_serpentine_scan_list,
)
from lfc_toolkit.src.data_handlers.formatters import get_view_name_with_leading_zeros
from lfc_toolkit.src.data_handlers.lightfield import (
LightField,
RAW_BT709_FR_YUV444p10le_LightField_Data,
RAWLightFieldData,
)
from lfc_toolkit.src.file.pgx_handler import PGXHandler
[docs]
def generate_yuv_from_pgx(
raw_light_field_data: RAWLightFieldData,
yuv_path: Union[str, Path],
scan_order: ScanFunctionType = get_serpentine_scan_list,
remove_after_using: bool = False,
) -> RAW_BT709_FR_YUV444p10le_LightField_Data:
"""
Get RAW YUV light field object from RAW PGX light field data.
:param raw_light_field_data: RAW PGX light field to be converted
:type raw_light_field_data: RAWLightFieldData
:param yuv_path: Path to save the YUV files
:type yuv_path: Union[str, Path]
:param scan_order: Function defining the scan order
:type scan_order: ScanFunctionType
:param remove_after_using: Whether to remove intermediate files
:type remove_after_using: bool
:return: Converted YUV light field data
:rtype: RAW_BT709_FR_YUV444p10le_LightField_Data
"""
hand = PGXHandler()
scan_list = scan_order(
raw_light_field_data.n_views_width,
raw_light_field_data.n_views_height,
0,
0,
1,
1,
)
# always in this format 0,0,1,1 as it is expected by the JPLM
assert raw_light_field_data.pix_fmt == "PGX"
# probably not necessary...
assert raw_light_field_data.colour_space == "BT.709 Full Range"
output_raw_lf = RAW_BT709_FR_YUV444p10le_LightField_Data(
lightfield=raw_light_field_data.copy(),
yuv_path=yuv_path,
bpp_for_naming=raw_light_field_data.bpp_for_naming,
remove_after_using=remove_after_using,
)
if Path(output_raw_lf.raw_path).is_file():
print("File exists")
return output_raw_lf
# ensuring the yuv_path exists
output_raw_lf.yuv_path.mkdir(parents=True, exist_ok=True)
pix_fmt = "yuv444p10le"
writer = yuvio.get_writer(
output_raw_lf.raw_path,
raw_light_field_data.view_width,
raw_light_field_data.view_height,
pix_fmt,
)
for x, y in scan_list:
view_filename = f"{get_view_name_with_leading_zeros(x, y)}.pgx"
y = hand.read(f"{raw_light_field_data.raw_path}/0/{view_filename}")
u = hand.read(f"{raw_light_field_data.raw_path}/1/{view_filename}")
v = hand.read(f"{raw_light_field_data.raw_path}/2/{view_filename}")
frame_444 = yuvio.frame((y, u, v), pix_fmt)
writer.write(frame_444)
return output_raw_lf
[docs]
def main():
import argparse
# 1. Create the ArgumentParser object with a description
parser = argparse.ArgumentParser(description="Convert a single PGX LF to YUV.")
# 2. Add a positional argument (required input, no dashes)
parser.add_argument(
"--name", "-n", required=True, type=str, help="The name of the light field."
)
parser.add_argument("--n-views-height", "-t", required=True, type=int, help="T")
parser.add_argument("--n-views-width", "-s", required=True, type=int, help="S")
parser.add_argument("--view-height", "-v", required=True, type=int, help="V")
parser.add_argument("--view-width", "-u", required=True, type=int, help="U")
parser.add_argument(
"--input_path", "-i", required=True, type=str, help="Input path"
)
parser.add_argument(
"--output_path", "-o", required=True, type=str, help="Output path"
)
# 3. Parse the arguments from the command line
args = parser.parse_args()
lf = RAWLightFieldData(
lightfield=LightField(
name=args.name,
view_width=args.view_width,
view_height=args.view_height,
n_views_width=args.n_views_width,
n_views_height=args.n_views_height,
),
raw_path=args.input_path,
type="PGX",
pix_fmt="PGX",
)
print(lf.type)
generate_yuv_from_pgx(
raw_light_field_data=lf, yuv_path=args.output_path, remove_after_using=False
)
if __name__ == "__main__":
main()