こんにちは!zhackです。
先日、以下の画像処理に関する記事を掲載いたしました。
今回は、それを実際にプログラムで再現してみました。
利用したプログラム言語は、現在勉強中のGo言語です!
画像処理業界ではおなじみのLena画像を用いて、
二値化処理について、今回は説明していきます。
前提
実行環境
今回の実行環境は以下の通りです。
- Debian GNU/Linux8
※Dockerコンテナで環境構築 - プログラム名称:binary.go
- 入力データ:lena.jpg
- 実行コマンド
$ go run プログラム名 < 入力画像のパス > 出力画像のパス 今回の場合は $ go run binary.go < lena.jpg > binary.jpg
- Gitにも掲載しています。ご参考まで。
Dockerの環境構築及び、Go言語の開発環境構築については以下の記事に記載しています。
プログラムのひな型
今回実装したプログラムのひな型を紹介します。
package main // 必要なライブラリのインストール import ( "image" "image/color" "image/jpeg" "os" ) // メイン関数 func main() { // 入力データの読み込み img, _ := jpeg.Decode(os.Stdin) // 入力データを走査するデータの作成 bounds := img.Bounds() // 出力用の入れ物を作成 dest := image.NewRGBA(bounds) // 画像を1ピクセルずつ走査 for y := bounds.Min.Y; y < bounds.Max.Y; y++ { for x := bounds.Min.X; x < bounds.Max.X; x++ { // ピクセルの取得 curPixel := img.At(x, y) // ピクセルから色情報RGBA(16bit)を取得 r ,g ,b, a := curPixel.RGBA() // 色情報16bitを8bitの形式に変換 r, g, b, a = r>>8, g>>8, b>>8, a>>8 // (1) 必要な処理 } } // 処理結果を画像形式で出力 err := jpeg.Encode(os.Stdout, dest, nil) if err != nil { panic("Failed to encode JPEG gradient image.") } }
上記、プログラムにおける“(1) 必要な処理”と書いているところに二値化処理ようのコードが入ります。
一点、Go言語のImageパッケージを用いたときの色情報の取得方法について説明します。
At関数で画素を取得した後、RGBA関数で色情報を取得することができます。
しかし、これで得られる色情報は16bitで表現された色情報になります。
先日の記事では、0~255までの数値で各RGBAの値が表現されていると述べましたが、ここではそうではありません。
そのため、ここで取得した値を確認しても60352だとか、ものすごく大きな値になります。
そこで、8bitの色情報で変換してあげましょう。
今回は簡単に16bitの色情報のうち、下位8bitを落としました。
16bitの色情報を8bit右にシフトし、8bitに変換する。 (例) ()内は10進数表記のときの値 16bitの色情報:1111110000111101 (64573) ↓ 8bitの色情報:0000000011111100 (252)
Go言語で二値化処理
プログラム
各ピクセルの値の平均値を算出し、その平均値が閾値以上であれば白、閾値より小さい値の場合は黒としました。
閾値の設定は、ループ外のどこかに配置してください。
// 閾値の設定 threshold := 120
// (1) 必要な処理 // 平均値の計算 mean := ( r + g + b ) / 3 if uint8(mean) >= uint8(threshold) { // 閾値以上の為、白をセット col := color.RGBA{R: uint8(255), G: uint8(255), B: uint8(255), A: uint8(0)} dest.Set(x, y, col) } else { // 閾値より小さいため、黒をセット col := color.RGBA{R: uint8(0), G: uint8(0), B: uint8(0), A: uint8(0)} dest.Set(x, y, col) }
出力結果
出力結果はこのような感じです。
閾値が120の場合は、上記のような結果ですが、例えば閾値を50にした場合、ほとんどの画素が閾値以上となるため、白い領域が増えます。
さいごに
先日紹介した二値化処理について、Go言語で実装してみました。
しかしただ単純に二値化処理を行うだけだと、ノイズものっていますね。
また、色の濃淡を知りたいときもあるかもしれません。
今後、この画像処理シリーズはいくつか掲載する予定です。
よろしくお願いいたします。
ではでは!
コメント
[…] 先日画像処理に関する記事を掲載し、これに関して、Go言語で二値化処理したプログラムについて紹介しました。 […]
[…] Go言語のImageパッケージを用いたときの色情報の取得方法については、【画像処理】Go言語で二値化処理!【サンプルプログラムあり】をご参考ください。 […]
[…] Go言語のImageパッケージを用いたときの色情報の取得方法については、【画像処理】Go言語で二値化処理!【サンプルプログラムあり】をご参考ください。 […]
[…] […]
[…] […]