GoCVでガンマ補正してみた
こんにちは、わたる です。
初めに
GoCVを使ったガンマ補正のサンプルプログラムを探してみたのですが、自分の検索能力が低かったせいか見つからなかったので作ってみました。
考え方
GoCV、否、OpenCVにも言えることと思いますが、ガンマ補正を行うAPIは存在しませんので、変換式をCVのLUP(LookUpTable)の仕組みを用意して変換をかける方法です。
ガンマ補正の変換式
探すと色々と出てくると思いますが、入力の
この変換式をそのまま0~255の出力のLUTを作って入力の値から変換させればよい…という考え方になります。
GoCVのセットアップ
前回の拙記事をご参照ください。
プログラムソース
package main
import (
"fmt"
"os"
"math"
"gocv.io/x/gocv"
"strconv"
)
func main() {
if len(os.Args) < 3 {
fmt.Printf("How to run:\n\tgamma gamma_value imgfile")
fmt.Printf("Ex) gamma 1.5 sample.png")
return
}
arg_str_gamma := os.Args[1]
gamma, err := strconv.ParseFloat(arg_str_gamma, 64)
if err != nil {
fmt.Printf("Error gamma value: %v\n", arg_str_gamma)
return
}
arg_str_filename := os.Args[2]
img := gocv.IMRead(arg_str_filename, gocv.IMReadColor)
if img.Empty() {
fmt.Printf("Error reading image from: %v\n", arg_str_filename)
return
}
str_after := fmt.Sprintf("after gamma:%v", gamma)
window := gocv.NewWindow("before")
window_2 := gocv.NewWindow(str_after)
window.IMShow(img)
img_gamma := myGamma_conversion(img, gamma)
defer img_gamma.Close()
for {
window_2.IMShow(img_gamma)
if window_2.WaitKey(1) >= 0 {
break
}
}
}
func myGamma_conversion(src gocv.Mat, gamma float64) gocv.Mat {
gamma_cvt := gocv.NewMatWithSize(256, 1, gocv.MatTypeCV8U)
for r := 0 ; r < 256 ; r++ {
gamma_element := 255.0 * math.Pow(float64(r)/255.0, 1.0/gamma)
gamma_cvt.SetUCharAt(r, 0, uint8(gamma_element))
}
ret_gamma := src.Clone()
gocv.LUT(src, gamma_cvt, &ret_gamma)
return ret_gamma
}
変換テーブルを作っているのは
for r := 0 ; r < 256 ; r++ {
gamma_element := 255.0 * math.Pow(float64(r)/255.0, 1.0/gamma)
gamma_cvt.SetUCharAt(r, 0, uint8(gamma_element))
}
この箇所で、
LUTとして変換しているのは
gocv.LUT(src, gamma_cvt, &ret_gamma)
この箇所です。
プログラム引数の2つ目をガンマ値、3つ目を入力ファイルとして設定していますので、例えば、
$ go run gamma.go 1.5 samplg.png
のように動作することでガンマ補正前後の画像を表示するようにしています。[1]
ガンマ補正値を1.5した出力結果は下記です。
※画像は「あの」レナ様です。
ガンマ値を1.5としたときの出力結果
サンプルのガンマ値を0.667にした出力結果は下記です。
ガンマ値を0.667としたときの出力結果
ガンマ値が1より大きいと明るく、1より小さいと暗く変換するのが分かるかと思います。
まとめ
今回はGoCVを使ったガンマ補正のプログラムを作ってみました。
この記事も前回と同様qiitaからの転載[2]になりますが、他にもヒストグラムを作ってみたので、またこれも転載するとともに、新たに他の画像変換やgolangのプログラムも作ってみてアップしたいと思います。
Discussion