Files
labs-information-security/lab6-steganography/entities/label64.py
T
2026-07-12 14:06:45 +04:00

47 lines
1.7 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from typing import Iterable
import numpy as np
from PIL import Image
@dataclass(frozen=True)
class Label64:
"""Бинарная метка 64x64."""
data: np.ndarray # uint8, shape (64, 64), значения {0,1}
def __post_init__(self):
arr = np.asarray(self.data, dtype=np.uint8)
if arr.shape != (64, 64):
raise ValueError("Метка должна быть 64x64.")
# Нормализация к {0,1}
arr = (arr > 0).astype(np.uint8)
object.__setattr__(self, "data", arr)
@classmethod
def from_image(cls, path: str, threshold: int = 128) -> "Label64":
"""Создать из изображения 64x64."""
img = Image.open(path).convert("L")
if img.size != (64, 64):
raise ValueError("Изображение метки должно быть 64x64.")
arr = np.array(img, dtype=np.uint8)
arr = (arr >= threshold).astype(np.uint8)
return cls(arr)
@classmethod
def from_vector(cls, vec: Iterable[int]) -> "Label64":
"""Создать из вектора длиной 4096."""
v = np.fromiter(vec, dtype=np.uint8, count=4096)
if v.size != 4096:
raise ValueError("Длина вектора должна быть 4096.")
return cls(v.reshape(64, 64))
def to_vector(self) -> np.ndarray:
"""Вернуть вектор длиной 4096."""
return self.data.reshape(-1).astype(np.uint8)
def to_image(self, path: str) -> None:
"""Сохранить PNG 64x64."""
Image.fromarray(self.data * 255, mode="L").save(path)