Motion Detection in C#

HI,
I would like to do a simple motion detection that can detect a car from my web cam in which my program can tell you the car is from left to right or from right to left.
  I have searched a sample code from
http://www.codeproject.com/KB/audio-video/Motion_Detection.aspx
I tried to modified the program
for ( int y = 0; y < height; y++ )
                        {
                              for ( int x = 0; x < width; x++, ptr++ )
                              {
                                    count += ( (*ptr) >> 7 );
                       
                        Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
                        Debug.WriteLine(count.ToString());
                              }
                              ptr += offset;
                 
                        }

However, when I use Debug, the video cannot capture image.  Anyway I should not use Debug.

So how can I detect the car from left to right or from right to left?

thanks
gorexyAsked:
Who is Participating?
 
savethetigerCommented:
you can:
define a custom event and throw the event and then manage in this evenr your logic or
 (easier) you can add to ImotionDetector a property LeftCount e RightCount.

Then you can use  timer_elapse function  on mainform (that is called by a time to generate statistical data) to read
and display these values.
0
 
magicdlfCommented:
I checked the code. This code is surrounded by "unsafe". Try to move your code out of the unsafe and see if debug is stoping your from capturing the video.
Btw, what's the point by adding debug code here? The code just counts the white pixels diffs. I think what you need to do is check the project and see where the author call CalculateWhitePixels() and put your debug code there.
Let me know if this is working.
0
 
savethetigerCommented:
I've seen the article I would say that the  software  does not give indication concerning motion direction.
You are  checking  the difference between the original background image and current image.


To identify motion direction you need to examine with the same alghoritm two different frames A and B.
In these two different analysis you have to match movement region in frame A and B to define it is the same object.
Checking the relative positions of the object in the two frame you have the direction information.
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
gorexyAuthor Commented:
magicdlf / savethetiger:
  My idea is to check the X and Y coordinate and decide the initial few different changes.  Does it make sense??  
  In fact, I would like to see how to find the coordinate in which the first appear white (motion) pixels appear at say, 0 - 15 ( x coordinate, left to right) or ( 150 - 200) (x coordinate, right to left)

  That's why I put debug in the for loop , however seems doesn't work...
0
 
gorexyAuthor Commented:
So I tried to add something here:  My idea is whenever the R,G or B changes, I get the coordinate and decide the direction.  However, it will stop capturing the video too

....
 thresholdFilter.ApplyInPlace( bitmapData );
            // erosion filter
            Bitmap tmpImage3 = erosionFilter.Apply( bitmapData );

            // unlock temporary image
            tmpImage2.UnlockBits( bitmapData );
            tmpImage2.Dispose( );

////////////////////////I added here in order to check the pixel changes and get the x , y coordinates/////

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    //tmpImage3.GetPixel(x, y).ToString();
                    if ((tmpImage3.GetPixel(x, y).R > 0) || (tmpImage3.GetPixel(x, y).G > 0) || (tmpImage3.GetPixel(x, y).B > 0))
                    {
                        Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
                        Debug.WriteLine(x.ToString());
                        Debug.WriteLine(y.ToString());
                    }
                    else
                    {
                       
                    }

                }
            }
           
           
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////      
           
            // calculate amount of changed pixels
                  pixelsChanged = ( calculateMotionLevel ) ?
                        CalculateWhitePixels( tmpImage3 ) : 0;

                  // dispose old background
                  backgroundFrame.Dispose( );
                  // set backgound to current
                  backgroundFrame = tmpImage;

.........
0
 
gorexyAuthor Commented:
can I raise points?
0
 
gorexyAuthor Commented:
sorry...any updates?
0
 
savethetigerCommented:
If I understand your idea is to  check if the motion is in the left area or right area to identify from which
side the object is entering in the scene.

In this case you could use detection 4.
Then you can check if the center of the rectangle is on the left or on the right of the image.
Of course you can also restrict your check just to a smaller area on the left and on the right.


