15
13

More than 3 years have passed since last update.

OpenCVによるコントラストと明るさの調整

Last updated at Posted at 2021-03-20

はじめに

GIMPなどに明るさ・コントラストを調整する画面があります。
こんな機能を明るさ・コントラストをOpenCVとPythonで実装してみたいと思います。
GIMPは、明るさ・コントラストを0~127段階で調整できますが、この調整項の段階に
ついては同様にはいたしません。

GIMP操作風景
GIMP_SCREEN.JPG

処理方法

今回の入力画像としては、今年鉄道が運休するほど大雪が降った日の写真です。
朝なので暗いです。この暗い感じを何とかしたいと思います。

snow400.JPG

まずはヒストグラムで現状確認します。
q_first_hist_graph.png

処理としては、グラフの山を左右に広げるとコントラストが改善します。
また、山全体を左に寄せると暗くなり、右側に寄せると明るくなります。
この辺の操作を計算で行います。

計算方法

alphaをコントラスト係数とし、betaを明るさ係数とします。

R ← R × apha + beta
G ← G × apha + beta
B ← B × apha + beta

OpenCVによる実装

convertScaleAbs()関数を使います。

関数
dst = cv.convertScaleAbs(src[, dst[, alpha[, beta]]])
 src - 入力イメージ
 alpha - scaleファクタ
 beta - スケーリングされた値に加算する値(デルタ)
 dst - 出力イメージ

このような式の計算を行います。

dst(I)=saturate_cast(|src(I)∗alpha+beta|)

機能としては下記コードと等価です。

for y in range(image.shape[0]):
    for x in range(image.shape[1]):
        for c in range(image.shape[2]):
            res_image[y,x,c] = np.clip(alpha*image[y,x,c] + beta, 0, 255)

詳細は下記リンクを参照してください。

opencv.org - Operations on arrays

プログラム

import cv2
import numpy as np
import matplotlib.pyplot as plt

# ヒストグラム表示
def histgram(image, filename):
    histR = cv2.calcHist([image],[0,], None, [256,], [0, 255,] )
    histG = cv2.calcHist([image],[1,], None, [256,], [0, 255,] )
    histB = cv2.calcHist([image],[2,], None, [256,], [0, 255,] )

    plt.title("Histgram")
    plt.plot(histR,c='red', label='red')
    plt.plot(histG,c='green', label='green')
    plt.plot(histB,c='blue', label='blue')
    plt.grid()
    plt.show()

def main():
    image = cv2.imread('snow400.JPG', cv2.IMREAD_COLOR)
    if image is None:
        print('ファイルオープンエラー')
        exit(0)
    # 入力画像表示
    cv2.imshow('Original Image', image)
    cv2.waitKey()

    alpha = 1.3 # コントラスト項目
    beta = 30    # 明るさ項目

    # 明るさ・コントラスト操作
    res_image = cv2.convertScaleAbs(image,alpha = alpha,beta = beta)

    # 画像表示
    capt = 'New Image alpha=%.1f beta=%.1f' % (alpha,beta )
    cv2.imshow(capt, res_image)
    cv2.waitKey()

    # ヒストグラム表示
    histgram(res_image, capt + '.png')

if __name__ == '__main__':
    main()

入力画像ファイル名はsnow400.JPGとし、
パラメータ alpha = 1.3 , beta = 30 を仮で入力しています。

明るさ・コントラスト処理結果

処理条件 aplha=1.0 beta=80

bconv_1.0_80.jpg
明るさは改善していますが、全体的にコントラストが悪いです。

q_Image alpha=1.0 beta=80.0.png
全体的にグラフの山が右に移動しているのが分かるかと面ます。

処理条件 aplha=1.3 beta=40

bconv_1.3_40.jpg
明るさ、コントラストが改善しています。

q_Image alpha=1.3 beta=40.0.png

処理条件 aplha=1.6 beta=80

bconv_1.6_80.jpg
露光オーバーな感じになっています。

q_Image alpha=1.6 beta=80.0.png
計算値が255からオーバーフローしているのが分かるかともいます。

終わりに

明るさ・コントラストを自動で改善する方法もありますが、OpenCVによる
明るさ・コントラストの基本的操作について書かれた記事が見つけられなかったので
書かせていただきました。
このアルゴリズムは人の確認が必要だったりしますが、下手に自動にすると
再現性のない画像を量産することにもなるため、その目的などに応じて
適用してくのが良いかと思います。
ありがとうございました。

実行環境

Windows10 Anaconda 3(Miniforge)
Python 3.9.2 packaged by conda-forge
OpenCV 4.5.1
numpy 1.20.1

参考

Emotion Explorer - OpenCV 画像のコントラストと明るさの調整

15
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
13