Вы находитесь на странице: 1из 7

using System;

using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Features2D;
using Emgu.CV.Structure;
using Emgu.CV.UI;
using Emgu.CV.Util;

namespace realtime_surf
{
public partial class Form1 : Form
{
//member variables
Capture capWebcam;
bool blnWebcamCapturingInProcess = false;
Image<Bgr, byte> imgSceneColor = null;
Image<Bgr, byte> imgToFindColor = null;
Image<Bgr, byte> imgCopyOfImageToFindWidthBorder = null;
bool blnImageSceneLoaded = false;
bool blnImageToFindLoaded = false;
Image<Bgr, byte> imgResult = null;
Bgr bgrKeyPointColor = new Bgr(Color.Blue);
Bgr bgrMatchingLinesColor = new Bgr(Color.Green);
Bgr bgrFoundImageColor = new Bgr(Color.Red);
Stopwatch stopwatch = new Stopwatch();
public Form1()
{
InitializeComponent();
}

private void radioButton1_CheckedChanged(object sender, EventArgs e)


{
if ((rdoImageFile.Checked == true))
{
if ((blnWebcamCapturingInProcess == true))
{
Application.Idle -= new
EventHandler(this.PerformSURFDetectionAndUpdateGUI);
blnWebcamCapturingInProcess = false;
}

imgSceneColor = null;
imgToFindColor = null;
imgCopyOfImageToFindWidthBorder = null;
imgResult = null;
blnImageSceneLoaded = false;
blnImageToFindLoaded = false;

txtImageScene.Text = "";
txtImageToFind.Text = "";
ibResult.Image = null;
this.Text = "Instruction : use \",,,\" buttons to choose both image
file, theb press Perform SURF Button";
btnPerformSURFOrGetImageToTrack.Text = "Perform SURF Detection";
ibResult.Image = null;
label1.Visible = true;
label2.Visible = true;
txtImageScene.Visible = true;
txtImageToFind.Visible = true;
btnImageScene.Visible = true;
btnImageToFind.Visible = true;
}
}

private void radioButton2_CheckedChanged(object sender, EventArgs e)


{
if ((rdoWebcam.Checked == true)) {
imgSceneColor = null;
imgToFindColor = null;
imgCopyOfImageToFindWidthBorder = null;
imgResult = null;
blnImageSceneLoaded = false;
blnImageToFindLoaded = false;
txtImageScene.Text = "";
txtImageToFind.Text = "";
ibResult.Image = null;
try {
capWebcam = new Capture();
} catch (Exception ex) {
this.Text = ex.Message;
return;
}
this.Text = "Instruction : hold Image to Track up to camera, then
press\"get image To Track\" ";
btnPerformSURFOrGetImageToTrack.Text = "get image to track";
imgToFindColor = null;
Application.Idle += new
EventHandler(this.PerformSURFDetectionAndUpdateGUI);
blnWebcamCapturingInProcess = true;
label1.Visible = false;
label2.Visible = false;
txtImageScene.Visible = false;
txtImageToFind.Visible = false;
btnImageScene.Visible = false;
btnImageToFind.Visible = false;
}
}

private void button1_Click(object sender, EventArgs e)


{
DialogResult dialogResult = ofdImageScene.ShowDialog();
if ((dialogResult == System.Windows.Forms.DialogResult.OK |
dialogResult ==
System.Windows.Forms.DialogResult.Yes)) {
txtImageScene.Text = ofdImageScene.FileName;
} else {
return;
}
try {
imgSceneColor = new Image<Bgr, byte>(txtImageScene.Text);
//Image(Of Bgr, Byte) My_Image = New Image(Of Bgr,Byte)
(txtImageScene.Text)
//imgSceneColor = imgSceneColor.ToBitmap();
} catch (Exception ex) {
this.Text = ex.Message;
return;
}
blnImageSceneLoaded = true;
if ((blnImageToFindLoaded == false)) {
ibResult.Image = imgSceneColor;
} else {
ibResult.Image =
imgSceneColor.ConcateHorizontal(imgCopyOfImageToFindWidthBorder);
}
}

private void button2_Click(object sender, EventArgs e)


{
DialogResult dialogResult = ofdImageToFind.ShowDialog();
if ((dialogResult == System.Windows.Forms.DialogResult.OK |
dialogResult ==
System.Windows.Forms.DialogResult.Yes))
{
txtImageToFind.Text = ofdImageToFind.FileName;
}
else
{
return;
}
try
{
imgToFindColor = new Image<Bgr, byte>(txtImageToFind.Text);
}
catch (Exception ex)
{
this.Text = ex.Message;
return;
}
blnImageToFindLoaded = true;
imgCopyOfImageToFindWidthBorder = imgToFindColor.Copy();
imgCopyOfImageToFindWidthBorder.Draw(new Rectangle(1, 1,
imgCopyOfImageToFindWidthBorder.Width - 3,
imgCopyOfImageToFindWidthBorder.Height - 3),
bgrFoundImageColor, 2);
if ((blnImageSceneLoaded == true))
{
ibResult.Image =
imgSceneColor.ConcateHorizontal(imgCopyOfImageToFindWidthBorder);
}
else
{
ibResult.Image = imgCopyOfImageToFindWidthBorder;
}
}

private void txtImageScene_TextChanged(object sender, EventArgs e)


{
txtImageScene.SelectionStart = txtImageScene.Text.Length;
}

private void txtImageToFind_TextChanged(object sender, EventArgs e)


{
txtImageToFind.SelectionStart = txtImageToFind.Text.Length;
}

private void btnPerformSURFOrGetImageToTrack_Click(object sender, EventArgs


e)
{
if ((rdoImageFile.Checked == true)) {
if ((txtImageToFind.Text != string.Empty & txtImageScene.Text !=
string.Empty)) {
PerformSURFDetectionAndUpdateGUI(new object(), new EventArgs());
} else {
this.Text = "choose image files first, then choose Perform SURF
Detection button";
}
} else if ((rdoWebcam.Checked == true)) {
imgToFindColor = imgSceneColor.Resize(320, 240,
INTER.CV_INTER_CUBIC,true);
this.Text = "Instruction : to update image to track, hold image up
to camera, then press \"update image to track\" ";
btnPerformSURFOrGetImageToTrack.Text = "update image to track";
} else {
//should never get here
}
}

private void ckDrawKeyPoints_CheckedChanged(object sender, EventArgs e)


{
if ((ckDrawKeyPoints.Checked == false)) {
ckDrawMatchingLines.Checked = false;
ckDrawMatchingLines.Enabled = false;
} else if ((ckDrawKeyPoints.Checked == true)) {
ckDrawMatchingLines.Enabled = true;
}

if ((rdoImageFile.Checked == true)) {
btnPerformSURFOrGetImageToTrack_Click(new object(), new
EventArgs());
}
}

private void ckDrawMatchingLines_CheckedChanged(object sender, EventArgs e)


{
if ((rdoImageFile.Checked == true)) {
btnPerformSURFOrGetImageToTrack_Click(new object(), new
EventArgs());
}
}

public void PerformSURFDetectionAndUpdateGUI(object sender, EventArgs arg)


{
if ((rdoImageFile.Checked == true)) {
if ((blnImageSceneLoaded == false | blnImageToFindLoaded == false |
imgSceneColor == null | imgToFindColor == null)) {
this.Text = "either or both image are not loaded or null,
please choose both images before performing SURF";
return;
}
this.Text = "processing, please wait . . .";
Application.DoEvents();
stopwatch.Restart();
} else if ((rdoWebcam.Checked == true)) {
try {
imgSceneColor = capWebcam.QueryFrame();
} catch (Exception ex) {
this.Text = ex.Message;
return;
}
if ((imgSceneColor == null)) {
this.Text = "error, imgSceneColor Is Nothing";
return;
}
if ((imgToFindColor == null)) {
ibResult.Image = imgSceneColor;
return;
}
}
//if we get here, we both color imagesare good, we can begin SURF
detection stuff . . .
SURFDetector surfDetector = new SURFDetector(500, false);
Image<Gray, byte> imgSceneGray = null;
Image<Gray, byte> imgToFindGray = null;
VectorOfKeyPoint vkpSceneKeyPoints = default(VectorOfKeyPoint);
VectorOfKeyPoint vkpToFindKeyPoints = default(VectorOfKeyPoint);
Matrix<float> mtxSceneDescriptors = default(Matrix<float>);
Matrix<float> mtxToFindDescriptors = default(Matrix<float>);
Matrix<int> mtxMatchIndices = default(Matrix<int>);
Matrix<float> mtxDistance = default(Matrix<float>);
Matrix<byte> mtxMask = default(Matrix<byte>);
BruteForceMatcher<float> bruteForceMatcher =
default(BruteForceMatcher<float>);
HomographyMatrix homographyMatrix = null;

int intKNumNearestNeighbors = 2;
double dblUniquenessThreshold = 0.8;
int intNumNonZeroElements = 0;
double dblScaleIncrement = 1.5;
int intRotationBins = 20;
double dblRansacReprojectionThreshold = 2.0;

Rectangle rectImageToFind = default(Rectangle);


PointF[] ptfPointsF = null;
Point[] ptPoints = null;

imgSceneGray = imgSceneColor.Convert<Gray, byte>();


imgToFindGray = imgToFindColor.Convert<Gray, byte>();
vkpSceneKeyPoints = surfDetector.DetectKeyPointsRaw(imgSceneGray,
null);
mtxSceneDescriptors = surfDetector.ComputeDescriptorsRaw(imgSceneGray,
null, vkpSceneKeyPoints);
vkpToFindKeyPoints = surfDetector.DetectKeyPointsRaw(imgToFindGray,
null);
mtxToFindDescriptors =
surfDetector.ComputeDescriptorsRaw(imgToFindGray, null, vkpToFindKeyPoints);
bruteForceMatcher = new BruteForceMatcher<float>(DistanceType.L2);
bruteForceMatcher.Add(mtxToFindDescriptors);
mtxMatchIndices = new Matrix<int>(mtxSceneDescriptors.Rows,
intKNumNearestNeighbors);
mtxDistance = new Matrix<float>(mtxSceneDescriptors.Rows,
intKNumNearestNeighbors);
bruteForceMatcher.KnnMatch(mtxSceneDescriptors, mtxMatchIndices,
mtxDistance, intKNumNearestNeighbors, null);
mtxMask = new Matrix<byte>(mtxDistance.Rows, 1);
mtxMask.SetValue(255);

Features2DToolbox.VoteForUniqueness(mtxDistance,
dblUniquenessThreshold, mtxMask);

intNumNonZeroElements = CvInvoke.cvCountNonZero(mtxMask);

if ((intNumNonZeroElements >= 4)) {


intNumNonZeroElements =
Features2DToolbox.VoteForSizeAndOrientation(vkpToFindKeyPoints, vkpSceneKeyPoints,
mtxMatchIndices, mtxMask, dblScaleIncrement, intRotationBins);

if ((intNumNonZeroElements >= 4)) {


homographyMatrix =
Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(vkpToFindKeyPoints,
vkpSceneKeyPoints, mtxMatchIndices, mtxMask, dblRansacReprojectionThreshold);
}
}

imgCopyOfImageToFindWidthBorder = imgToFindColor.Copy();
imgCopyOfImageToFindWidthBorder.Draw(new Rectangle(1, 1,
imgCopyOfImageToFindWidthBorder.Width - 3,
imgCopyOfImageToFindWidthBorder.Height - 3),
bgrFoundImageColor, 2);

if ((ckDrawKeyPoints.Checked == true & ckDrawMatchingLines.Checked ==


true)){
imgResult =
Features2DToolbox.DrawMatches(imgCopyOfImageToFindWidthBorder, vkpToFindKeyPoints,
imgSceneColor, vkpSceneKeyPoints, mtxMatchIndices, bgrMatchingLinesColor,
bgrKeyPointColor, mtxMask, Features2DToolbox.KeypointDrawType.DEFAULT);
} else if ((ckDrawKeyPoints.Checked == true &
ckDrawMatchingLines.Checked == false)) {
imgResult = Features2DToolbox.DrawKeypoints(imgSceneColor,
vkpSceneKeyPoints, bgrKeyPointColor,
Features2DToolbox.KeypointDrawType.DEFAULT);
imgCopyOfImageToFindWidthBorder =
Features2DToolbox.DrawKeypoints(imgCopyOfImageToFindWidthBorder,
vkpToFindKeyPoints, bgrKeyPointColor, Features2DToolbox.KeypointDrawType.DEFAULT);
imgResult =
imgResult.ConcateHorizontal(imgCopyOfImageToFindWidthBorder);
} else if ((ckDrawKeyPoints.Checked == false &
ckDrawMatchingLines.Checked == false)) {
imgResult = imgSceneColor;
imgResult =
imgResult.ConcateHorizontal(imgCopyOfImageToFindWidthBorder);
} else {
//should be never here
}

if ((homographyMatrix != null)) {
rectImageToFind.X = 0;
rectImageToFind.Y = 0;
rectImageToFind.Width = imgToFindGray.Width;
rectImageToFind.Height = imgToFindGray.Height;
ptfPointsF = new PointF[] {
new PointF(rectImageToFind.Left, rectImageToFind.Top),
new PointF(rectImageToFind.Right, rectImageToFind.Top),
new PointF(rectImageToFind.Right, rectImageToFind.Bottom),
new PointF(rectImageToFind.Left, rectImageToFind.Bottom)};

homographyMatrix.ProjectPoints(ptfPointsF);
ptPoints = new Point[] {
Point.Round(new
PointF(rectImageToFind.Left,rectImageToFind.Top)),
Point.Round(new PointF(rectImageToFind.Right,
rectImageToFind.Top)),
Point.Round(new PointF(rectImageToFind.Right,
rectImageToFind.Bottom)),
Point.Round(new PointF(rectImageToFind.Left,
rectImageToFind.Bottom))};

imgResult.DrawPolyline(ptPoints, true, bgrFoundImageColor, 2);


}

ibResult.Image = imgResult;
if ((rdoImageFile.Checked == true)) {
stopwatch.Stop();
this.Text = "processing time = " +
stopwatch.Elapsed.TotalSeconds.ToString() + "Sec, done processing,
choose another image if desired";
}
}
}
}