saifullah khan

saifullah khan

  • 1.7k
  • 335
  • 281.4k

select multiple objects in a video using emgu.cv librareis

Jul 21 2013 6:15 AM
i have a desktop application. the purpose of the application is that user selects a point in the video(shown in picturebox1), so that point is highlighted by a white and red rectangle and the same video with those rectangles is shown in the other picturbox2. when the object in the video moves the rectangles also moves.
the main problem is that it selects only one point at a time. i want to use two point. first select point one and then the point 2 so the both of the points(rectangles) should be used in the video. in other words i can say i want to use multiple points in a video.
please check the  source and and help me out
thanks in advance.

FFT.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;

using System.Drawing;

class FFT//: IDisposable//Nothing to dispose
{
    #region Variables
    Point Object_Location = new Point();
    #endregion
    #region Constructors

    /// <summary>
    /// Track Object with Class Creation
    /// </summary>
    /// <param name="Input_Image"></param>
    /// <param name="Template"></param>
    public FFT(Image<Gray, Byte> Input_Image, Image<Gray, Byte> Template)
    {
        Detect_objects(Input_Image.Copy(), Template.Copy());
    }

    /// <summary>
    /// Blank Creation
    /// </summary>
    public FFT()
    {
    }


    #endregion
    #region Public
    /// <summary>
    /// Returns Location of the tracked object
    /// </summary>
    /// <returns></returns>
    public Point GetLocation()
    {
        return Object_Location;
    }
    public bool TrackObject(Image<Gray, Byte> Input_Image, Image<Gray, Byte> Template)
    {
        return Detect_objects(Input_Image.Copy(), Template.Copy());
    }
    #endregion
    #region Private
    private bool Detect_objects(Image<Gray,Byte> Input_Image, Image<Gray, Byte> object_Image)
    {
        Point dftSize = new Point(Input_Image.Width + (object_Image.Width * 2), Input_Image.Height + (object_Image.Height * 2));
        bool Success = false;
        using (Image<Gray, Byte> pad_array = new Image<Gray, Byte>(dftSize.X, dftSize.Y))
        {
            //copy centre
            pad_array.ROI = new Rectangle(object_Image.Width, object_Image.Height, Input_Image.Width, Input_Image.Height);
            CvInvoke.cvCopy(Input_Image.Convert<Gray, Byte>(), pad_array, IntPtr.Zero);

            //CvInvoke.cvShowImage("pad_array", pad_array);
            pad_array.ROI = (new Rectangle(0, 0, dftSize.X, dftSize.Y));
            using (Image<Gray, float> result_Matrix = pad_array.MatchTemplate(object_Image, TM_TYPE.CV_TM_CCOEFF_NORMED))
            {
                result_Matrix.ROI = new Rectangle(object_Image.Width, object_Image.Height, Input_Image.Width, Input_Image.Height);
               
                Point[] MAX_Loc, Min_Loc;
                double[] min, max;
                result_Matrix.MinMax(out min, out max, out Min_Loc, out MAX_Loc);

                using (Image<Gray, double> RG_Image = result_Matrix.Convert<Gray, double>().Copy())
                {
                    //#TAG WILL NEED TO INCREASE SO THRESHOLD AT LEAST 0.8

                    if (max[0] > 0.4)
                    {
                        Object_Location = MAX_Loc[0];
                        Success = true;
                    }
                }

            }
        }
        return Success;
    }
    #endregion
}


Form2.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;

using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;

namespace FFT_Object_Tracking
{
    public partial class Form1 : Form
    {
        #region
        //Images
        Image<Gray, Byte> Template;
        Image<Bgr, Byte> Frame;
        Image<Gray, Byte> GrayFrame;

        //Classes
        FFT _FFT = new FFT();
        Capture _capture;

        //Drawing
        int Template_Width = 20;
        int Template_Hieght = 20;

        Rectangle Image_ROI_Location;
        Rectangle Template_Location;

        //Object Change
        int NO_Match = 0;
        bool Start = false;

