Source code for wed.chaptors.rotating_rectangle
# coding: utf-8
"""This submodule contains a set of functions for editing the following image:
.. image:: _images/chaptors/rotating-rectangle.png
:class: popup-img
"""
from typing import Tuple
import cv2
import numpy as np
import numpy.typing as npt
import scipy as sp
import scipy.ndimage
from ..utils._path import ROTATING_SQUARE_IMAGE_PATH
from .base_editor import BaseWedOPEditor
[docs]class RotatingRectangleEditor(BaseWedOPEditor):
"""Editor which in charge of editing rotating rectangle.
.. image:: _images/chaptors/rotating-rectangle.png
:class: popup-img
Args:
square_image_path (str, optional) : The path to the image for embedding. Defaults to ``ROTATING_SQUARE_IMAGE_PATH``.
atol (int, optional) : Absolute tolerance to recognize where to embed a square image. Defaults to ``50``.
rotating_start_pos (int, optional) : The number of the frame where the rotation starts. Defaults to ``220``.
Attributes:
MASKED_COLOR (Tuple[int,int,int]) : BGR Color of the part to be masked.
"""
MASKED_COLOR: Tuple[int, int, int] = (248, 232, 217)
def __init__(
self,
square_image_path: str = ROTATING_SQUARE_IMAGE_PATH,
atol: int = 50,
rotating_start_pos: int = 220,
):
super().__init__(
positions=(212, 246), image_paths=dict(square_image=square_image_path)
)
self.atol = atol
self.rotating_start_pos = rotating_start_pos
[docs] def edit(self, frame: npt.NDArray[np.uint8], pos: int) -> npt.NDArray[np.uint8]:
"""Edit the image if it is an assigned chapter (``pos``)
Args:
frame (npt.NDArray[np.uint8]) : Current frame (BGR image) in the video.
pos (int) : Current position in the video.
Returns:
npt.NDArray[np.uint8]: Edited frame.
"""
frame = self.embed_image(frame=frame, pos=pos)
return frame
[docs] def embed_image(
self, frame: npt.NDArray[np.uint8], pos: int
) -> npt.NDArray[np.uint8]:
"""Embed a square image in the following gray square:
.. image:: _images/chaptors/rotating-rectangle.png
:class: popup-img
Args:
frame (npt.NDArray[np.uint8]) : Current frame (BGR image) in the video.
pos (int) : Current position in the video.
Returns:
npt.NDArray[np.uint8]: Edited frame.
"""
H, W = frame.shape[:2]
h, w = cH, cW = (H // 2, W // 2)
flag = (
np.sum(
np.abs(
frame - np.asarray([[RotatingRectangleEditor.MASKED_COLOR]]),
dtype=int,
),
axis=2,
)
< self.atol
)
while True:
if not flag[h, w]:
if np.any(flag[h - 1, w : w + 3]):
w += 1
else:
break
else:
h += 1
l = int(np.sqrt((h - cH) ** 2 + (w - cW) ** 2))
mask = np.zeros_like(flag)
mask[cH - l : cH + l, cW - l : cW + l] = flag[cH - l : cH + l, cW - l : cW + l]
paste = np.zeros_like(frame)
paste[cH - l : cH + l, cW - l : cW + l] = cv2.resize(
src=sp.ndimage.rotate(
self.square_image_arr,
angle=int(45 + max(0, 20 / 26 * (pos - self.rotating_start_pos))),
),
dsize=(int(2 * l), int(2 * l)),
)
return np.where(mask[:, :, None], paste, frame)