Pythonの学習の過程とか

学習の記録をつけておきましょう。Python3に少しずつ移行していきます。過去の記事のソースを2から3に、、、と考えましたが、新しいことをやったほうがいいですね。

Python OpenCVの基礎 LUTで画像の暗部を持ち上げてみる

LUTを使って画像の暗部を持ち上げてみる

夕方に撮影したこんな感じのちょっと暗い画像があります

この写真に手を加えてみたいと思います

加工前の画像

f:id:PeaceAndHiLight:20160203224223j:plain

加工後の画像

f:id:PeaceAndHiLight:20160203224230j:plain

こんな感じに変わります。

人影や車など、暗くて見えなかった部分がハッキリ見れるようになりましたね。

ソース

ガンマを1.8に設定してガンマテーブルを作ってみました。

ガンマテーブルを作る

lookUpTable = np.zeros((256, 1), dtype = 'uint8')

for i in range(256):
    lookUpTable[i][0] = 255 * pow(float(i) / 255, 1.0 / gamma)

まずは0うめの256の配列を作り、0から255までの値を計算して配列に入れています。

難しいと感じられましたら、ガンマとは何かを調べてみるといいと思います。

ガンマ曲線の確認をしてみよう

import csv

#中略

f = open('data.csv', 'ab')

csvWriter = csv.writer(f)

val = 0

for i in range(256):
    listData = []
    listData.append(i)
    listData.append(lookUpTable[i][0])
    csvWriter.writerow(listData)

f.close()

グラフ化してみた

f:id:PeaceAndHiLight:20160204234234p:plain

そこそこ緩やかなカーブですね。

ところでこのグラフは、上記のガンマテーブルをCSVとして出力してアップル謹製のNumbersで作りました。

実はNumbersを使ったのは初めてなのですが、、、

正直にもうしまして、エクセルの方がはるかに使いやすい次第です。申し訳ありません。 Numbersを使う機会はもうないかもしれないですねー

cv2.LUTで適用する

さて、本題に戻りましてガンマテーブルを適用させます。

img_src = cv2.imread('image.jpg', 1)

img_gamma = cv2.LUT(img_src, lookUpTable)

cv2.imwrite('lutImage.jpg', img_gamma)

割りと難しそうなことをやりましたが、ソースはシンプルだし、理解しやすいと思います。

画像の中の暗い部分が、少しずつ明るくなった

ということがわかるとお思います。もう一度画像を比べてみてくださいね!

結局LUTで何をしたのか?

ただ「明るくなりました!」だけでは物足りないので、もう少し踏み込んでみましょう。 画像的には、LUT適用の前後でどのように変化しているのか?

明るくなっているのだから、きっと輝度に変化があったのでしょう。 ということなので、両者の輝度を比較してみたいと思います。

輝度を比較してみる

こんな感じで比較しましょう。

  1. 画像をBGRからYCrCbに変換する
  2. Yのヒストグラムを比較してみる
  3. Cr,Cbも比較してみる

グラフ表示は、今回はpylabに任せます。Numbersはもう使わない!

#coding: utf-8

import cv2
import pylab as plt

imgOrg = cv2.imread('Org.jpg', 1)
imgLut = cv2.imread('LUT.jpg', 1)

#BGRをYCrCbに変換します
orgYCrCb = cv2.cvtColor(imgOrg, cv2.COLOR_BGR2YCR_CB)
lutYCrCb = cv2.cvtColor(imgLut, cv2.COLOR_BGR2YCR_CB)

#輝度のヒストグラムを作成
histOrgY = cv2.calcHist([orgYCrCb], [0], None, [256], [0, 256])
histLutY = cv2.calcHist([lutYCrCb], [0], None, [256], [0, 256])

#ヒストグラムの表示
plt.plot(histOrgY)
plt.plot(histLutY)
plt.xlim([0, 256])
plt.show()

cv2.calcHistで画像のヒストグラムを作ってくれます。便利ですね。

calcHist

cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]]) 

channelsに輝度であるYを指定し、マスクはなし、サイズを256にして、範囲も指定します。簡単ですね。 CrCbを比較したい時には、channelsにそれぞれ1,2を入れればよいと思います。

で、出来たのがコチラ

Yの比較

f:id:PeaceAndHiLight:20160204234610p:plain

青がオリジナル画像の輝度、緑がLUT画像の輝度です。 暗い部分に集中していた要素が、全体的に上に持ち上がっています。

Cr, Cbの比較

Cb

f:id:PeaceAndHiLight:20160205003827p:plain

Cr

f:id:PeaceAndHiLight:20160205003842p:plain

ほとんど変化がありませんね。

ということは、LUTでは輝度が大きく変わったということがいえます。

今回参考にしたのはコチラです。

参考にさせていただきました。ありがとうございます。大変勉強になりました。

blog.umentu.work

tatabox.hatenablog.com