【Excel】VBAで画像処理。画像の色調補正をする
今回は、VBAで画像のコントラスト補正をおこないます。
Excel上へ画像の展開の詳細はこの記事↓を見てください!
tsunakan97.hatenablog.com
線形な色調補正とS字を描く非線形な色調補正を行います。
線形な色調補正
a1=0.2, a2=0.8, a3=0.1, a4=0.9
横軸が元の画像の画素値で、縦軸が補正後の画素値になります。
255×a1より小さい画素値はすべて255×a3にして、255×a2より大きい画素値はすべて255×a4にします。そしてa1とa2の間は、直線でつなげて画素値とします。
'画像の線形変換!! Function ToneMapping(image() As Byte, a1 As Double, a2 As Double, a3 As Double, a4 As Double) Dim c As Long, r As Long, color As Long Dim rMax As Long, cMax As Long rMax = UBound(image, 2) cMax = UBound(image, 1) Dim image2() As Double ReDim image2(cMax, rMax, 2) For r = 0 To rMax For c = 0 To cMax For color = 0 To 2 image2(c, r, color) = image(c, r, color) / 255 Next Next Next Dim myScale As Double Dim x As Double, xNew As Double myScale = (a4 - a3) / (a2 - a1) For r = 0 To rMax For c = 0 To cMax For color = 0 To 2 x = image(c, r, color) / 255 If x < a1 Then xNew = a3 ElseIf a2 < x Then xNew = a4 Else xNew = myScale * (x - a1) + a3 End If image(c, r, color) = xNew * 255 Next Next Next End Function
非線形な色調補正
S字のカーブを作り、中心より暗い画素はより暗く、中心より明るい画素はより明るくします。メリハリがつき、はっきりとした画像になります。
今回はS字をつくるのに、正規分布の確率密度関数を積分することで得た関数を使います。
補正前後のヒストグラム(画素値の出現頻度)です。補正後のほうが山が左右に広がっており、暗い部分はより暗く、明るい部分はより明るくなっています
画素ごとに毎回計算を行っていると時間がかかるので、先に返還後の画素値を格納したルックアップテーブルを作成して、参照するようにします。
'S字のトーンカーブ(正規分布確率密度関数の積分) 'による非線形濃度変換 Function ToneMapping3(image() As Byte) Dim c As Long, r As Long, color As Long Dim x As Byte Dim rMax As Long, cMax As Long rMax = UBound(image, 2) cMax = UBound(image, 1) Dim table(255) As Double, tabledx(255) As Double, table255(255) As Byte Dim i As Long Dim a1 As Double, a2 As Double, a3 As Double, a4 As Double, myScale As Double 'tableを-3から3で正規化 '±3SDの正規分布を積分するため a1 = 0 a2 = 255 a3 = -3 a4 = 3 myScale = (a4 - a3) / (a2 - a1) For i = 0 To 255 table(i) = myScale * (i - a1) + a3 Next 'tableを正規分布の確率密度関数で計算 For i = 0 To 255 table(i) = (1 / Sqr((2 * 3.1416))) * Exp(-(table(i) ^ 2 / 2)) Next 'tableを積分してtabledxに代入 For i = 0 To 255 If i = 0 Then tabledx(i) = 0 Else tabledx(i) = tabledx(i - 1) + table(i) End If Next 'tabledxから画素値置換用のルックアップテーブルtable255を求める a1 = 0 a2 = tabledx(255) a3 = 0 a4 = 255 myScale = (a4 - a3) / (a2 - a1) For i = 0 To 255 table255(i) = CByte(myScale * (tabledx(i) - a1) + a3) Next 'image()をtable255で濃度変換 For r = 0 To rMax For c = 0 To cMax For color = 0 To 2 x = image(c, r, color) image(c, r, color) = table255(x) Next Next Next End Function
以下、全ソース。
Excelで画像の色調補正