OpenCV – 画像の明るさ、コントラストの変更、ガンマ補正

OpenCV – 画像の明るさ、コントラストの変更、ガンマ補正

概要

OpenCV で画像の明るさやコントラストを変更する方法について紹介します。

Advertisement

積和演算で明るさ、コントラストを変更する。

画像の位置 $(x, y)$ の画素値を $\text{src}(x, y)$ としたとき、次の式で明るさおよびコントラストを変更できます。

$$ \text{dst}(x, y) = \alpha \text{src}(x, y) + \beta $$

$\alpha, \beta$ は定数で、$\alpha$ はゲイン (gain) またはコントラスト (contrast)、$\beta$ はバイアス (bias) または明るさ (brightness) といいます。

各パラメータの効果

明るさを $1.0$ で固定し、コントラストのパラメータを変化させた結果を確認します。

コントラストを $0.0$ で固定し、明るさのパラメータを変化させた結果を確認します。

サンプルコード

積和演算を行った後、値を画素値として有効な値にするため、$[0, 255]$ の範囲でクリップを行い、型を numpy.uint8 にキャストします。

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))

def adjust(img, alpha=1.0, beta=0.0):
    # 積和演算を行う。
    dst = alpha * img + beta
    # [0, 255] でクリップし、uint8 型にする。
    return np.clip(dst, 0, 255).astype(np.uint8)


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

# コントラスト、明るさを変更する。
dst = adjust(src, alpha=2.0, beta=30.0)
imshow(dst)
Advertisement

ipywidgets を使用したパラメータ調整

Jupyter Notebook で利用できる ipywidgets を使ってパラメータを調整するためのコードを記載します。

ipywidgets

In [2]:
import cv2
from IPython.display import Image, display
from ipywidgets import widgets


def imshow(img):
    """画像を Notebook 上に表示する。
    """
    encoded = cv2.imencode(".png", img)[1]
    display(Image(encoded, width=400))


def process(img, alpha, beta):
    """明るさ、コントラストを調整し、結果を表示する。
    """
    dst = adjust(img, alpha, beta)
    imshow(dst)


param_widgets = {}

# パラメータ「ゲイン」を設定するスライダー
param_widgets["alpha"] = widgets.FloatSlider(
    min=0.0, max=3.0, step=0.1, value=1.0, description="alpha: "
)

# パラメータ「バイアス」を設定するスライダー
param_widgets["beta"] = widgets.FloatSlider(
    min=-100.0, max=100.0, step=10.0, value=0.0, description="beta: "
)

for x in param_widgets.values():
    x.layout.width = "400px"

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

# ウィジェットを表示する。
widgets.interactive(process, img=widgets.fixed(img), **param_widgets)

ガンマ補正

画像の位置 $(x, y)$ の画素値を $src(x, y)$ としたとき、次の式で変換する処理をガンマ補正 (gamma correction) といいます。

$$ y = \left(\frac{x}{255}\right)^\gamma \times 255 $$

ただし、$\gamma$ は定数です。$\gamma = 1$ のとき、$y = x$ となり、入力と出力が同じになります。

パラメータ $\gamma$ を変化させた結果を確認します。

サンプルコード

画素値の変換には、cv2.LUT() を使います。ガンマ補正の計算を行ったあと、値を画素値として有効な値にするため、$[0, 255]$ の範囲でクリップを行い、型を numpy.uint8 にキャストします。

In [3]:
import cv2
import numpy as np


def gamma_correction(img, gamma):
    # テーブルを作成する。
    table = (np.arange(256) / 255) ** gamma * 255
    # [0, 255] でクリップし、uint8 型にする。
    table = np.clip(table, 0, 255).astype(np.uint8)

    return cv2.LUT(img, table)


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

# コントラスト、明るさを変更する。
dst = gamma_correction(src, gamma=2.0)
imshow(dst)
Advertisement

ipywidgets を使用したパラメータ調整

Jupyter Notebook で利用できる ipywidgets を使ってパラメータを調整するためのコードを記載します。

ipywidgets

In [4]:
import cv2
from IPython.display import Image, display
from ipywidgets import widgets


def imshow(img):
    """画像を Notebook 上に表示する。
    """
    encoded = cv2.imencode(".png", img)[1]
    display(Image(encoded, width=400))


def process(img, gamma):
    """ガンマ補正を行い、結果を表示する。
    """
    dst = gamma_correction(img, gamma)
    imshow(dst)


# パラメータ「ガンマ」を設定するスライダー
slider = widgets.FloatSlider(
    min=0.0, max=3.0, step=0.1, value=1.0, description="gamma: "
)
slider.layout.width = "400px"

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

# ウィジェットを表示する。
widgets.interactive(process, img=widgets.fixed(img), gamma=slider)