Module facetorch.datastruct

Classes

class Dimensions (height: int = 0, width: int = 0)
Expand source code
@dataclass
class Dimensions:
    """Data class for image dimensions.

    Attributes:
        height (int): Image height.
        width (int): Image width.
    """

    height: int = field(default=0)
    width: int = field(default=0)

Data class for image dimensions.

Attributes
-----=
height : int
Image height.
width : int
Image width.

Instance variables

var height : int
var width : int
class Location (x1: int = 0, x2: int = 0, y1: int = 0, y2: int = 0)
Expand source code
@dataclass
class Location:
    """Data class for face location.

    Attributes:
        x1 (int): x1 coordinate
        x2 (int): x2 coordinate
        y1 (int): y1 coordinate
        y2 (int): y2 coordinate
    """

    x1: int = field(default=0)
    x2: int = field(default=0)
    y1: int = field(default=0)
    y2: int = field(default=0)

    def form_square(self) -> None:
        """Form a square from the location.

        Returns:
            None
        """
        height = self.y2 - self.y1
        width = self.x2 - self.x1

        if height > width:
            diff = height - width
            low = diff // 2
            self.x1 -= low
            self.x2 += diff - low
        elif height < width:
            diff = width - height
            low = diff // 2
            self.y1 -= low
            self.y2 += diff - low

    def expand(self, amount: float) -> None:
        """Expand the location while keeping the center.

        Args:
            amount (float): Amount to expand the location by in multiples of the original size.


        Returns:
            None
        """
        if amount < 0:
            raise ValueError("amount must be greater than or equal to 0.")
        if amount != 0.0:
            width = self.x2 - self.x1
            height = self.y2 - self.y1
            expand_x = int(round(width * amount / 2))
            expand_y = int(round(height * amount / 2))
            self.x1 -= expand_x
            self.y1 -= expand_y
            self.x2 += expand_x
            self.y2 += expand_y

    def clamp(self, width: int, height: int) -> None:
        """Clamp coordinates to an image boundary."""
        self.x1 = max(0, min(int(self.x1), int(width)))
        self.x2 = max(self.x1, min(int(self.x2), int(width)))
        self.y1 = max(0, min(int(self.y1), int(height)))
        self.y2 = max(self.y1, min(int(self.y2), int(height)))

    def fit_square(self, width: int, height: int) -> None:
        """Fit the largest possible square around this location inside an image."""
        center_x = (self.x1 + self.x2) / 2.0
        center_y = (self.y1 + self.y2) / 2.0
        side = min(max(self.x2 - self.x1, self.y2 - self.y1), width, height)
        side = max(0, int(round(side)))

        x1 = int(round(center_x - side / 2.0))
        y1 = int(round(center_y - side / 2.0))
        x1 = min(max(0, x1), max(0, width - side))
        y1 = min(max(0, y1), max(0, height - side))
        self.x1, self.y1 = x1, y1
        self.x2, self.y2 = x1 + side, y1 + side

Data class for face location.

Attributes
-----=
x1 : int
x1 coordinate
x2 : int
x2 coordinate
y1 : int
y1 coordinate
y2 : int
y2 coordinate

Instance variables

var x1 : int
var x2 : int
var y1 : int
var y2 : int

Methods

def form_square(self) ‑> None
Expand source code
def form_square(self) -> None:
    """Form a square from the location.

    Returns:
        None
    """
    height = self.y2 - self.y1
    width = self.x2 - self.x1

    if height > width:
        diff = height - width
        low = diff // 2
        self.x1 -= low
        self.x2 += diff - low
    elif height < width:
        diff = width - height
        low = diff // 2
        self.y1 -= low
        self.y2 += diff - low

Form a square from the location.

Returns -----= None

