35 lines
1.3 KiB
Python
35 lines
1.3 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
from dataclasses import dataclass
|
||
|
|
import numpy as np
|
||
|
|
|
||
|
|
from entities.rgb_image512 import RgbImage512
|
||
|
|
from entities.ycbcr_image512 import YcbcrImage512
|
||
|
|
from entities.label64 import Label64
|
||
|
|
from entities.sequence8 import Sequence8
|
||
|
|
|
||
|
|
from .embedder import Embedder
|
||
|
|
from .extractor import Extractor
|
||
|
|
|
||
|
|
|
||
|
|
@dataclass(frozen=True)
|
||
|
|
class ComponentPipeline:
|
||
|
|
"""Оркестрация встраивания/извлечения в заданный канал Y/Cb/Cr."""
|
||
|
|
|
||
|
|
channel: str # "Y", "Cb", "Cr"
|
||
|
|
embedder: Embedder
|
||
|
|
extractor: Extractor
|
||
|
|
|
||
|
|
def embed_rgb(self, rgb: RgbImage512, label: Label64, seq: Sequence8) -> RgbImage512:
|
||
|
|
"""Вернуть новый RGB с вшитой меткой в выбранный канал."""
|
||
|
|
ycbcr = YcbcrImage512.from_rgb(rgb)
|
||
|
|
comp = ycbcr.get_channel(self.channel)
|
||
|
|
comp_new = self.embedder.embed_component(comp, label, seq)
|
||
|
|
ycbcr_new = ycbcr.with_channel(self.channel, comp_new)
|
||
|
|
return ycbcr_new.to_rgb()
|
||
|
|
|
||
|
|
def extract_from_rgb(self, rgb: RgbImage512, seq: Sequence8) -> Label64:
|
||
|
|
"""Извлечь метку из выбранного канала RGB-изображения."""
|
||
|
|
ycbcr = YcbcrImage512.from_rgb(rgb)
|
||
|
|
comp = ycbcr.get_channel(self.channel)
|
||
|
|
return self.extractor.extract_label(comp, seq)
|