OpenCV – エンボス処理を行う方法について

目次

概要

OpenCV で画像にエンボス処理を行う方法について解説します。

エンボス処理

入力画像の $(x, y)$ の画素値を $\text{src}(x, y)$ としたとき、符号を反転させ、$x, y$ 共に $t$ だけ平行移動した位置の画素 $-\text{src}(x + t, y + t)$ を足して、出力画像の画素を作成する処理をエンボス (emboss) といいます。

$$ \text{dst}(x, y) = \text{src} + (-\text{src}(x + t, y + t)) $$

1次元で考えると、以下のようにエッジ部分を強調する処理であると理解できます。

フィルタを使用したエンボス処理

エンボス処理はフィルタリングでも行えます。

水平方向のエンボスフィルタ

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

垂直方向のエンボスフィルタ

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

斜め方向のエンボスフィルタ

$$ \begin{pmatrix} 1 & 0 & 0 \\ 0 & 0 & 0 \\ 0 & 0 & -1 \\ \end{pmatrix}, \begin{pmatrix} -1 & 0 & 0 \\ 0 & 0 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} $$$$ \begin{pmatrix} 0 & 0 & 1 \\ 0 & 0 & 0 \\ -1 & 0 & 0 \\ \end{pmatrix}, \begin{pmatrix} 0 & 0 & -1 \\ 0 & 0 & 0 \\ 1 & 0 & 0 \\ \end{pmatrix} $$

OpenCV でのエンボス処理

sample.jpg

In [1]:
import cv2
import numpy as np
from IPython.display import Image, display


def imshow(img):
    """ndarray 配列をインラインで Notebook 上に表示する。
    """
    ret, encoded = cv2.imencode(".jpg", img)
    display(Image(encoded))


# 画像を読み込む。
img = cv2.imread("sample.jpg", cv2.IMREAD_GRAYSCALE)

cv2.filter() で画像にエンボスフィルタを適用できます。 演算結果は $[0, 255]$ に収まらないので、ddepth=cv2.CV_32F を指定して、結果は float32 型の配列で受け取ります。その後、$[0, 255]$ の範囲にスケールします。

水平方向のエンボスフィルタ

In [2]:
def scale(x):
    x = 255 / (x.max() - x.min()) * (x - x.max()) + 255
    return x.astype(np.uint8)


# 水平方向のエンボスフィルタ
kernel = np.array([[0, 0, 0],
                   [1, 0, -1],
                   [0, 0, 0]])
dst = cv2.filter2D(img, cv2.CV_32F, kernel)
dst = scale(dst)
imshow(dst)

垂直方向のエンボスフィルタ

In [3]:
# 垂直方向のエンボスフィルタ
kernel = np.array([[0, 1, 0],
                   [0, 0, 0],
                   [0, -1, 0]])
dst = cv2.filter2D(img, cv2.CV_32F, kernel)
dst = scale(dst)
imshow(dst)

斜め方向のエンボスフィルタ

In [4]:
kernel = np.array([[1, 0, 0],
                   [0, 0, 0],
                   [0, 0, -1]])
dst = cv2.filter2D(img, cv2.CV_32F, kernel)
dst = scale(dst)
imshow(dst)
In [5]:
kernel = np.array([[0, 0, -1],
                   [0, 0, 0],
                   [1, 0, 0]])
dst = cv2.filter2D(img, cv2.CV_32F, kernel)
dst = scale(dst)
imshow(dst)

エンボスをより強くする

In [6]:
kernel = np.array(
    [
        [1, 0, 0, 0, 0],
        [0, 1, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, -1, 0],
        [0, 0, 0, 0, -1],
    ]
)
dst = cv2.filter2D(img, cv2.CV_32F, kernel)
dst = scale(dst)
imshow(dst)

コメント

コメントする

目次