def expand(self, amount: float) ‑> None
Expand source code
def expand(self, amount: float) -> None:
    """Expand the location while keeping the center.

    Args:
        amount (float): Amount to expand the location by in multiples of the original size.


    Returns:
        None
    """
    if amount < 0:
        raise ValueError("amount must be greater than or equal to 0.")
    if amount != 0.0:
        width = self.x2 - self.x1
        height = self.y2 - self.y1
        expand_x = int(round(width * amount / 2))
        expand_y = int(round(height * amount / 2))
        self.x1 -= expand_x
        self.y1 -= expand_y
        self.x2 += expand_x
        self.y2 += expand_y

Expand the location while keeping the center.

Args
-----=
amount : float
Amount to expand the location by in multiples of the original size.

Returns -----= None

def clamp(self, width: int, height: int) ‑> None
Expand source code
def clamp(self, width: int, height: int) -> None:
    """Clamp coordinates to an image boundary."""
    self.x1 = max(0, min(int(self.x1), int(width)))
    self.x2 = max(self.x1, min(int(self.x2), int(width)))
    self.y1 = max(0, min(int(self.y1), int(height)))
    self.y2 = max(self.y1, min(int(self.y2), int(height)))

Clamp coordinates to an image boundary.

def fit_square(self, width: int, height: int) ‑> None
Expand source code
def fit_square(self, width: int, height: int) -> None:
    """Fit the largest possible square around this location inside an image."""
    center_x = (self.x1 + self.x2) / 2.0
    center_y = (self.y1 + self.y2) / 2.0
    side = min(max(self.x2 - self.x1, self.y2 - self.y1), width, height)
    side = max(0, int(round(side)))

    x1 = int(round(center_x - side / 2.0))
    y1 = int(round(center_y - side / 2.0))
    x1 = min(max(0, x1), max(0, width - side))
    y1 = min(max(0, y1), max(0, height - side))
    self.x1, self.y1 = x1, y1
    self.x2, self.y2 = x1 + side, y1 + side

Fit the largest possible square around this location inside an image.

class Prediction (label: str = <factory>,
logits: torch.Tensor = <factory>,
other: Dict = <factory>)
Expand source code
@dataclass
class Prediction:
    """Data class for face prediction results and derivatives.

    Attributes:
        label (str): Label of the face given by predictor.
        logits (torch.Tensor): Output of the predictor model for the face.
        other (Dict): Any other predictions and derivatives for the face.
    """

    label: str = field(default_factory=str)
    logits: torch.Tensor = field(default_factory=torch.Tensor)
    other: Dict = field(default_factory=dict)

Data class for face prediction results and derivatives.

Attributes
-----=
label : str
Label of the face given by predictor.
logits : torch.Tensor
Output of the predictor model for the face.
other : Dict
Any other predictions and derivatives for the face.

Instance variables

var label : str
var logits : torch.Tensor
var other : Dict
class Detection (loc: torch.Tensor = <factory>,
conf: torch.Tensor = <factory>,
landmarks: torch.Tensor = <factory>,
boxes: torch.Tensor = <factory>,
dets: torch.Tensor = <factory>)
Expand source code
@dataclass
class Detection:
    """Data class for detector output.

    Attributes:
        loc (torch.Tensor): Locations of faces
        conf (torch.Tensor): Confidences of faces
        landmarks (torch.Tensor): Selected landmark coordinates in source-image space.
        boxes (torch.Tensor): Selected bounding boxes in source-image space.
        dets (torch.Tensor): Selected boxes and confidence scores.

    """

    loc: torch.Tensor = field(default_factory=torch.Tensor)
    conf: torch.Tensor = field(default_factory=torch.Tensor)
    landmarks: torch.Tensor = field(default_factory=torch.Tensor)
    boxes: torch.Tensor = field(default_factory=torch.Tensor)
    dets: torch.Tensor = field(default_factory=torch.Tensor)

Data class for detector output.