        #endregion
        public Form1()
        {
            InitializeComponent();
            try
            {
                _capture = new Capture();
                Application.Idle += ProcessFrame;
            }
            catch (NullReferenceException excpt)
            {
                MessageBox.Show("No Video Input Found\nException:"+excpt.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if(_capture != null)
            {
                //Set template Location
                //Template_Location = new Rectangle(e.X, e.Y, 100, 100);
                //Template = GrayFrame.Copy(Template_Location);

                //Set ROI Location
                //Image_ROI_Location = new Rectangle(e.X - 50, e.Y - 50, 200, 200);

                //Set Template
                SetTemplate(e.X, e.Y);

                //Show Match
                DisplayImage();

            }
        }

        public void DisplayImage()
        {
            //Draw 2 Rectangle showing template location and ROI
            Frame.Draw(Image_ROI_Location, new Bgr(0, 0, 255), 2);
            Frame.Draw(Template_Location, new Bgr(0, 255, 0), 2);
            pictureBox2.Image = Frame.ToBitmap();

        }

        private void ProcessFrame(object sender, EventArgs e)
        {
            Frame = _capture.QueryFrame().Copy();
            GrayFrame = Frame.Convert<Gray, Byte>();
            pictureBox1.Image = Frame.ToBitmap();
            try
            {
                if (Start)
                {
                    //Apply template to ROI
                    if (checkrange(Image_ROI_Location.X, Image_ROI_Location.Y))
                    {
                        if (_FFT.TrackObject(GrayFrame.Copy(Image_ROI_Location), Template))
                        {
                            //Apply Ajustmet and display match location
                            Account_Movement();
                            DisplayImage();
                        }
                    }  
                  
                        //if not found apply it to the whole image
                        else if (_FFT.TrackObject(GrayFrame.Copy(), Template))
                        {
                            //Set New Location of Template and Template ROI
                            Template_Location = new Rectangle(_FFT.GetLocation().X, _FFT.GetLocation().Y, Template_Width, Template_Hieght);
                            Image_ROI_Location = new Rectangle(_FFT.GetLocation().X - Template_Width / 2, _FFT.GetLocation().Y - Template_Hieght / 2, Template_Width * 2, Template_Hieght * 2);
                            DisplayImage();
                        }
                        else
                        {
                            //Track to see if object change
                            int buffer = 50;
                            if (Template_Location.X > buffer && Template_Location.X < Frame.Width - buffer &&
                                Template_Location.Y > buffer && Template_Location.Y < Frame.Height - buffer)
                            {
                                NO_Match++;
                                if (NO_Match > 20)
                                {
                                    NO_Match = 0;
                                    //Create new template from last know location
                                    SetTemplate(Template_Location.X, Template_Location.Y);
                                    DisplayImage();
                                }
                            }
                            //Else just display Image
                            else pictureBox2.Image = Frame.ToBitmap();
                        }
                      

                }
                else pictureBox1.Image = Frame.ToBitmap();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        public void Account_Movement()
        {
            Image_ROI_Location.X += _FFT.GetLocation().X - (Template_Width / 2);
            Image_ROI_Location.Y += _FFT.GetLocation().Y - (Template_Hieght / 2);
            Template_Location.X += _FFT.GetLocation().X - (Template_Width / 2);
            Template_Location.Y += _FFT.GetLocation().Y - (Template_Hieght / 2);
        }

        public void SetTemplate(int X, int Y)
        {
            if(checkrange(X, Y))
            {
                //Set template Location
                Template_Location = new Rectangle(X, Y, Template_Width, Template_Hieght);
                //check to make sure within Image Bounds
                Template = GrayFrame.Copy(Template_Location);

                //Set ROI Location
                Image_ROI_Location = new Rectangle(X - Template_Width / 2, Y - Template_Hieght / 2, Template_Width * 2, Template_Hieght * 2);

                //Start Matching
                Start = true;
            }
        }

        public bool checkrange(int X, int Y)
        {
            if (X - Template_Width / 2 < 0) return false;
            if (Y - Template_Hieght / 2 < 0) return false;
            if (X + (Template_Width * 2) > Frame.Width) return false;
            if (Y + (Template_Hieght * 2) > Frame.Height) return false;
            return true;
        }
    }
}