OpenCV – 画像をせん断、平行移動する方法

目次

概要

画像に対して、平行移動やせん断といったアフィン変換を適用する方法について解説します。

平行移動

$x$ 軸方向に $t_x$、$y$ 軸方向に $t_y$ だけ平行移動 (translation) するアフィン変換行列は、以下のようになります。

$$ \begin{pmatrix} 1 & 0 & t_1\\ 0 & 1 & t_2\\ \end{pmatrix} $$
In [1]:
import cv2
from IPython import display


def imshow(img, format=".jpg", **kwargs):
    """ndarray 配列をインラインで Notebook 上に表示する。"""
    img = cv2.imencode(format, img)[1]
    img = display.Image(img, **kwargs)
    display.display(img)
In [2]:
import cv2
import numpy as np


def translation(tx, ty):
    M = np.array(
        [
            [1, 0, tx],
            [0, 1, ty],
        ],
        dtype=float,
    )

    return M


img = cv2.imread("sample.jpg")

M = translation(20, 30)
img_h, img_w = img.shape[:2]
dst = cv2.warpAffine(img, M, dsize=(img_w, img_h))
imshow(dst)

せん断

せん断変換 (shear transformation) は、平面や空間の幾何学的変換の一つで、図形をある方向に平行に引き伸ばす操作です。 $x$ 軸方向、$y$ 軸方向のせん断変換は次のアフィン変換行列で表されます。ただし、$k$ はせん断の強さを表す係数です。

水平せん断

$$ \begin{pmatrix} 1 & k & 0\\ 0 & 1 & 0\\ \end{pmatrix} $$

鉛直せん断

$$ \begin{pmatrix} 1 & 0 & 0\\ k & 1 & 0\\ \end{pmatrix} $$
In [3]:
def sheer_x(k):
    M = np.array(
        [
            [1, k, 0],
            [0, 1, 0],
        ],
        dtype=float,
    )

    return M


img = cv2.imread("sample.jpg")

M = sheer_x(0.2)
img_h, img_w = img.shape[:2]
dst = cv2.warpAffine(img, M, dsize=(img_w, img_h))
imshow(dst)
In [4]:
def sheer_y(k):
    M = np.array(
        [
            [1, 0, 0],
            [k, 1, 0],
        ],
        dtype=float,
    )

    return M


img = cv2.imread("sample.jpg")

M = sheer_y(0.2)
img_h, img_w = img.shape[:2]
dst = cv2.warpAffine(img, M, dsize=(img_w, img_h))
imshow(dst)

コメント

コメントする

目次