Attributes
-----=
loc : torch.Tensor
Locations of faces
conf : torch.Tensor
Confidences of faces
landmarks : torch.Tensor
Selected landmark coordinates in source-image space.
boxes : torch.Tensor
Selected bounding boxes in source-image space.
dets : torch.Tensor
Selected boxes and confidence scores.

Instance variables

var loc : torch.Tensor
var conf : torch.Tensor
var landmarks : torch.Tensor
var boxes : torch.Tensor
var dets : torch.Tensor
class Face (indx: int = <factory>,
loc: Location = <factory>,
dims: Dimensions = <factory>,
tensor: torch.Tensor = <factory>,
ratio: float = <factory>,
preds: Dict[str, Prediction] = <factory>)
Expand source code
@dataclass
class Face:
    """Data class for face attributes.

    Attributes:
        indx (int): Index of the face.
        loc (Location): Location of the face in the image.
        dims (Dimensions): Dimensions of the face (height, width).
        tensor (torch.Tensor): Face tensor.
        ratio (float): Ratio of the face area to the image area.
        preds (Dict[str, Prediction]): Predictions of the face given by predictor set.
    """

    indx: int = field(default_factory=int)
    loc: Location = field(default_factory=Location)
    dims: Dimensions = field(default_factory=Dimensions)
    tensor: torch.Tensor = field(default_factory=torch.Tensor)
    ratio: float = field(default_factory=float)
    preds: Dict[str, Prediction] = field(default_factory=dict)

Data class for face attributes.

Attributes
-----=
indx : int
Index of the face.
loc : Location
Location of the face in the image.
dims : Dimensions
Dimensions of the face (height, width).
tensor : torch.Tensor
Face tensor.
ratio : float
Ratio of the face area to the image area.
preds : Dict[str, Prediction]
Predictions of the face given by predictor set.

Instance variables

var indx : int
var locLocation
var dimsDimensions
var tensor : torch.Tensor
var ratio : float
var preds : Dict[str, Prediction]
class ImageData (path_input: str = <factory>,
path_output: str | None = <factory>,
img: torch.Tensor = <factory>,
tensor: torch.Tensor = <factory>,
dims: Dimensions = <factory>,
det: Detection = <factory>,
faces: List[Face] = <factory>,
version: str = <factory>,
warnings: List[str] = <factory>)
Expand source code
@dataclass
class ImageData:
    """The main data class used for passing data between the different facetorch modules.

    Attributes:
        path_input (str): Path to the input image.
        path_output (str): Path to the output image where the resulting image is saved.
        img (torch.Tensor): Original image tensor used for drawing purposes.
        tensor (torch.Tensor): Processed image tensor.
        dims (Dimensions): Dimensions of the image (height, width).
        det (Detection): Detection data given by the detector.
        faces (List[Face]): List of faces in the image.
        version (str): Version of the facetorch library.

    """

    path_input: str = field(default_factory=str)
    path_output: Optional[str] = field(default_factory=str)
    img: torch.Tensor = field(default_factory=torch.Tensor)
    tensor: torch.Tensor = field(default_factory=torch.Tensor)
    dims: Dimensions = field(default_factory=Dimensions)
    det: Detection = field(default_factory=Detection)
    faces: List[Face] = field(default_factory=list)
    version: str = field(default_factory=str)
    warnings: List[str] = field(default_factory=list)

    def add_preds(
        self,
        preds_list: List[Prediction],
        predictor_name: str,
        face_offset: int = 0,
    ) -> None:
        """Adds a list of predictions to the data object.

        Args:
            preds_list (List[Prediction]): List of predictions.
            predictor_name (str): Name of the predictor.
            face_offset (int): Offset of the face index where the predictions are added.

        Returns:
            None

        """
        j = 0
        for i in range(face_offset, face_offset + len(preds_list)):
            self.faces[i].preds[predictor_name] = preds_list[j]
            j += 1

    def reset_img(self) -> None:
        """Reset the original image tensor to empty state."""
        self.img = torch.tensor([])

    def reset_tensor(self) -> None:
        """Reset the processed image tensor to empty state."""
        self.tensor = torch.tensor([])

    def reset_face_tensors(self) -> None:
        """Reset the face tensors to empty state."""
        for i in range(0, len(self.faces)):
            self.faces[i].tensor = torch.tensor([])

    def reset_face_pred_tensors(self) -> None:
        """Reset prediction tensors while preserving non-tensor metadata."""
        for i in range(0, len(self.faces)):
            for key in self.faces[i].preds:
                prediction = self.faces[i].preds[key]
                prediction.logits = torch.tensor([])
                cleaned_other = _without_tensors(prediction.other)
                prediction.other = (
                    {} if cleaned_other is _REMOVED_TENSOR else cleaned_other
                )

    def reset_det_tensors(self) -> None:
        """Reset the detection object to empty state."""
        self.det = Detection()

    @Timer(
        "ImageData.reset_faces", "{name}: {milliseconds:.2f} ms", logger=logger.debug
    )
    def reset_tensors(self) -> None:
        """Reset the tensors to empty state."""
        self.reset_img()
        self.reset_tensor()
        self.reset_face_tensors()
        self.reset_face_pred_tensors()
        self.reset_det_tensors()

    def set_dims(self) -> None:
        """Set the dimensions attribute from the tensor attribute."""
        self.dims.height = self.tensor.shape[2]
        self.dims.width = self.tensor.shape[3]

    def aggregate_loc_tensor(self) -> torch.Tensor:
        """Aggregates the location tensor from all faces.

        Returns:
            torch.Tensor: Aggregated location tensor for drawing purposes.
        """
        loc_tensor = torch.zeros((len(self.faces), 4), dtype=torch.float32)
        for i in range(0, len(self.faces)):
            loc_tensor[i] = torch.tensor(
                [
                    self.faces[i].loc.x1,
                    self.faces[i].loc.y1,
                    self.faces[i].loc.x2,
                    self.faces[i].loc.y2,
                ]
            )
        return loc_tensor

