210063x
@210063x (k k)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

グレースケール画像の各画素の輝度値を取得する方法

opencv python 初心者です。
 
RGB画像をグレースケールに変換した画像から、全画素の輝度値をそれぞれ画素ごとに取得して、1画素ごとに計算式に入れて処理
(画素ごとに一定の値になるようにガンマ補正をかけて、全画素で均一な輝度値の画像の作成)を行いたいのですが、なにかいい方法はあるでしょうか?
現在は、グレースケールで読み込み、画像サイズを取得するところまでしかできていません。 
宜しくお願い致します。

import cv2
import matplotlib.pyplot as plt
%matplotlib inline

img = cv2.imread('resize_img09940.jpg',0)
img_blur = cv2.GaussianBlur(img,(3,3),0)

height = img_blur.shape[0]
width = img_blur.shape[1]

for x in range(height):
    for y in range(width):

ご教授いただけると幸いです。
宜しくお願い致します。

0

3Answer

Pythonのforループは遅いので、以下のようにスライスとブロードキャストを利用して実装することをおすすめします。

Numpyが裏でチューンナップされたネイティブコードを走らせるので、下手にC言語などで実装するより高速になりますよ。

# RGB画像読み込み
# img.shape = (height, width, 3)
img = cv2.imread("Lenna.jpg")

# ガウシアンフィルタ
blur = cv2.GaussianBlur(img, (3,3), 0)

# float化 0~255 -> 0.0~1.0
blurf = blur.astype(np.float32) / 255.0

# グレイスケール化
# grayf.shape = (height, width)
grayf = 0.2126 * blurf[:, :, 2] + 0.7152 * blurf[:, :, 1] + 0.0722 * blurf[:, :, 0]

# ガンマ補正
gamma = 2.0
grayf_gamma = grayf ** (1.0/gamma)

# 整数化 0.0~1.0 -> 0~255
gray_gamma = (grayf_gamma * 255).astype(np.uint8)

2Like

Comments

  1. 申し訳有りません、グレイスケール化の式が間違っていたため先程修正しました。
    (OpenCVではRGBではなくBGRの順で値が格納されていたため、RとBの係数が逆になっていました)

こんにちは.
もしご質問内容を正確に把握できていなかったらすみません.

ご自分で作られたガンマ補正の式があって,その式に各画素値を代入して画像全体にガンマ補正をかけたいという認識で回答いたします.

まず,画像は基本的に2次元配列とかでできているので,opencvを用いている場合ですと,以下のようになります.

main.py
#画像imgにおける座標(x, y) = (2, 3)の画素値
pixel = img[3, 2] 

したがって,質問者様のコードに適用すると

main.py
import cv2

img = cv2.imread('resize_img09940.jpg',0)
img_blur = cv2.GaussianBlur(img,(3,3),0)

height = img_blur.shape[0]
width = img_blur.shape[1]

for x in range(height):
    for y in range(width):
        #pixelという変数に各画素値を取り出す
        pixel = img_blur[y, x]

        #以下,何らかの処理

img_bulrをそのまま書き換えるなら,

img_bulr[y, x] = #何かの値,画素値を返す関数

でいいと思います.

1Like

なお、単純に画像の輝度値を全画素で同じ値にしたい場合は、読み込んだ画像の色空間をRGBからHLS(もしくはHSV)に変換し、輝度(HSVの場合は明度)を同じ値で上書きしてからRGBに変換すればよいかと思います。

色空間についてはWikipedia等をご参照下さい。

# RGB画像読み込み
# img.shape = (height, width, 3)
img = cv2.imread("Lenna.jpg")

# float化
imgf = img.astype(np.float32) / 255.0

# 色空間をHLSに変換
hls = cv2.cvtColor(imgf, cv2.COLOR_BGR2HLS)

# 全画素の輝度を同じ値に変更
hls[:, :, 1] = 0.5

# 色空間をRGBに変換
resultf = cv2.cvtColor(hls, cv2.COLOR_HLS2BGR)

# 整数化 0.0~1.0 -> 0~255
result = (resultf * 255).astype(np.uint8)

輝度値のみにガンマ補正をかけたい場合は、以下のような実装になるかと思います。


# 輝度値にガンマ補正を掛ける
gamma = 2.0
hls[:, :, 1] = hls[:, :, 1] ** (1.0 / gamma)

1Like

Comments

  1. @210063x

    Questioner

    なるほど、、そのような方法は知らなかったため、とても参考になりました。ありがとうございます。

Your answer might help someone💌