Files
labs-information-security/lab6-steganography/entities/block_grid8.py
T

41 lines
1.8 KiB
Python
Raw Normal View History

2026-07-12 14:06:45 +04:00
from __future__ import annotations
from dataclasses import dataclass
import numpy as np
@dataclass(frozen=True)
class BlockGrid8:
"""Разбиение и сборка блоков 8×8."""
@staticmethod
def split(component: np.ndarray) -> np.ndarray:
"""Разбить 2D-компоненту на блоки (N,8,8)."""
if component.ndim != 2:
raise ValueError("Ожидается 2D-массив компоненты.")
h, w = component.shape
if h % 8 != 0 or w % 8 != 0:
raise ValueError("Размеры должны быть кратны 8.")
# Перестановка осей даёт (nH, nW, 8, 8) -> (N, 8, 8)
arr = np.asarray(component)
nH, nW = h // 8, w // 8
blocks = arr.reshape(nH, 8, nW, 8).transpose(
0, 2, 1, 3).reshape(nH * nW, 8, 8)
return blocks
@staticmethod
def merge(blocks: np.ndarray, height: int, width: int) -> np.ndarray:
"""Собрать 2D-компоненту из блоков (N,8,8)."""
if blocks.ndim != 3 or blocks.shape[1:] != (8, 8):
raise ValueError("Ожидается массив блоков формы (N,8,8).")
if height % 8 != 0 or width % 8 != 0:
raise ValueError("Размеры должны быть кратны 8.")
nH, nW = height // 8, width // 8
if blocks.shape[0] != nH * nW:
raise ValueError(
"Количество блоков не соответствует размеру выходной матрицы.")
# Обратная перестановка из (N,8,8) -> (nH, nW, 8, 8) -> (H, W)
arr = np.asarray(blocks)
comp = arr.reshape(nH, nW, 8, 8).transpose(
0, 2, 1, 3).reshape(height, width)
return comp