OpenCV 4.13.0
Open Source Computer Vision
読み込み中...
検索中...
見つかりません
🤖 AIによる機械翻訳(非公式) — これは OpenCV 4.13.0 公式リファレンス(英語)を AI (Claude) で自動翻訳したものです。訳に誤りを含む場合があります。正確な情報は 公式英語版(原文) を参照してください。
画像のコントラストと明るさを変える!

前のチュートリアル: OpenCVを使った2枚の画像の加算(ブレンディング)
次のチュートリアル: 離散フーリエ変換

原著者Ana Huamán
互換性OpenCV >= 3.0

目標

このチュートリアルでは、以下の方法を学ぶ:

  • ピクセル値にアクセスする
  • 行列をゼロで初期化する
  • cv::saturate_cast が何を行い、なぜ便利なのかを学ぶ
  • ピクセル変換に関する有用な情報を得る
  • 実践的な例で画像の明るさを改善する

理論

覚え書き
以下の説明は、Richard Szeliski 著の書籍 Computer Vision: Algorithms and Applications によるものである

画像処理

  • 一般的な画像処理演算子とは、1枚以上の入力画像を受け取り、1枚の出力画像を生成する関数である。
  • Image transforms can be seen as:
    • 点演算子(ピクセル変換)
    • 近傍(領域ベース)演算子

ピクセル変換

  • この種の画像処理変換では、各出力ピクセルの値は対応する入力ピクセルの値のみに依存する(加えて、場合によってはグローバルに収集された情報やパラメータに依存する)。
  • このような演算子の例には、明るさとコントラストの調整のほか、色補正や色変換が含まれる。

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

  • よく使われる2つの点処理は、定数による乗算加算である:

    \[g(x) = \alpha f(x) + \beta\]

  • パラメータ \(\alpha > 0\) と \(\beta\) はしばしばゲイン (gain) およびバイアス (bias) パラメータと呼ばれる。これらのパラメータはそれぞれコントラスト明るさを制御するとも言われることがある。
  • \(f(x)\) を入力画像のピクセル、\(g(x)\) を出力画像のピクセルと考えることができる。すると、この式はより便利に次のように書ける:

    \[g(i,j) = \alpha \cdot f(i,j) + \beta\]

    ここで \(i\) と \(j\) は、ピクセルがi 行目j 列目に位置することを示す。

コード

解説

  • cv::imread を使って画像を読み込み、Mat オブジェクトに保存する:
  • Now, since we will make some transformations to this image, we need a new Mat object to store it. Also, we want this to have the following features:
    • 初期ピクセル値はゼロに等しい
    • 元の画像と同じサイズおよび型

cv::Mat::zerosimage.size()image.type() に基づく Matlab スタイルのゼロ初期化子を返すことがわかる

  • 次に、\(\alpha\) と \(\beta\) の値をユーザーに入力してもらう:
  • ここで、演算 \(g(i,j) = \alpha \cdot f(i,j) + \beta\) を実行するため、画像内の各ピクセルにアクセスする。BGR 画像を扱っているため、ピクセルごとに3つの値(B, G, R)があり、それらにも個別にアクセスする。以下がコードの一部である:

以下に注意すること(C++ コードのみ):

  • 画像内の各ピクセルにアクセスするには、次の構文を使用する:image.at<Vec3b>(y,x)[c]。ここで y は行、x は列、c は B, G, R(それぞれ 0, 1, 2)である。
  • 演算 \(\alpha \cdot p(i,j) + \beta\) は範囲外の値や(\(\alpha\) が浮動小数点の場合)整数でない値を返すことがあるため、値が有効であることを保証するために cv::saturate_cast を使用する。
  • 最後に、いつもの方法でウィンドウを作成し、画像を表示する。
覚え書き
各ピクセルにアクセスするために for ループを使う代わりに、単にこのコマンドを使うこともできた:

ここで cv::Mat::convertTo は実質的に *new_image = a*image + beta* を実行する。しかし、ここでは各ピクセルへのアクセス方法を示したかった。いずれにせよ、両方の方法は同じ結果を与えるが、convertTo の方がより最適化されており、はるかに高速に動作する。