The main data class used for passing data between the different facetorch modules.

Attributes
-----=
path_input : str
Path to the input image.
path_output : str
Path to the output image where the resulting image is saved.
img : torch.Tensor
Original image tensor used for drawing purposes.
tensor : torch.Tensor
Processed image tensor.
dims : Dimensions
Dimensions of the image (height, width).
det : Detection
Detection data given by the detector.
faces : List[Face]
List of faces in the image.
version : str
Version of the facetorch library.

Instance variables

var path_input : str
var path_output : str | None
var img : torch.Tensor
var tensor : torch.Tensor
var dimsDimensions
var detDetection
var faces : List[Face]
var version : str
var warnings : List[str]

Methods

def add_preds(self,
preds_list: List[Prediction],
predictor_name: str,
face_offset: int = 0) ‑> None
Expand source code
def add_preds(
    self,
    preds_list: List[Prediction],
    predictor_name: str,
    face_offset: int = 0,
) -> None:
    """Adds a list of predictions to the data object.

    Args:
        preds_list (List[Prediction]): List of predictions.
        predictor_name (str): Name of the predictor.
        face_offset (int): Offset of the face index where the predictions are added.

    Returns:
        None

    """
    j = 0
    for i in range(face_offset, face_offset + len(preds_list)):
        self.faces[i].preds[predictor_name] = preds_list[j]
        j += 1

Adds a list of predictions to the data object.

Args
-----=
preds_list : List[Prediction]
List of predictions.
predictor_name : str
Name of the predictor.
face_offset : int
Offset of the face index where the predictions are added.

Returns -----= None

def reset_img(self) ‑> None
Expand source code
def reset_img(self) -> None:
    """Reset the original image tensor to empty state."""
    self.img = torch.tensor([])

Reset the original image tensor to empty state.