In motiondetector4.cs you can modify the drawing code as below:
You have red rectangle on the right and green on the left.





    foreach ( Rectangle rc in rects )
                    {

                        
                        //g.DrawRectangle( pen, rc );

                        if ( ( n < 10 ) && ( rc.Width > 15 ) && ( rc.Height > 15 ) )
                        {
                            g.DrawImage( numbersBitmaps[n], rc.Left, rc.Top, 7, 9 );
                            n++;
                            if ((image.Width / 2) < (rc.Width) / 2+rc.X)
                            {

                                //Right
                                pen.Color = Color.Red;
                                g.DrawRectangle(pen, rc);
                            }
                            else
                            {  //Left
                                 pen.Color=Color.Green;
                                g.DrawRectangle(pen, rc);
                            
                            }



                        }

Open in new window

0
 
gorexyAuthor Commented:
Hi savethetiger:
  Thanks a lots and I will test it when I go back office.  By the way, can I raise a signal say, "Left" or "Right" after it detects the square?  Since I need the signal for the next part of my program to do other things.

I will let you know soon

Really appreciate
0
 
gorexyAuthor Commented:
Excellent.  Just sometimes if the car moves fast, the cam seems cannot accurate capture the car.  and as a result gives false result.  Anyway the idea is good!  Many thanks!
0
 
gorexyAuthor Commented:
"define a custom event and throw the event and then manage in this evenr your logic or
 (easier) you can add to ImotionDetector a property LeftCount e RightCount.

Then you can use  timer_elapse function  on mainform (that is called by a time to generate statistical data) to read
and display these values."
I didn't test this yet since I am a new babie in C#.  If you have time and don't mind, could you show me the code as well? so that I can learn something new.
0
 
savethetigerCommented:
Hello gorexy see some code below
// 1)Define the event in motiondetector4 and the delegatefunction


   public event handleCarEnter OnCarEnter;  
   public delegate void handleCarEnter(MotionDetector4 m, MovementDirection e);

 //  2)Raise the event in the motiondetector4 class

    //Right
     pen.Color = Color.Red;
     g.DrawRectangle(pen, rc);
     MovementDirection md= new MovementDirection();
     md.direction = 0;
     OnCarEnter(this, md);
     //... on the left only direction change

 //  3)In main.cs then you subscribe to the event and handle the event when you create the motion detector

     detector = new MotionDetector4( );
     MotionDetector4 tmp = (MotionDetector4)detector;
     tmp.OnCarEnter += new MotionDetector4.handleCarEnter(tmp_OnCarEnter);
     
      void tmp_OnCarEnter(MotionDetector4 m, MovementDirection e)
        {
            if (e.direction == 0) { _carfromRight = _carfromRight + 1;
            MessageBox.Show("right");}
                
                
        } 



//5)  motion direction is just a simple class..


    public class MovementDirection : EventArgs
    {
        int _direction;
        public int direction
        {
            set { _direction = value; }
            get { return _direction;}
        
        }
      

    
    }

Open in new window

0
 
gorexyAuthor Commented:
sorry to my silly question

where is main.cs??

Also, do I need to create a new class to hold :
public class MovementDirection : EventArgs
    {
        int _direction;
        public int direction
        {
            set { _direction = value; }
            get { return _direction;}
       
        }
     

   
    }??

0
 
savethetigerCommented:
The proper name is MainForm.cs sorry.

Yes you need to create the class MovementDirection.
 you can add it into the motiondetector4.cs file under the namespace "motion" before the class definition.

you can find a very simple tutorial on c# events here

http://www.codeproject.com/KB/cs/simplesteventexample.aspx

 
0
 
gorexyAuthor Commented:
sorry one more question....

detector = new MotionDetector4( );
     MotionDetector4 tmp = (MotionDetector4)detector;
     tmp.OnCarEnter += new MotionDetector4.handleCarEnter(tmp_OnCarEnter);
     
      void tmp_OnCarEnter(MotionDetector4 m, MovementDirection e)
        {
            if (e.direction == 0) { _carfromRight = _carfromRight + 1;
            MessageBox.Show("right");}
               
               
        }

where should I put this portion of code inside MainForm.cs??

I cannot find a proper place to find.  it always give me error when put at the end (after  private void motionAlarmItem_Click( object sender, System.EventArgs e ) method)

Sorry for my stupid learning curve.
0
 
savethetigerCommented:
Hello
you should insert this line when you create the object


 // Select detector 4
        private void detector4MotionItem_Click( object sender, System.EventArgs e )
        {
            detector = new MotionDetector4( );
            MotionDetector4 tmp = (MotionDetector4)detector;
            tmp.OnCarEnter += new MotionDetector4.CarEnter(tmp_OnCarEnter);
         

            detectorType = 5;
            SetMotionDetector( );
        }


you then add the function outside:


void tmp_OnCarEnter(MotionDetector4 m, MovementDirection e)
        {
            if (e.direction == 0) { _carfromRight = _carfromRight + 1;
            MessageBox.Show("right");}
               
               
        }






0
 
gorexyAuthor Commented:
I think It is ok now.  You are not only an expert but also a good mentor!  Your link is useful and I am learning.

Many thanks!
0
 
savethetigerCommented:
you are welcome.
Happy to help.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.