Newer
Older
SmTIAS-Evaluation / src / io / loader.py
"""PNG 画像の読み込みと ROI 抽出モジュール."""

from pathlib import Path

import cv2
import numpy


def load_image(path: str) -> numpy.ndarray:
    """PNG 画像を読み込み RGB 配列として返す.

    OpenCV は BGR で読み込むため RGB に変換する.

    Args:
        path: 画像ファイルのパス.

    Returns:
        RGB 画像の NumPy 配列(H x W x 3, uint8).

    Raises:
        FileNotFoundError: 指定されたパスに画像ファイルが存在しない場合.
        ValueError: OpenCV が画像を読み込めなかった場合(形式が不正等).
    """
    if not Path(path).exists():
        raise FileNotFoundError(f"画像ファイルが見つかりません: {path}")

    bgr = cv2.imread(str(path))
    if bgr is None:
        raise ValueError(
            f"画像の読み込みに失敗しました(形式が不正の可能性があります): {path}"
        )

    # BGR → RGB 変換
    rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)
    return rgb


def extract_roi(
    image: numpy.ndarray,
    x: int,
    y: int,
    width: int,
    height: int,
) -> numpy.ndarray:
    """画像から矩形 ROI(関心領域)を切り出す.

    Args:
        image: 入力画像の NumPy 配列(H x W x 3).
        x: ROI 左上隅の X 座標(列方向,ピクセル).
        y: ROI 左上隅の Y 座標(行方向,ピクセル).
        width: ROI の幅(ピクセル).
        height: ROI の高さ(ピクセル).

    Returns:
        切り出した ROI の NumPy 配列(height x width x 3, uint8).

    Raises:
        ValueError: ROI が画像の範囲外に出る場合.
    """
    img_h, img_w = image.shape[:2]

    if x < 0 or y < 0 or width <= 0 or height <= 0:
        raise ValueError(
            f"ROI のパラメータが不正です: x={x}, y={y}, width={width}, height={height}"
        )

    if x + width > img_w or y + height > img_h:
        raise ValueError(
            f"ROI が画像範囲外に出ています: "
            f"ROI=({x}, {y}, {width}, {height}), 画像サイズ=({img_w}, {img_h})"
        )

    return image[y : y + height, x : x + width]