def reset_tensor(self) ‑> None
Expand source code
def reset_tensor(self) -> None:
    """Reset the processed image tensor to empty state."""
    self.tensor = torch.tensor([])

Reset the processed image tensor to empty state.

def reset_face_tensors(self) ‑> None
Expand source code
def reset_face_tensors(self) -> None:
    """Reset the face tensors to empty state."""
    for i in range(0, len(self.faces)):
        self.faces[i].tensor = torch.tensor([])

Reset the face tensors to empty state.

def reset_face_pred_tensors(self) ‑> None
Expand source code
def reset_face_pred_tensors(self) -> None:
    """Reset prediction tensors while preserving non-tensor metadata."""
    for i in range(0, len(self.faces)):
        for key in self.faces[i].preds:
            prediction = self.faces[i].preds[key]
            prediction.logits = torch.tensor([])
            cleaned_other = _without_tensors(prediction.other)
            prediction.other = (
                {} if cleaned_other is _REMOVED_TENSOR else cleaned_other
            )

Reset prediction tensors while preserving non-tensor metadata.

def reset_det_tensors(self) ‑> None
Expand source code
def reset_det_tensors(self) -> None:
    """Reset the detection object to empty state."""
    self.det = Detection()

Reset the detection object to empty state.

def reset_tensors(self) ‑> None
Expand source code
@Timer(
    "ImageData.reset_faces", "{name}: {milliseconds:.2f} ms", logger=logger.debug
)
def reset_tensors(self) -> None:
    """Reset the tensors to empty state."""
    self.reset_img()
    self.reset_tensor()
    self.reset_face_tensors()
    self.reset_face_pred_tensors()
    self.reset_det_tensors()

Reset the tensors to empty state.

def set_dims(self) ‑> None
Expand source code
def set_dims(self) -> None:
    """Set the dimensions attribute from the tensor attribute."""
    self.dims.height = self.tensor.shape[2]
    self.dims.width = self.tensor.shape[3]

Set the dimensions attribute from the tensor attribute.

def aggregate_loc_tensor(self) ‑> torch.Tensor
Expand source code
def aggregate_loc_tensor(self) -> torch.Tensor:
    """Aggregates the location tensor from all faces.

    Returns:
        torch.Tensor: Aggregated location tensor for drawing purposes.
    """
    loc_tensor = torch.zeros((len(self.faces), 4), dtype=torch.float32)
    for i in range(0, len(self.faces)):
        loc_tensor[i] = torch.tensor(
            [
                self.faces[i].loc.x1,
                self.faces[i].loc.y1,
                self.faces[i].loc.x2,
                self.faces[i].loc.y2,
            ]
        )
    return loc_tensor

Aggregates the location tensor from all faces.

