この記事では、Pythonを使用して画像に対してさまざまな算術演算を実行する方法を学びます。
加算、減算、乗算、除算のようなさまざまな演算を行います。
画像の算術演算とはどういうことか?
画像演算とは、画像に対する算術演算のことです。
画像に対して何らかの算術演算を行う場合、必ず個々の画素の値に対して行われます。
例えば 例えば、画像に色がついている場合、以下のような加算が行われます。
f_img(i, j, k) = img1(i, j, k) + img2(i, j, k) or f_img(i, j, k) = img1(i, j, k) + constant |
グレースケール画像の場合、加算は次のように行われます。
f_img(i, j) = img1(i, j) + img2(i, j)
or f_img(i, j) = img1(i, j) + constant
|
同様に、他の算術演算も画像に対して行われます。
画像はNumPyのN次元配列として読み込まれるので、その上でさまざまな算術演算を行うのは非常に簡単です。
注意:複数の画像に対して演算を行う場合、すべての画像はjpeg, jpg, pngなどの同じタイプ、 *depth, dimensionsである必要があります。
Depth: 各画素を表現するためのビット数のことで、1チャンネル8ビットの画像を24ビットカラー画像(8ビット×3チャンネル)と呼ぶことが多い。
この記事もチェック:PythonとOpenCVを使って画像分割|二値化やグレースケールの変換等を解説
OpenCV を使って画像に算術演算を施す
まず,OpenCV-Python ライブラリをインストールし,Python プログラム内で cv2 モジュールをインポートする必要があります.以下は,OpenCV-Pythonのインストールとcv2モジュールのインポートのためのコマンドです.
# Installing OpenCV-Python library pip install opencv - python
|
# Importing cv2 module import cv2
|
1. 画像の加算
2枚の画像を足すか、画像に定数値を足すかのどちらかです。
画像の加算は、それ自体として有用な操作というよりも、いくつかの複雑な処理の中間段階としてよく使われます。
例えば、ある画像に適切なマスキングを施した後、別の画像を重ね合わせることができます。
画像の加算は、2つの方法で行うことができます。
- NumPyによる加算。NumPy Addition:これは、単に画像ファイルを読み込み、画像を読み込んだ後に返されるNumPyのN-d配列を(+)演算子で加算するものです。これはモジュロ演算で、入力(ロード)画像のピクセル値を加算した結果のピクセル値が255より大きい場合、結果のピクセル値を256(8ビット画像フォーマットの場合)でモジュロ(%)計算し、結果のピクセル値に代入して255以下、つまりどのピクセル値も255を超えられないようにすることを意味します。例:
250+10 = 260 => 260 % 256 = 4
。
# Reading image files img1 = cv2.imread( 'sample-img-1.jpg' )
img2 = cv2.imread( 'sample-img-2.jpg' )
# Applying NumPy addition on images fimg = img1 + img2
# Saving the output image cv2.imwrite( 'output.jpg' , fimg)
|
# Reading image files img1 = cv2.imread( 'sample-img-1.jpg' )
img2 = cv2.imread( 'sample-img-2.jpg' )
# Applying OpenCV addition on images fimg = cv2.add(img1, img2)
# Saving the output image cv2.imwrite( 'output.jpg' , fimg)
|
# Reading image files img1 = cv2.imread( 'sample-img-1.jpg' )
img2 = cv2.imread( 'sample-img-2.jpg' )
# Applying OpenCV subtraction on images fimg = cv2.subtract(img1, img2)
# Saving the output image cv2.imwrite( 'output.jpg' , fimg)
|
結果は以下の通りです。
# Reading image file img = cv2.imread( 'sample_img.jpg' )
# Applying NumPy scalar multiplication on image fimg = img * 1.5
# Saving the output image cv2.imwrite( 'output.jpg' , fimg)
|
OpenCVによる加算。
ここでは,単純に画像ファイルをロードし,ロード後に返される NumPy の N-d 配列を cv2.add()
メソッドに引数として渡します.これは飽和演算であり、入力(ロード)画像のピクセル値を加算した結果のピクセル値が255より大きい場合、どのピクセル値も255を超えないように255に飽和されます。
これを *saturation と呼びます。
例:250+10 = 260 => 255
。
**■■は画像処理の手法の一つで、画素のオーバーフローを処理するために、オーバーフローする画素を全て最大値に設定することです。
# Reading image file img = cv2.imread( 'sample_img.jpg' )
# Applying OpenCV scalar multiplication on image fimg = cv2.multiply(img, 1.5 )
# Saving the output image cv2.imwrite( 'output.jpg' , fimg)
|
結果は以下の通りです。
結果は以下の通りです。
# Reading image file img = cv2.imread( 'sample_img.jpg' )
# Applying OpenCV scalar division on image fimg = cv2.divide(img, 2 )
# Saving the output image cv2.imwrite( 'output.jpg' , fimg)
|
注:画像に対して様々な操作を行うには、常にOpenCVの関数を使用することをお勧めします。
なぜなら、上記の2つの例の出力から分かるように、より良い結果が得られるからです。
この記事もチェック:Pythonによる画像の強度変換操作 OpenCV
2. イメージサブトラクション
イメージサブトラクションは、2つの画像を入力とし、1つ目の画像のピクセル値から2つ目の画像の対応するピクセル値を引いただけのピクセル値を持つ3つ目の画像を出力とする、単純なピクセルサブトラクションです。
また、1つの画像を入力とし、そのすべてのピクセル値から定数値を引くこともできます。
この演算子のいくつかのバージョンでは、符号付きのストレートな出力ではなく、ピクセル値の差の絶対値を出力します。
画像の減算の実装は、出力画素値が負である場合にどうするかという点でさまざまです。
画像フォーマットがピクセルの負の値をサポートしている場合、その場合は負の値でも問題ありません。
画像フォーマットが負のピクセル値をサポートしていない場合、多くの場合、そのようなピクセルはゼロに設定されます(つまり、一般的に黒)。
画像減算が、同じ画素値型を使用する2つの入力画像の差の絶対値を計算する場合、出力画素値は入力画像の画素値型が表現しうる指定範囲外にはなりえないので、この問題は発生しない。
そのため、差分の絶対値を利用するのがよいのです。
ここでも2つの方法で画像減算を行うことができます。
NumPyの減算とOpenCVの減算です。
ここでは、より良い結果が得られ、広く利用されている OpenCV subtraction のみを使用します。
画像減算は、複雑な画像処理技術の中間段階として、またそれ自体も重要な操作として使用されます。
画像差分の最も一般的な使用方法は、前景のオブジェクトをより簡単かつ明確に分析できるように、背景の照明の変化をシーンから差分することです。
注:同じサンプル画像を画像減算にも使用する予定です。
# Reading image file img = cv2.imread( 'sample_img.jpg' )
# Applying NumPy scalar division on image fimg = img / 2
# Saving the output image cv2.imwrite( 'output.jpg' , fimg)
|
結果は以下の通りです。
この記事もチェック:PythonとOpenCVで画像の特徴量抽出・照合を実装する方法
3. 画像の乗算
画像に対する他の算術演算と同様に、画像の乗算も形態で実装することができる。
第1の画像乗算は、2つの入力画像を受け取り、画素値が入力画像の対応する画素値の積となる出力画像を生成します。
そして、第2の形態は、1つの入力画像を取り込み、各画素値が入力画像の対応する画素値と所定の定数(スケーリングファクター)との積となる出力を生成します。
この第2の形式の画像乗算はより広く使用されており、一般にスケーリングと呼ばれています。
画像のスケーリングにはいくつかの用途がありますが、一般にスケーリングファクターが単一より大きいと画像は明るくなり、単一より小さいと画像は暗くなります。
通常、スケーリングは画像の相対的なコントラストをよりよく保持するため、ピクセル値に単にオフセットを追加するよりもはるかに自然な明るさや暗さの効果を画像に生成します。
注:定数値は多くの場合浮動小数点数であり、これによって画像の強度を増減させることができる。
画像フォーマットがそれをサポートする場合、それは負になることができます。
もし、出力値が許容される最大ピクセル値より大きく計算されるなら、その最大許容ピクセル値で切り捨てられます。
以下に示すサンプル画像の明るさを増すために、NumPyの画像乗算を使用してみましょう。
結果は以下の通りです。
次に、通常2つの画像配列、または1つの画像配列と1つの定数を受け取る cv2.multiply()
メソッドを用いて、OpenCV の画像乗算を適用した場合のサンプル画像の変化を見てみましょう。
結果は以下の通りです。
4. 画像分割
画像分割は通常2枚の画像を入力とし、1枚目の画像の画素値を2枚目の画像の対応する画素値で割った画素値を持つ3枚目の画像を作成します。
この場合、画像の各ピクセル値は指定された定数で割られる。
除算は減算と同様に変化検出に使用できますが、ある画像から別の画像への各画素値の絶対変化を与える代わりに、対応する画素値間の分数変化または比率を与えることになります。
そのため、一般的に配給と呼ばれています。
ここでは, cv2.divide()
メソッド を用いて,上のサンプル画像の明るさを減少させるために画像の除算を行ってみましょう.
結果は以下の通りです。
また、以下のように NumPy の除算を使用して、上記のサンプル画像の明るさを減少させることもできます。
結果は以下の通りです。
まとめ
この記事では、画像に対してさまざまな算術演算を行う方法を学び、画像の算術演算に使用されるさまざまなOpenCVメソッドの動作を分析し、彩度、配給、スケーリングなど、これらの画像算術演算が使用される場所を学びました。