画像変換
画像変換とは、元の画像行列を関数で処理した後にターゲット画像行列に変換する関数を見つけることです。
ピクセルレベルの変換と領域レベルの変換の 2 つの方法に分けることができます。
- ポイント演算子 (ピクセル変換)
- 近隣(エリアベース)オペレーター
ピクセルレベルの変換は、変換後の各ピクセル値が、変換前の同じ位置のピクセル値と関数マッピング関係を持つことと同等です。
線形変換
最も一般的に使用されるのは線形変換です。つまり、
f(i, j) は元のピクセル値であり、g(i, j) は変換されたピクセル値です。
α はコントラストを調整し、β は明るさを調整します。ゲインおよびバイアス パラメータと呼ばれることもあります。
コントラストと明るさ
コントラストとは何ですか? それは「明暗の差」ではないでしょうか?つまり、画素値の大きさの違いです。これにアルファ係数を掛けて、アルファが大きいと明るさの差が大きくなり、コントラストが良くなり、アルファが小さいと明るさの差が小さくなり、コントラストが高くなります。削減。
ベータについてはよく理解されています。ピクセルの輝度値に数値を直接加算します。正の数値は輝度を増加させ、負の数値は輝度を減少させます。
以下のコードの例を見てください。
from __future__ import print_function
from builtins import input
import cv2 as cv
import numpy as np
import argparse
# Read image given by user
parser = argparse.ArgumentParser(description='Code for Changing the contrast and brightness of an image! tutorial.')
parser.add_argument('--input', help='Path to input image.', default='lena.jpg')
args = parser.parse_args()
image = cv.imread(cv.samples.findFile(args.input))
if image is None:
print('Could not open or find the image: ', args.input)
exit(0)
new_image = np.zeros(image.shape, image.dtype)
alpha = 1.0 # Simple contrast control
beta = 0 # Simple brightness control
# Initialize values
print(' Basic Linear Transforms ')
print('-------------------------')
try:
alpha = float(input('* Enter the alpha value [1.0-3.0]: '))
beta = int(input('* Enter the beta value [0-100]: '))
except ValueError:
print('Error, not a number')
# Do the operation new_image(i,j) = alpha*image(i,j) + beta
# Instead of these 'for' loops we could have used simply:
# new_image = cv.convertScaleAbs(image, alpha=alpha, beta=beta)
# but we wanted to show you how to access the pixels :)
for y in range(image.shape[0]):
for x in range(image.shape[1]):
for c in range(image.shape[2]):
new_image[y,x,c] = np.clip(alpha*image[y,x,c] + beta, 0, 255)
cv.imshow('Original Image', image)
cv.imshow('New Image', new_image)
# Wait until user press some key
cv.waitKey()
実行: python change_brightness_contrast.py --input ./lights.jpeg
上の図は、alpha=2、beta=20 のレンダリングです。
非線形変換
線形変換には問題があり、上の図に示すように、α=1.3、β=40 では、元の画像の明るさが増加しますが、雲はほとんど見えなくなります。雲を見たい場合は建物の明るさが足りません。
このとき、ガンマ補正と呼ばれる非線形変換が導入されます。
線形変換とは異なり、変化の強さは元の輝度値によって異なり、非線形です。
γ<1の場合、画像の明るさは増加します。>1 の場合、明るさを下げます。
γ=0.4の変形効果図は上記の通りです。コントラストを維持しながら雲や建物が明るくなり、鮮明な画像が得られていることがわかります。
さまざまな変換を行ったグレースケール ヒストグラムを見るとそれがわかります。中央は元の画像のグレースケール ヒストグラムで、輝度値の低いピクセルが多数あることがわかります。
左側が線形変換され、ヒストグラム全体が右にシフトし、255 にピークが現れます。各ピクセルの明るさが増加するためです。その結果、白い雲と青い空は明るすぎて区別できません。
右側のガンマ補正画像は比較的均一な輝度分布となっており、輝度値の低い部分を強調することができますが、白雲が判別できないほど白飛びすることはありません。
ガンマ補正を実装するコードは次のとおりです。
lookUpTable = np.empty((1,256), np.uint8)
for i in range(256):
lookUpTable[0,i] = np.clip(pow(i / 255.0, gamma) * 255.0, 0, 255)
res = cv.LUT(img_original, lookUpTable)
ここで、cv.LUT は変換関数です。lookUpTable から変換関係を見つけて、新しい画像行列を生成します。