目次
概要
OpenCV の inRange を使用した 2 値化方法について解説します。
inRange による 2 値化
cv2.inRange()
は、指定した範囲内の値を持つ画素を 255 で、それ以外の画素を 0 に変換して 2 値化を行う関数です。この関数は、画像中の特定の色範囲を抽出し、2 値画像を生成する際に利用されます。
1 チャンネル画像の 2 値化
255 に変換する輝度値の範囲 $[l, u]$ を指定します。
dst = cv2.inRange(src, l, u)
$$
\displaystyle
dst(x, y) =
\begin{cases}
255 & l \le src(x, y) \le u \\
0 & その他の場合
\end{cases}
$$
3 チャンネル画像の 2 値化
255 に変換する輝度値の範囲の下限 $(l1, l2, l3)$ と上限 $u1, u2, u3$ を指定します。
dst = cv2.inRange(src, (l1, l2, l3), (u1, u2, u3))
$$
\displaystyle
dst(x, y) =
\begin{cases}
255 & (l_1, l_2, l_3) \le src(x, y) \le (u_1, u_2, u_3) \\
0 & その他の場合
\end{cases}
$$
画像から特定の色を抽出する
cv2.inRange()
は画像から特定の色を抽出するのに便利な関数です。
In [1]:
import cv2
import numpy as np
from IPython import display
from matplotlib import pyplot as plt
def imshow(img, format=".jpg", **kwargs):
"""ndarray 配列をインラインで Notebook 上に表示する。"""
img = cv2.imencode(format, img)[1]
img = display.Image(img, **kwargs)
display.display(img)
色の選択は RGB 色空間で行うよりも、HSV 色空間に変換して行ったほうが選択しやすくなります。HSV 色空間の場合、S、V は下限 0、上限 255 のままにし、H (色相) で調整するのがおすすめです。
HSV 色空間での範囲選択は下記を参考にしてください。
In [2]:
def binarize(img, c1, c2, c3):
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([c1[0], c2[0], c3[0]])
upper = np.array([c1[1], c2[1], c3[1]])
dst = cv2.inRange(hsv, lower, upper)
return dst
img = cv2.imread("sample.jpg")
dst = binarize(img, c1=(0, 20), c2=(0, 255), c3=(0, 255))
imshow(dst)
2 値画像を使って透過処理する
2 値画像を使って透過処理を行う方法を紹介します。
In [3]:
def binarize(img, c1, c2, c3):
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([c1[0], c2[0], c3[0]])
upper = np.array([c1[1], c2[1], c3[1]])
dst = cv2.inRange(hsv, lower, upper)
return dst
img = cv2.imread("sample.jpg")
img_bin = binarize(img, c1=(0, 20), c2=(0, 255), c3=(0, 255))
# アルファチャンネルを追加する
bgra = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
# 2値画像の値が0の画素のアルファ値は0 (透過) にする
bgra[img_bin == 0, 3] = 0
imshow(bgra, ".png")
ipywidgets を使用したパラメータ調整
ipywidgets のスライダー機能を使って、インタラクティブにパラメータを決めるためのコードを紹介します。
In [4]:
from ipywidgets import widgets, fixed
def binarize(img, c1, c2, c3):
"""2値化処理を行い、結果を表示する。"""
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([c1[0], c2[0], c3[0]])
upper = np.array([c1[1], c2[1], c3[1]])
img_bin = cv2.inRange(hsv, lower, upper)
imshow(img_bin)
# パラメータ lower, upper を設定するスライダー
names = ["H", "S", "V"]
parts = {}
for i, name in enumerate(names, 1):
slider = widgets.SelectionRangeSlider(
options=np.arange(256), index=(0, 255), description=name
)
slider.layout.width = "400px"
parts[f"c{i}"] = slider
# 画像を読み込む。
img = cv2.imread("sample.jpg")
# ウィジェットを表示する。
widgets.interactive(binarize, **parts, img=fixed(img))
コメント