Read an image file (EXR or standard) as float32 RGB [0, 1]. Args: fpath: Absolute path to image file. gamma_correct_exr: If True, apply piecewise sRGB transfer function to EXR data (converts linear → sRGB for models expecting sRGB). Returns: float32 arra
(fpath: str, gamma_correct_exr: bool = False)
| 33 | |
| 34 | |
| 35 | def read_image_frame(fpath: str, gamma_correct_exr: bool = False) -> np.ndarray | None: |
| 36 | """Read an image file (EXR or standard) as float32 RGB [0, 1]. |
| 37 | |
| 38 | Args: |
| 39 | fpath: Absolute path to image file. |
| 40 | gamma_correct_exr: If True, apply piecewise sRGB transfer function |
| 41 | to EXR data (converts linear → sRGB for models expecting sRGB). |
| 42 | |
| 43 | Returns: |
| 44 | float32 array [H, W, 3] in RGB order, or None if read fails. |
| 45 | """ |
| 46 | is_exr = fpath.lower().endswith(".exr") |
| 47 | |
| 48 | if is_exr: |
| 49 | img = cv2.imread(fpath, cv2.IMREAD_UNCHANGED) |
| 50 | if img is None: |
| 51 | logger.warning("Could not read frame: %s", fpath) |
| 52 | return None |
| 53 | # Strip alpha channel from BGRA EXR |
| 54 | if img.ndim == 3 and img.shape[2] == 4: |
| 55 | img = img[:, :, :3] |
| 56 | img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) |
| 57 | result = np.maximum(img_rgb, 0.0).astype(np.float32) |
| 58 | if gamma_correct_exr: |
| 59 | result = linear_to_srgb(result).astype(np.float32) |
| 60 | return result |
| 61 | else: |
| 62 | img = cv2.imread(fpath) |
| 63 | if img is None: |
| 64 | logger.warning("Could not read frame: %s", fpath) |
| 65 | return None |
| 66 | img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) |
| 67 | return img_rgb.astype(np.float32) / 255.0 |
| 68 | |
| 69 | |
| 70 | def read_video_frame_at( |