In my last post i explain how EuclideanColorFiltering work . here i use that in my webcam for track and detect i made a realtime tracker could be made where color and objects size could also be changed in real time. and can draw movement of that objects in a bitmap with that color. i use some part of their code, although i use separate color filter for more accuracy.
First how my software work first can start tracking by default color black and color range of 120 but u can change in real time to color change press that a color dialog will come , then select color, remember to press OK and see the solidcolor box that Ur required color is present or not.
To select the range and define minimum size of the object see next image, there are 3 numeric updown list for that. objectsize calculated in pixel
now about the views, there are 4 view, 3 of them is Aforge video source control and another one is a picturebox, first one show normal video, second one show all detected object, 3rd box show only the biggest object and fourth one just draw a ‘0’ sign in biggest object location, see below image for more clearence
i also add a richtextbox which showing the pixel of biggestrectangle position .now about the code for connection i use normal aforge connection code,
for that u need to download aforge dll, and also add a very good videocontrol for showing video u can add it in ur toolbox. just click freespace on toolbox chooseitems-> browse the dll -> add the control
using AForge; using AForge.Video.DirectShow;
then initialize
videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); if (videoDevices.Count == 0) throw new ApplicationException(); foreach (FilterInfo device in videoDevices) { VideoCaptureDevice videoSource = new VideoCaptureDevice(device.MonikerString); videoSource.DesiredFrameSize = new Size(320, 240); videoSource.DesiredFrameRate = 15; videoSourcePlayer1.VideoSource = videoSource; videoSourcePlayer1.Start(); }
for videoplayercontrol add a event in its misc
named
private void videoSourcePlayer1_NewFrame(object sender, ref Bitmap image) {//work with image }
in that function i apply my color detection code by writing eucladian filtering and then use blobcounter to extract data to see how its work u can see my this post
the code is simple for second videoframe i used
private void videoSourcePlayer1_NewFrame(object sender, ref Bitmap image) { Bitmap objectsImage = null; Bitmap mImage = null; mImage=(Bitmap)image.Clone(); filter.CenterColor = Color.FromArgb(color.ToArgb()); filter.Radius =(short)range; objectsImage = image; filter.ApplyInPlace(objectsImage); BitmapData objectsData = objectsImage.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, image.PixelFormat); UnmanagedImage grayImage = grayscaleFilter.Apply(new UnmanagedImage(objectsData)); objectsImage.UnlockBits(objectsData); blobCounter.ProcessImage(grayImage); Rectangle[] rects = blobCounter.GetObjectRectangles(); if (rects.Length > 0) { foreach (Rectangle objectRect in rects) { Graphics g = Graphics.FromImage(mImage); using (Pen pen = new Pen(Color.FromArgb(160, 255, 160), 5)) { g.DrawRectangle(pen, objectRect); } g.Dispose(); } } image = mImage; }
and for second videoframe i used belowcode
private void videoSourcePlayer3_NewFrame(object sender, ref Bitmap image) { Bitmap objectsImage = null; // set center colol and radius filter.CenterColor = Color.FromArgb(color.ToArgb()); filter.Radius = (short)range; // apply the filter objectsImage = image; filter.ApplyInPlace(image); // lock image for further processing BitmapData objectsData = objectsImage.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, image.PixelFormat); // grayscaling UnmanagedImage grayImage = grayscaleFilter.Apply(new UnmanagedImage(objectsData)); // unlock image objectsImage.UnlockBits(objectsData); // locate blobs blobCounter.ProcessImage(grayImage); Rectangle[] rects = blobCounter.GetObjectRectangles(); if (rects.Length > 0) { Rectangle objectRect = rects[0]; // draw rectangle around derected object Graphics g = Graphics.FromImage(image); using (Pen pen = new Pen(Color.FromArgb(160, 255, 160), 5)) { g.DrawRectangle(pen, objectRect); } g.Dispose(); int objectX = objectRect.X + objectRect.Width / 2 - image.Width / 2; int objectY = image.Height / 2 - (objectRect.Y + objectRect.Height / 2); ParameterizedThreadStart t = new ParameterizedThreadStart(p); Thread aa = new Thread(t); aa.Start(rects[0]); } Graphics g1 = Graphics.FromImage(image); Pen pen1 = new Pen(Color.FromArgb(160, 255, 160), 3); g1.DrawLine(pen1,image.Width/2,0,image.Width/2,image.Width); g1.DrawLine(pen1, image.Width , image.Height / 2, 0, image.Height / 2); g1.Dispose(); }
the thread where i used to draw position and show that thread worked like
void p(object r) { try { Bitmap b = new Bitmap(pictureBox1.Image); Rectangle a = (Rectangle)r; Pen pen1 = new Pen(Color.FromArgb(160, 255, 160), 3); Graphics g2 = Graphics.FromImage(b); pen1 = new Pen(color, 3); SolidBrush b5 = new SolidBrush(color); Font f = new Font(Font, FontStyle.Bold); g2.DrawString("o", f, b5, a.Location); g2.Dispose(); pictureBox1.Image = (System.Drawing.Image)b; this.Invoke((MethodInvoker)delegate { richTextBox1.Text = a.Location.ToString() + "\n" + richTextBox1.Text + "\n"; ; }); } catch (Exception faa) { Thread.CurrentThread.Abort(); } Thread.CurrentThread.Abort(); }
i have to use invoke to write in textbox because of cross threading.
u can change color size any time u want, the color of drawing point will also be change
thank u for reading this long article, The full code uploaded here.
after few moderation u can use it in ur code for many type of application
thank u all.
see update- at this post
You must be logged in to post a comment.