Returns
-----=
torch.Tensor
Aggregated location tensor for drawing purposes.
class AnalysisResult (faces: List[Face] = <factory>,
version: str = <factory>,
image: torch.Tensor | None = None,
tensor: torch.Tensor | None = None,
detection: Detection | None = None,
dimensions: Dimensions = <factory>,
path_input: str | None = None,
path_output: str | None = None,
warnings: List[str] = <factory>)
Expand source code
@dataclass
class AnalysisResult:
    """Stable result for one analyzed source image.

    ``faces``, ``version``, dimensions, paths, and warnings are always available.
    Tensor-heavy fields are ``None`` unless ``include_tensors=True`` was used.
    Runtime timing remains diagnostic logging rather than a stable result field.
    ``img``, ``det``, and ``dims`` remain warning aliases throughout v1.x.
    """

    faces: List[Face] = field(default_factory=list)
    version: str = field(default_factory=str)
    image: Optional[torch.Tensor] = None
    tensor: Optional[torch.Tensor] = None
    detection: Optional[Detection] = None
    dimensions: Dimensions = field(default_factory=Dimensions)
    path_input: Optional[str] = None
    path_output: Optional[str] = None
    warnings: List[str] = field(default_factory=list)

    @classmethod
    def from_image_data(
        cls, data: ImageData, *, include_tensors: bool
    ) -> "AnalysisResult":
        """Create the public result without introducing a second pipeline."""
        return cls(
            faces=data.faces,
            version=data.version,
            image=data.img if include_tensors else None,
            tensor=data.tensor if include_tensors else None,
            detection=data.det if include_tensors else None,
            dimensions=data.dims,
            path_input=data.path_input,
            path_output=data.path_output,
            warnings=list(data.warnings),
        )

    @property
    def img(self) -> Optional[torch.Tensor]:
        """Deprecated v0.x alias for :attr:`image`."""
        _warnings.warn(
            "AnalysisResult.img is deprecated; use AnalysisResult.image.",
            DeprecationWarning,
            stacklevel=2,
        )
        return self.image

    @property
    def det(self) -> Optional[Detection]:
        """Deprecated v0.x alias for :attr:`detection`."""
        _warnings.warn(
            "AnalysisResult.det is deprecated; use AnalysisResult.detection.",
            DeprecationWarning,
            stacklevel=2,
        )
        return self.detection

    @property
    def dims(self) -> Dimensions:
        """Deprecated v0.x alias for :attr:`dimensions`."""
        _warnings.warn(
            "AnalysisResult.dims is deprecated; use AnalysisResult.dimensions.",
            DeprecationWarning,
            stacklevel=2,
        )
        return self.dimensions

Stable result for one analyzed source image.

faces, version, dimensions, paths, and warnings are always available. Tensor-heavy fields are None unless include_tensors=True was used. Runtime timing remains diagnostic logging rather than a stable result field. img, det, and dims remain warning aliases throughout v1.x.

Static methods

def from_image_data(data: ImageData,
*,
include_tensors: bool) ‑> AnalysisResult

Create the public result without introducing a second pipeline.

Instance variables

var faces : List[Face]
var version : str
var dimensionsDimensions
var warnings : List[str]
var image : torch.Tensor | None
var tensor : torch.Tensor | None
var detectionDetection | None
var path_input : str | None
var path_output : str | None
prop img : torch.Tensor | None
Expand source code
@property
def img(self) -> Optional[torch.Tensor]:
    """Deprecated v0.x alias for :attr:`image`."""
    _warnings.warn(
        "AnalysisResult.img is deprecated; use AnalysisResult.image.",
        DeprecationWarning,
        stacklevel=2,
    )
    return self.image

Deprecated v0.x alias for :attr:image.

prop detDetection | None
Expand source code
@property
def det(self) -> Optional[Detection]:
    """Deprecated v0.x alias for :attr:`detection`."""
    _warnings.warn(
        "AnalysisResult.det is deprecated; use AnalysisResult.detection.",
        DeprecationWarning,
        stacklevel=2,
    )
    return self.detection

Deprecated v0.x alias for :attr:detection.

prop dimsDimensions
Expand source code
@property
def dims(self) -> Dimensions:
    """Deprecated v0.x alias for :attr:`dimensions`."""
    _warnings.warn(
        "AnalysisResult.dims is deprecated; use AnalysisResult.dimensions.",
        DeprecationWarning,
        stacklevel=2,
    )
    return self.dimensions

Deprecated v0.x alias for :attr:dimensions.

class Response (faces: List[Face] = <factory>,
version: str = <factory>)
Expand source code
@dataclass
class Response:
    """Data class for response data, which is a subset of ImageData.

    Attributes:
        faces (List[Face]): List of faces in the image.
        version (str): Version of the facetorch library.

    """

    faces: List[Face] = field(default_factory=list)
    version: str = field(default_factory=str)

Data class for response data, which is a subset of ImageData.

Attributes
-----=
faces : List[Face]
List of faces in the image.
version : str
Version of the facetorch library.

Instance variables

var faces : List[Face]
var version : str