资源描述
原创-EMGUCV的模板匹配与跟踪完成啦!
兄弟们好!
经过很多天的努力学习,我的EMGUCV的模板匹配完成了,用实际的摄像头取图象,再存为模板后,就能实现物体跟踪,还能进行相机上马达进行位置确定。好玩吧!弄两幅图来看下。
这是匹配的,还能过行坐标二次定位。
坐标二次定位的
这是跟踪的
以下为代码,只有自己写的部分,由软件生成的部分没有帖上
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;
using System.Threading;
using System.IO;
using System.Drawing.Imaging;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using Emgu.CV.Util;
using Emgu.CV.UI;
using Emgu.CV.VideoSurveillance;
using Emgu.Util;
using Emgu.Util.TypeEnum;
using Emgu.CV.GPU;
namespace 模板匹配
{
public partial class Form1 : Form
{
public Image<Bgr, byte> src;
public Image<Bgr, byte> tempsrc;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog of = new OpenFileDialog();
of.Filter = "(jpg)|*.jpg";
if (of.ShowDialog ()== DialogResult.OK)
{
Image<Bgr, byte> imsrc = new Image<Bgr, byte>(of.FileName);
imageBox2.Image = imsrc;
src = imsrc;
imageBox1.Image = null;
}
}
private void button2_Click(object sender, EventArgs e)
{
if (src != null)
{
Image<Bgr, byte> imgsrc = src.Clone();//不可直接将src符值给新建图象,它传的只是一个地址,不是数据,要先考贝后才能不再引响原图像
Image<Gray, byte> imggray = imgsrc.Convert<Gray, byte>();
Image<Gray, byte> imgthread = imggray.ThresholdBinary(new Gray(60), new Gray(255));
Image<Gray, byte> imgcanny = imgthread.Canny(130,255);
//Contour<Point> contour = imgcanny.FindContours();//这个函数用来找中间的轮廓的每一个点,是一个数组点,很多个才能组成一个圆。
CircleF[] cf = imgthread.HoughCircles(new Gray(130), new Gray(255), 10, 1, 1, 400)[0];
MCvFont mf = new MCvFont(FONT.CV_FONT_HERSHEY_COMPLEX, 1, 1);
if (cf.Length > 0)
{
cf[0].Radius = cf[0].Radius + 50;
imgsrc.Draw(cf[0], new Bgr(0, 0, 255), 2);
Rectangle rec = new Rectangle((int)(cf[0].Center.X - cf[0].Radius), (int)(cf[0].Center.Y - cf[0].Radius), (int)(cf[0].Radius * 2), (int)(cf[0].Radius * 2));
imgsrc.Draw(rec, new Bgr(0, 0, 255), 2);
imgsrc.Draw(cf[0].Center.ToString() + "," + cf[0].Radius.ToString(), ref mf, new Point(0, src.Height - 30), new Bgr(0, 0, 255));
Image<Bgr, byte> templatebgr = src.Clone();
Image <Bgr ,byte > temp1 = templatebgr.GetSubRect(rec).Clone ();
imageBox1.Image = temp1;
temp1.Save(@"e:\template.jpg");
tempsrc = temp1.Clone();
MessageBox.Show(@"模板生成成功!已保存到e:\template.jpg中");
}
else
{
imgsrc.Draw(@"Dn't find out circle!PLS try agina.", ref mf, new Point(0, src.Height - 30), new Bgr(0, 0, 255));
imageBox1.Image = imgcanny;
}
}
}
private void button3_Click(object sender, EventArgs e)
{
Image<Gray, byte> imgsrc = src.Convert<Gray, byte>().Clone();
Image<Bgr, byte> readimg = new Image<Bgr, byte>(@"e:\template.jpg");
Image<Gray, byte> template =readimg.Convert<Gray, byte>().Clone();
Image <Bgr ,byte > imgcolor=src.Clone();
Image<Gray,byte > imgresult = imgsrc.MatchTemplate(template, TM_TYPE.CV_TM_CCOEFF ).Convert <Gray,byte>() .Clone();
imageBox1.Image = imgresult;
double bestvalue;
Point bestpoint;
FindBestPoint(imgresult, TM_TYPE.CV_TM_CCOEFF, out bestvalue, out bestpoint);
Rectangle rec1 = new Rectangle(new Point(bestpoint.X, bestpoint.Y ), template.Size);
imgcolor.Draw(rec1,new Bgr (0,0,255),2);
MCvFont mf = new MCvFont(FONT.CV_FONT_HERSHEY_COMPLEX, 1, 1);
imgcolor.Draw(rec1.X.ToString() +","+ rec1.Y.ToString(),ref mf ,new Point (0,src.Height -30),new Bgr (0,0,255));
imageBox1.Image = imgcolor ;
}
public void FindBestPoint(Image <Gray ,byte > image,TM_TYPE tmtype,out double bestvalue,out Point bestpoint)
{
bestvalue = 0d;
bestpoint = new Point(0, 0);
double[] max, min;
Point[] maxl, minl;
image.MinMax(out min, out max, out minl, out maxl);
if (tmtype == TM_TYPE.CV_TM_SQDIFF || tmtype == TM_TYPE.CV_TM_SQDIFF_NORMED)
{
bestvalue = min[0];
bestpoint = minl[0];
}
else
{
bestvalue = max[0];
bestpoint = maxl[0];
}
}
private bool mousestatus = false;
private Point startpoint;
private Point endpoint;
private Rectangle rectcurrent;
private void imageBox2_MouseDown(object sender, MouseEventArgs e)
{
if (imageBox2 .Image !=null )
{
startpoint.X = e.X;
startpoint.Y = e.Y;
mousestatus = true;
}
}
private void imageBox2_MouseUp(object sender, MouseEventArgs e)
{
if (mousestatus )
{
endpoint.X = e.X;
endpoint.Y = e.Y;
mousestatus = false;
}
}
private void imageBox2_MouseMove(object sender, MouseEventArgs e)
{
if (mousestatus )
{
endpoint.X = e.X;
endpoint.Y = e.Y;
Rectangle rec1 = new Rectangle(startpoint, new Size(Math.Abs(startpoint.X - endpoint.X), Math.Abs(startpoint.Y - endpoint.Y)));
Image<Bgr, byte> imgdraw = src.Clone();
imgdraw.Draw(rec1, new Bgr(0, 255, 0), 2);
imageBox2.Image = imgdraw;
rectcurrent = rec1;
imgdraw.Dispose();
}
}
private void button4_Click(object sender, EventArgs e)
{
if (rectcurrent != null)
{
Image<Bgr, byte> imgsrc = src.Clone();
Image<Bgr, byte> redo = imgsrc.GetSubRect(rectcurrent);
redo.Save(@"e:\template.jpg");
}
}
Capture ct = new Capture(0);
private void button5_Click(object sender, EventArgs e)
{
if (ct != null)
{
Application.Idle += new EventHandler(GetFrame);
}
}
private void GetFrame(object sender, EventArgs e)
{
Image<Bgr, byte> fram = ct.QueryFrame();
imageBox2.Image = fram;
src = fram;
if (captureflg==true)
{
Image<Gray, byte> imgsrc = src.Convert<Gray, byte>().Clone();
Image<Bgr, byte> readimg = tempsrc;
Image<Gray, byte> template = readimg.Convert<Gray, byte>().Clone();
Image<Bgr, byte> imgcolor = src.Clone();
Image<Gray, byte> imgresult = imgsrc.MatchTemplate(template, TM_TYPE.CV_TM_CCOEFF).Convert<Gray, byte>().Clone();
imageBox1.Image = imgresult;
double bestvalue;
Point bestpoint;
FindBestPoint(imgresult, TM_TYPE.CV_TM_CCOEFF, out bestvalue, out bestpoint);
Rectangle rec1 = new Rectangle(new Point(bestpoint.X, bestpoint.Y), template.Size);
imgcolor.Draw(rec1, new Bgr(0, 0, 255), 2);
imageBox1.Image = imgcolor;
}
Thread.Sleep(1);
}
private void button6_Click(object sender, EventArgs e)
{
Application.Idle -= new EventHandler(GetFrame);
Image<Bgr, byte> imgsrc = src.Clone();
imageBox2.Image = imgsrc;
}
private void button8_Click(object sender, EventArgs e)
{
if (rectcurrent.Width != 0|rectcurrent .Height !=0)
{
Image<Bgr, byte> imgsrc = src.Clone();
Image<Bgr, byte> redo = imgsrc.GetSubRect(rectcurrent);
redo.Save(@"e:\template.jpg");
tempsrc = redo;
}
Application.Idle += new EventHandler(GetFrame);
}
public bool captureflg = false;
private void button7_Click(object sender, EventArgs e)
{
tempsrc = new Image<Bgr, byte>(@"e:\template.jpg");
if (captureflg == false & tempsrc != null)
{
captureflg = true;
button7.Text = "跟踪中";
}else
{
captureflg = false ;
button7.Text = "跟踪停止";
}
}
}
}
展开阅读全文