linqで画像処理

Post on 30-Jun-2015

937 Views

Category:

Documents

4 Downloads

Preview:

Click to see full reader

DESCRIPTION

CLR/H #74 のLTで発表したもの

TRANSCRIPT

LINQで画像処理

momo_*(@tututen)

自己紹介

● 某北見市で働く職業プログラマ● 趣味でもプログラム書くことがあります● お仕事:C言語、(Python、C#)● 趣味:ほぼ何でも(※アセンブリを除く)● パネルでポン(以下、パネポン)ができます● タグ「友達がいないとこうなります」で検索!● あと、手元を映したUst動画もあったりします

地図

地図

自己紹介

● 某北見市で働く職業プログラマ● 趣味でもプログラム書くことがあります● お仕事:C言語、(Python、C#)● 趣味:ほぼ何でも(※アセンブリを除く)● パネルでポン(以下、パネポン)ができます● タグ「友達がいないとこうなります」で検索!● あと、手元を映したUst動画もあったりします

検索結果

最近のタグ(7/7 13:00現在)

Ust風景

http://www.ustream.tv/recorded/20923039

LINQについて

Language Integrated Query の略称で、 C# や VB

などの .NET Framework 対応言語に、 リレーショナルデータや XML に対するデータ操作構文を組み込む (+ データベースや XML 操作用のライブラリ)

引用:http://ufcpp.net/study/csharp/sp3_linq.html

LINQについて

0 1 2

1098

7654

3

11

141312 15

0 2

8

64

1412

10Where(p => p % 2 == 0)

LINQについて

Select(p => p.ToString())

0 2

8

64

1412

10

"0" "2"

"8"

"6""4"

"14""12"

"10"

今回の説明する機能

今回の説明する機能

画像処理の主な手順

● 画像をグレースケール(モノクロ)化● 画像を二値化● テンプレート画像とのマッチング

グレースケール(モノクロ)化

● 中間値法● NTSC系加重平均法

(NTSC=National Television System Commitee(全米テレビジョン放送標準化委員会))

R * 0.298912 + G * 0.586611 + B * 0.114478

グレースケール(モノクロ)化

● 中間値法● NTSC系加重平均法

(NTSC=National Television System Commitee(全米テレビジョン放送装標準化委員会)) 

グレースケール(モノクロ)化

※画像はイメージです!

二値化

● 各画素の値を取る● しきい値によって「0」or「255」を設定するだけ

※画像はイメージです!

LINQ的にどう書く?

1. 画像を画素のシーケンシャルに変換2. 各画素に対してグレースケール化3. グレースケールした画素に対して、二値化

LockBits1. Bitmap型のデータをByte配列にする2. 画像のフォーマットによって、1画素の情報が違

う3. PixelFormat.Format32bppArgbの場合byte[4]

に1画素の情報が入り、1byteごとにBlue、Green、Red、Alphaのデータが入る。

LockBits

各画素をグレースケール化

1. [0 .. 画像サイズ*4byte分]のシーケンシャルデータを生成

2. 4の倍数のシーケンシャルデータにフィルタ3. NTSC系加重平均法の公式を当てはめる

各画素をグレースケール化

Enumerable.Range(0, bmp.Width * bmp.Height * 4) // 1

各画素をグレースケール化

Enumerable.Range(0, bmp.Width * bmp.Height * 4) // 1 .Where(p => p % 4 == 0) // 2

各画素をグレースケール化

Enumerable.Range(0, bmp.Width * bmp.Height * 4) // 1 .Where(p => p % 4 == 0) // 2 .AsParallel() // 並列化 .ForAll(p => { double cr = 0.298912, cg = ..., cb = ...; byte g = (byte)(cr * ba[i + 0] + cg * ba[i + 1] + cb * ba[i + 2]) ba[i + 0] = ba[i + 1] = ba[i + 2] = g; });

各画素を二値化

Enumerable.Range(0, bmp.Width * bmp.Height * 4) // 1 .Where(p => p % 4 == 0) // 2 .AsParallel() // 並列化 .ForAll(p => { double cr = 0.298912, cg = ..., cb = ...; byte g = (byte)(cr * ba[i + 0] + cg * ba[i + 1] + cb * ba[i + 2]) ba[i + 0] = ba[i + 1] = ba[i + 2] = g < th ? 0 : 255; });

テンプレート画像でマッチング

● 空白・数字「1−9」までのテンプレート画像を用意

● 上記のテンプレート画像を二値化した画像と、マスの画像を二値化した画像を比較

● 比較結果が最も似ているものをその数値と断定する。

37

370

テンプレート画像でマッチング

Enumerable.Range(0, 10) // 1

テンプレート画像でマッチング

Enumerable.Range(0, 10) // 1 .Select((p, i) => new {

})

テンプレート画像でマッチング

Enumerable.Range(0, 10) // 1 .Select((p, i) => new { Num = i, })

テンプレート画像でマッチング

Enumerable.Range(0, 10) // 1 .Select((p, i) => new { Num = i, Count = Enumerable.Range(0, 37 * 37) .Count( q => CellImgByte[q] == TmplImgByte[i * 37 + q % 37 + q / 37 + i * 370] ) // 2 })

テンプレート画像でマッチング

Enumerable.Range(0, 10) // 1 .Select((p, i) => new { Num = i, Count = Enumerable.Range(0, 37 * 37) .Count( q => CellImgByte[q] == TmplImgByte[i * 37 + q % 37 + q / 37 + i * 370] ) // 2 }) .OrderByDescending( p => p.Count )

テンプレート画像でマッチング

Enumerable.Range(0, 10) // 1 .Select((p, i) => new { Num = i, Count = Enumerable.Range(0, 37 * 37) .Count( q => CellImgByte[q] == TmplImgByte[i * 37 + q % 37 + q / 37 + i * 370] ) // 2 }) .OrderByDescending( p => p.Count ) .First()

テンプレート画像でマッチング

Enumerable.Range(0, 10) // 1 .Select((p, i) => new { Num = i, Count = Enumerable.Range(0, 37 * 37) .Count( q => CellImgByte[q] == TmplImgByte[i * 37 + q % 37 + q / 37 + i * 370] ) // 2 }) .OrderByDescending( p => p.Count ) .First() .Num; // 3

まとめ

● 各画素に対して行う画像処理とLINQの相性はばっちし!

● 今日からあなたもわたしもLINQ!LINQ!

ご清聴ありがとうございました

top related