Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TemplateMatching
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void searchLoadButton_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "bmp|*.bmp";
if (ofd.ShowDialog() == DialogResult.OK)
{
this.searchTextBox.Text = ofd.FileName;
}
}
private void templateLoadButton_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "bmp|*.bmp";
if (ofd.ShowDialog() == DialogResult.OK)
{
this.templateTextBox.Text = ofd.FileName;
}
}
private void go(long maxSAD)
{
maxSAD++;
try
{
Bitmap searchBmp = new Bitmap(searchTextBox.Text);
Bitmap templateBmp = new Bitmap(templateTextBox.Text);
if (searchBmp.Width < templateBmp.Width ||
searchBmp.Height < templateBmp.Height)
{
MessageBox.Show("検索画像がテンプレ画像より高さまたは幅が小さいです。");
return;
}
resultLabel.Text = "しばらくお待ち下さい。";
resultLabel.Update();
long minSAD = maxSAD; // SAD は Sum of absolute differences の略。
int bestX = 0;
int bestY = 0;
for (int x = 0; x <= searchBmp.Width-templateBmp.Width; x++)
{
for (int y = 0; y <= searchBmp.Height-templateBmp.Height; y++)
{
long SAD = 0;
// 実行に時間がかかるので、左上が一致した場合だけ処理する。
if (searchBmp.GetPixel(x, y) != templateBmp.GetPixel(0, 0))
{
continue;
}
for (int i = 0; i < templateBmp.Width; i++)
{
for (int j = 0; j < templateBmp.Height; j++)
{
Color s = searchBmp.GetPixel(x + i, y + j);
Color t = templateBmp.GetPixel(i, j);
SAD += Math.Abs(s.R - t.R) + Math.Abs(s.G - t.G) + Math.Abs(s.B - t.B);
}
}
if (minSAD > SAD)
{
minSAD = SAD;
bestX = x;
bestY = y;
}
}
}
if (minSAD == maxSAD)
{
resultLabel.Text = "一致パターンはありません。";
}
else
{
resultLabel.Text = "一致しました。\r\n\r\nX座標=" + bestX + "\r\nY座標=" + bestY + "\r\nSAD=" + minSAD;
}
}
catch
{
}
}
private void goButton_Click(object sender, EventArgs e)
{
try
{
long sad = long.Parse(maxSADTextBox.Text);
go(sad);
}
catch
{
MessageBox.Show("最大許容値を正しく入力してください。");
}
}
}
}
Form1.Designer.cs
namespace TemplateMatching
{
partial class Form1
{
/// <summary>
/// 必要なデザイナー変数です。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 使用中のリソースをすべてクリーンアップします。
/// </summary>
/// <param name="disposing">マネージ リソースが破棄される場合 true、破棄されない場合は false です。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows フォーム デザイナーで生成されたコード
/// <summary>
/// デザイナー サポートに必要なメソッドです。このメソッドの内容を
/// コード エディターで変更しないでください。
/// </summary>
private void InitializeComponent()
{
this.searchLoadButton = new System.Windows.Forms.Button();
this.templateLoadButton = new System.Windows.Forms.Button();
this.searchTextBox = new System.Windows.Forms.TextBox();
this.templateTextBox = new System.Windows.Forms.TextBox();
this.resultLabel = new System.Windows.Forms.Label();
this.goButton = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.maxSADTextBox = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// searchLoadButton
//
this.searchLoadButton.Location = new System.Drawing.Point(21, 37);
this.searchLoadButton.Name = "searchLoadButton";
this.searchLoadButton.Size = new System.Drawing.Size(119, 31);
this.searchLoadButton.TabIndex = 0;
this.searchLoadButton.Text = "検索画像読み込み";
this.searchLoadButton.UseVisualStyleBackColor = true;
this.searchLoadButton.Click += new System.EventHandler(this.searchLoadButton_Click);
//
// templateLoadButton
//
this.templateLoadButton.Location = new System.Drawing.Point(21, 83);
this.templateLoadButton.Name = "templateLoadButton";
this.templateLoadButton.Size = new System.Drawing.Size(119, 31);
this.templateLoadButton.TabIndex = 0;
this.templateLoadButton.Text = "テンプレ画像読み込み";
this.templateLoadButton.UseVisualStyleBackColor = true;
this.templateLoadButton.Click += new System.EventHandler(this.templateLoadButton_Click);
//
// searchTextBox
//
this.searchTextBox.Location = new System.Drawing.Point(166, 43);
this.searchTextBox.Name = "searchTextBox";
this.searchTextBox.Size = new System.Drawing.Size(273, 19);
this.searchTextBox.TabIndex = 1;
//
// templateTextBox
//
this.templateTextBox.Location = new System.Drawing.Point(166, 89);
this.templateTextBox.Name = "templateTextBox";
this.templateTextBox.Size = new System.Drawing.Size(273, 19);
this.templateTextBox.TabIndex = 1;
//
// resultLabel
//
this.resultLabel.AutoSize = true;
this.resultLabel.Location = new System.Drawing.Point(164, 170);
this.resultLabel.Name = "resultLabel";
this.resultLabel.Size = new System.Drawing.Size(48, 12);
this.resultLabel.TabIndex = 2;
this.resultLabel.Text = "出力なし";
//
// goButton
//
this.goButton.Location = new System.Drawing.Point(21, 163);
this.goButton.Name = "goButton";
this.goButton.Size = new System.Drawing.Size(119, 26);
this.goButton.TabIndex = 3;
this.goButton.Text = "実行";
this.goButton.UseVisualStyleBackColor = true;
this.goButton.Click += new System.EventHandler(this.goButton_Click);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(88, 133);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(65, 12);
this.label1.TabIndex = 4;
this.label1.Text = "最大許容値";
//
// maxSADTextBox
//
this.maxSADTextBox.ImeMode = System.Windows.Forms.ImeMode.Disable;
this.maxSADTextBox.Location = new System.Drawing.Point(166, 130);
this.maxSADTextBox.Name = "maxSADTextBox";
this.maxSADTextBox.Size = new System.Drawing.Size(273, 19);
this.maxSADTextBox.TabIndex = 1;
this.maxSADTextBox.Text = "10";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(459, 262);
this.Controls.Add(this.label1);
this.Controls.Add(this.goButton);
this.Controls.Add(this.resultLabel);
this.Controls.Add(this.maxSADTextBox);
this.Controls.Add(this.templateTextBox);
this.Controls.Add(this.searchTextBox);
this.Controls.Add(this.templateLoadButton);
this.Controls.Add(this.searchLoadButton);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button searchLoadButton;
private System.Windows.Forms.Button templateLoadButton;
private System.Windows.Forms.TextBox searchTextBox;
private System.Windows.Forms.TextBox templateTextBox;
private System.Windows.Forms.Label resultLabel;
private System.Windows.Forms.Button goButton;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox maxSADTextBox;
}
}