結果

  • \(\alpha = 2.2\) と \(\beta = 50\) を使ってコードを実行する
    $ ./BasicLinearTransforms lena.jpg
    Basic Linear Transforms
    -------------------------
    * Enter the alpha value [1.0-3.0]: 2.2
    * Enter the beta value [0-100]: 50
  • 次の結果が得られる:

実践的な例

この段落では、これまで学んだことを実践し、画像の明るさとコントラストを調整して露出不足の画像を補正する。また、画像の明るさを補正する別の手法であるガンマ補正についても見ていく。

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

\(\beta\) の値を増加(/減少)させると、すべてのピクセルに一定の値が加算(/減算)される。[0 ; 255] の範囲外のピクセル値は飽和(saturate)する(すなわち、255(/0)より大きい(/小さい)ピクセル値は 255(/0)にクランプされる)。

In light gray, histogram of the original image, in dark gray when brightness = 80 in Gimp

ヒストグラムは、各カラーレベルについて、そのカラーレベルを持つピクセルの数を表す。暗い画像では低いカラー値を持つピクセルが多くなり、その結果、ヒストグラムは左側にピークを示す。一定のバイアスを加算すると、すべてのピクセルに一定のバイアスを加算したことになるため、ヒストグラムは右側にシフトする。

\(\alpha\) パラメータはレベルの広がり方を変化させる。\( \alpha < 1 \) の場合、カラーレベルは圧縮され、結果としてコントラストの低い画像になる。

In light gray, histogram of the original image, in dark gray when contrast < 0 in Gimp

これらのヒストグラムは Gimp ソフトウェアの明るさ・コントラストツールを使って取得したものである点に注意。明るさツールは \(\beta\) バイアスパラメータと同一であるはずだが、コントラストツールは \(\alpha\) ゲインとは異なるように見え、Gimp では出力範囲が中央に揃えられているようである(前のヒストグラムで気づけるように)。

\(\beta\) バイアスを調整すると明るさは改善するが、同時にコントラストが低下するため、画像にわずかなベールがかかったように見えることがある。この効果を弱めるために \(\alpha\) ゲインを使用できるが、飽和のために、元々明るかった領域では細部の一部が失われる。

ガンマ補正

ガンマ補正は、入力値とマッピングされた出力値の間の非線形変換を用いて画像の明るさを補正するために使用できる:

\[O = \left( \frac{I}{255} \right)^{\gamma} \times 255\]

この関係は非線形であるため、その効果はすべてのピクセルで同じにはならず、各ピクセルの元の値に依存する。

Plot for different values of gamma

\( \gamma < 1 \) の場合、元々暗かった領域がより明るくなり、ヒストグラムは右側にシフトする。一方、\( \gamma > 1 \) の場合は逆になる。

露出不足の画像を補正する

次の画像は \( \alpha = 1.3 \) と \( \beta = 40 \) で補正したものである。

By Visem (Own work) [CC BY-SA 3.0], via Wikimedia Commons

全体的な明るさは改善されたが、使用した実装の数値的な飽和(写真におけるハイライトのクリッピング)のために、雲が大きく飽和していることに気づくだろう。

次の画像は \( \gamma = 0.4 \) で補正したものである。

By Visem (Own work) [CC BY-SA 3.0], via Wikimedia Commons

ガンマ補正はマッピングが非線形であり、前の手法のような数値的飽和が起こり得ないため、飽和効果が少なくなる傾向がある。

Left: histogram after alpha, beta correction ; Center: histogram of the original image ; Right: histogram after the gamma correction

前の図は3枚の画像のヒストグラムを比較したものである(3つのヒストグラムの間で y 軸の範囲は同じではない)。元の画像では、ほとんどのピクセル値がヒストグラムの下部にあることに気づくだろう。\( \alpha \), \( \beta \) 補正の後では、飽和による 255 での大きなピークと右側へのシフトが観察できる。ガンマ補正の後では、ヒストグラムは右側にシフトするが、暗い領域のピクセルの方が明るい領域のピクセルよりも大きくシフトしている(ガンマ曲線のを参照)。

このチュートリアルでは、画像のコントラストと明るさを調整する2つの簡単な手法を見てきた。これらは基本的な手法であり、ラスターグラフィックスエディタの代替として使用することを意図したものではない!

コード

ガンマ補正のコード:

計算の性能を向上させるためにルックアップテーブルが使用されている。256個の値を一度だけ計算すればよいためである。

追加リソース