こんにちは!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方向微分【サンプルコード付き】こ… […]