こんにちは!zhackです。
Go言語で画像処理シリーズ第3弾!
今回は、エッジ検出について説明していきます。
先日、フィルタ処理に関する記事を掲載しました。
その中の輪郭抽出である、X方向及びY方向の微分について、実装してみました。
前提
実行環境
今回の実行環境は以下の通りです。
- Debian GNU/Linux8
※Dockerコンテナで環境構築 - プログラム名称:edge_x.go, edge_y.go
- 入力データ:zukei.jpg
- 実行コマンド
$ go run プログラム名 < 入力画像のパス > 出力画像のパス 今回の場合は $ go run edge_x.go < zukei.jpg > zukei_x.jpg もしくは $ go run edge_y.go < zukei.jpg > zukei_y.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++ { // (1) 必要な処理 } } // 処理結果を画像形式で出力 err := jpeg.Encode(os.Stdout, dest, nil) if err != nil { panic("Failed to encode JPEG gradient image.") } }
上記、プログラムにおける“(1) 必要な処理”と書いているところにエッジ検出用のコードが入ります。
Go言語のImageパッケージを用いたときの色情報の取得方法については、二値化処理に関する以下の記事に記載していますので、そちらをご参考ください。
Go言語でX方向、Y方向の微分処理
フィルタの説明
今回扱うフィルタは、このようなフィルタになります。
濃い黄色になっているところが、注目画素です。
X方向の微分について、注目画素とその左側の画素以外には0が入っています。
そのため、処理後の画素に入る数値は、
(処理後の画素に入る値) = (注目画素の値) - (注目画素の左側の画素の値)
になりますね。
Y方向の微分については、以下のようになります。
(処理後の画素に入る値) = (注目画素の値) - (注目画素の上側の画素の値)
では、これを実際にプログラムにしてみましょう。
プログラム
上記、(1)必要な処理の部分に以下のコードを入力します。
// 注目画素のRGB値を取得 curPixel := img.At(x, y) r, g, b, a := curPixel.RGBA() r, g, b, a = r>>8, g>>8, b>>8, a>>8 // 注目画素の左側の画素のRGB値を取得 curLeftPixel := img.At(x-1, y) r_l, g_l ,b_l, a_l := curLeftPixel.RGBA() r_l, g_l, b_l, a_l = r_l>>8, g_l>>8, b_l>>8, a_l>>8 // 画素の計算 rValue := r - r_l gValue := g - g_l bValue := b - b_l aValue := a - a_l // 0未満の場合は0に、255より大きい場合は255にする if rValue < 0{ rValue = 0} if rValue > 255 { rValue = 255} if gValue < 0{ gValue = 0} if gValue > 255 { gValue = 255} if bValue < 0{ bValue = 0} if bValue > 255 { bValue = 255} if aValue < 0{ aValue = 0} if aValue > 255 { aValue = 255} // 計算したものを出力画像としてセット col := color.RGBA{R: uint8(rValue), G: uint8(gValue), B: uint8(bValue), A: uint8(aValue)} dest.Set(x, y, col)
出力結果
上記のプログラムを実行するとこのようになります。
すこし、ノイズが載っていますが、x方向の微分を行うことができました。
正方形の辺がy方向の辺のみ抽出できていますね。
これは、注目画素とその左側の画素の差をとっている為、x方向の辺上の画素が0になってしまったことが原因です。
Y方向の微分はどのようなプログラムになるのでしょうか。
実際に試してみてください!
さいごに
Go言語で画像処理を行うシリーズ第三弾として、エッジ検出 X方向の微分及びY方向の微分を紹介しました。
結構シンプルな処理で実現できましたが、ノイズがのってしまいました。
いつか、このノイズを取る方法も説明しますね!
ではでは!
コメント
[…] 先日、X方向Y方向微分の記事を掲載しましたが、本日は平滑化処理を紹介します! […]
[…] 【画像処理】Go言語で輪郭抽出!X方向Y方向微分【サンプルコード付き】こ… […]