【Python初心者】明るさとコントラストの調整

写真を撮影する際には、撮影条件や環境によって明るさやコントラストが適切でないことがあります

しかし、PythonのOpenCVライブラリを利用することで、画像の明るさやコントラストを調整することができます

ここでは、明るさとコントラストの調整方法について初心者向けにわかりやすく解説します

明るさとコントラストの調整は、写真を魅力的に見せるために重要な処理です

明るさの調整によって画像を明るくしたり暗くしたりでき、コントラストの調整によって画像内の色の差や輪郭が強調されます

これらの調整は、一眼レフカメラで撮影した写真の品質を向上させるために役立ちます

はじめに

明るさとコントラストの調整は、画像処理において重要なステップです

画像の明るさとは、画像全体の明るさの程度を指し、コントラストとは画像の色や輪郭の差を表します

明るさとコントラストが適切でない場合、写真は暗く見えたり、色が薄くなったりしてしまいます

画像の明るさとコントラストを調整するための代表的なアルゴリズムには以下のようなものがあります

  • ガンマ補正: 画像の輝度値を非線形的に変換することで、明るさを調整します。ガンマ補正は特に暗い部分の明るさを引き出す効果があります。
  • ヒストグラム平坦化 : 画像の輝度値のヒストグラムを平坦化し、全体的なコントラストを向上させます。暗い部分と明るい部分の差が強調されます。
  • コントラストストレッチング : 画像の輝度値を入力範囲から出力範囲に変換することで、コントラストを拡張します。画像の輝度値が均等に分布するように調整されます。

初心者でも理解しやすいように、以下の記事ではガンマ補正、ヒストグラム平坦化、コントラストストレッチングをそれぞれ具体的な例を使いながら分かりやすく説明します

ガンマ補正

ガンマ補正は、画像の輝度値を非線形的に変換することで、明るさの調整を行う手法です

ガンマ補正は、カメラの撮影特性やディスプレイの表示特性を補正するためによく使われます

また、暗い領域の情報を引き出すことで、画像の見え方を改善することができます

ガンマ補正では、ガンマ値と呼ばれるパラメータを使います

ガンマ値が1より小さい場合、暗い領域の輝度が強調され、1より大きい場合は明るい領域の輝度が強調されます

具体的な手順としては、以下のようになります

  1. ガンマ値の選択 : ガンマ値を選択します。ガンマ値が1より小さい場合は暗く、1より大きい場合は明るくなります。
  2. 輝度値の変換 : 画像内の各ピクセルの輝度値をガンマ値に応じて変換します。変換式は、新しい輝度値 = 元の輝度値 ^ (1/ガンマ値) となります。
  3. 出力画像の作成 : 変換した輝度値を用いて、新しい画像を作成します。これがガンマ補正を行った後の画像です。

以下は、PythonのOpenCVライブラリを使ってガンマ補正を行う簡単な例です

import cv2
import numpy as np

# 画像の読み込み
image = cv2.imread("example.jpg")

# ガンマ値の選択
gamma_value = 1.5

# ガンマ補正
adjusted_image = np.power(image/255.0, gamma_value)
adjusted_image = (adjusted_image * 255).astype(np.uint8)

# ガンマ補正後の画像の表示
cv2.imshow("gamma correction", adjusted_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

ガンマ補正を行うことで、画像内の輝度値の分布が非線形的に変換され、暗い領域や明るい領域の情報が強調された画像を得ることができます

ヒストグラム平坦化

ヒストグラム平坦化は、画像の輝度値のヒストグラムを変更して、画像のコントラストを向上させる手法です

コントラストとは、画像内の色や輝度の差の強さを表します

ヒストグラムとは、画像内の輝度値の頻度分布をグラフで表したものです

例えば、ある画像において輝度値が0から255の範囲でほぼ同じ数だけ出現している場合、その画像はコントラストが低く、ぼんやりとした見た目になります

ヒストグラム平坦化は、このような均一でない輝度値の分布を調整し、より広い範囲に分布させることで、画像のコントラストを改善します

具体的な手順としては、以下のようになります

  1. グレースケール変換 : まず、対象となる画像をカラー画像からグレースケール画像に変換します。カラー情報はコントラストの調整には不要であり、グレースケール画像にすることで処理が簡単になります。
  2. ヒストグラムの計算 : グレースケール画像からヒストグラムを計算します。ヒストグラムは、輝度値ごとに画像内のピクセルの数をカウントして表したものです。
  3. 累積ヒストグラムの計算 : ヒストグラムをもとに累積ヒストグラムを計算します。累積ヒストグラムは、各輝度値までの累積ピクセル数を表したものです。
  4. 輝度値の変換 : 累積ヒストグラムをもとに、元の画像の輝度値を新しい値に変換します。変換は、累積ヒストグラムの値を0から255の範囲にスケーリングして行います。
  5. 出力画像の作成 : 変換した輝度値を用いて、新しい画像を作成します。これがヒストグラム平坦化を行った後の画像です。

以下は、PythonのOpenCVライブラリを使ってヒストグラム平坦化を行う簡単な例です

import cv2

# 画像の読み込み
image = cv2.imread("example.jpg")

# グレースケールに変換
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# ヒストグラム平坦化
hist_eq_image = cv2.equalizeHist(gray_image)

# ヒストグラム平坦化後の画像の表示
cv2.imshow("Histogram flattening", hist_eq_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

ヒストグラム平坦化を行うことで、画像内のコントラストが改善され、より明確な輪郭や色の差が強調された画像を得ることができます

コントラストストレッチング

コントラストストレッチングは、画像の輝度値を入力範囲から出力範囲に広げることで、画像のコントラストを強調する手法です

入力範囲とは画像内の輝度値の最小値から最大値までの範囲を指し、出力範囲は0から255までの範囲に設定されます

例えば、ある画像において輝度値が0から150の範囲に偏っている場合、画像は暗く見え、色の差も薄くなります

コントラストストレッチングは、このような範囲の偏りを修正して、画像のコントラストを改善します

具体的には、次のような手順で行われます

  1. 入力範囲の計算 : 画像内の最小値と最大値を求めて、入力範囲を特定します。
  2. スケーリングの計算 : 0から255までの出力範囲に対して、入力範囲を0から255に広げるためのスケーリング係数を計算します。
  3. 輝度値の変換 : 画像内の各ピクセルの輝度値に対して、スケーリング係数をかけて新しい輝度値に変換します。
  4. 出力画像の作成 : 変換した輝度値を用いて、新しい画像を作成します。これがコントラストストレッチングを行った後の画像です。

以下は、PythonのOpenCVライブラリを使ってコントラストストレッチングを行う簡単な例です

import cv2

# 画像の読み込み
image = cv2.imread("example.jpg")

# グレースケールに変換
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 入力範囲の計算
min_val, max_val, _, _ = cv2.minMaxLoc(gray_image)

# スケーリング係数の計算
a = 255 / (max_val - min_val)
b = -a * min_val

# コントラストストレッチング
stretched_image = cv2.convertScaleAbs(gray_image, alpha=a, beta=b)

# コントラストストレッチング後の画像の表示
cv2.imshow("contrast stretching", stretched_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

コントラストストレッチングを行うことで、画像内の色の差が強調され、よりはっきりとした画像を得ることができます

これらの手法を使って画像の明るさとコントラストを調整することで、一眼レフカメラで撮影した写真や他の画像をより美しく、魅力的に仕上げることができます

ぜひ、自分の写真にこれらの手法を試してみてください

おつー