こんにちは!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言語で二値化処理!【サンプルプログラムあり】をご参考ください。 […]
[…] […]
[…] […]