Motion Tracking Auto Turret

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • David24
    New Member
    • Jan 2008
    • 13

    Motion Tracking Auto Turret

    source code: <link removed>
    comcast wont allow .rar (because they suck) so you have to right-click save page as and rename to .rar. i tested this twice and it works fine.

    this motion detector has 2 filters, edges and rectangles. this is concerning the edges filter only, it compares two bitmaps (converted to grayscale), gets a list of x and y coordinates, and draws tiny rectangles at each coordinate which represent the difference between the 2 images (motion).

    problem 1:
    what i've been trying to do for a week now is create a method that takes that same x and y coordinate list, draws a rectangle of a different color on the AVERAGE of the coordinate list. it essentially creates a single target representing the average location of motion and displays it along with the original edges filter.

    problem 2:
    once that is done the next step would be to output that target coordinate to a mini-SSC servo controller (translated to servo angles) that the user would calibrate in a user interface.
  • David24
    New Member
    • Jan 2008
    • 13

    #2
    Originally posted by David24
    source code: <link removed>
    comcast wont allow .rar (because they suck) so you have to right-click save page as and rename to .rar. i tested this twice and it works fine.

    this motion detector has 2 filters, edges and rectangles. this is concerning the edges filter only, it compares two bitmaps (converted to grayscale), gets a list of x and y coordinates, and draws tiny rectangles at each coordinate which represent the difference between the 2 images (motion).

    problem 1:
    what i've been trying to do for a week now is create a method that takes that same x and y coordinate list, draws a rectangle of a different color on the AVERAGE of the coordinate list. it essentially creates a single target representing the average location of motion and displays it along with the original edges filter.

    problem 2:
    once that is done the next step would be to output that target coordinate to a mini-SSC servo controller (translated to servo angles) that the user would calibrate in a user interface.
    how's anybody supposed to help me if you guys remove the link to the source code? that's absolutely asinine..

    Comment

    • Ganon11
      Recognized Expert Specialist
      • Oct 2006
      • 3651

      #3
      It's part of our policy - you can read it in full if you follow the Help link at the top of the site.

      If you are having issues with a specific section of code, please post it here - don't make users download a zip/rar file to help you.

      Comment

      • David24
        New Member
        • Jan 2008
        • 13

        #4
        Originally posted by Ganon11
        It's part of our policy - you can read it in full if you follow the Help link at the top of the site.

        If you are having issues with a specific section of code, please post it here - don't make users download a zip/rar file to help you.
        if i were an experienced programmer i would want the whole solution so i could actually test my modifications for functionality.. .that's fine though, i'll post the code. now, OF COURSE, the ENTIRE code needs to be posted because anything less would hinder comprehension. so instead of a simple post with a link to the source code, here's the annoying, tacky, eleventybillion page long code pasted to this post.

        Code:
        using System;
        using System.Collections;
        using System.Drawing;
        using System.Drawing.Imaging;
        
        namespace VideoCapture
        {
            public class ImageProcessing
            {
                //autogenerated Constructor - does nothing
                private ImageProcessing( )
                {
                }
                //Method AnalyzeImageWithEdges returns newImage (or null)
                public static Bitmap AnalyzeImageWithEdges(
                    Bitmap originalImage,
                    Bitmap newImage )
                {
                    if( originalImage == null || newImage == null )
                    {
                        return null;
                    }
        
        
                    //half-size the originalImage
                    originalImage =
                        ResizeImage(
                            originalImage,
                            originalImage.Height / 2,
                            originalImage.Width / 2 );
                    //half-size the newImage
                    newImage =
                        ResizeImage(
                            newImage,
                            newImage.Height / 2,
                            newImage.Width / 2);
                    
                    //convert originalImage to grayscale
                    Bitmap grayedOriginalImage = GetGrayScaledImage(originalImage);
                    //convert newImage to grayscale
                    Bitmap grayedNewImage = GetGrayScaledImage(newImage);
        
                    CoordinateList coordinateList =
                        GetImageDifference(
                            grayedOriginalImage,
                            grayedNewImage);
        
                    //draw lines for the edges filter
                    if( coordinateList.CalculateEdges().Length > 0 )
                    {
                        using( Graphics graphics = Graphics.FromImage( newImage ) )
                        {
                            graphics.DrawRectangles(
                                new Pen( Color.Red, 1 ),
                                coordinateList.CalculateEdges() );
                        }
                    }
        
                    grayedOriginalImage.Dispose();
                    grayedOriginalImage = null;
        
                    grayedNewImage.Dispose();
                    grayedNewImage = null;
        
                    return newImage;
                }
        
                //Method AnalyzeImageWithRectangles returns newImage (or null)
                public static Bitmap AnalyzeImageWithRectangles(
                    Bitmap originalImage,
                    Bitmap newImage )
                {
                    if (originalImage == null || newImage == null)
                    {
                        return null;
                    }
        
                    originalImage =
                        ResizeImage(
                            originalImage,
                            originalImage.Height / 2,
                            originalImage.Width / 2);
        
                    newImage =
                        ResizeImage(
                            newImage,
                            newImage.Height / 2,
                            newImage.Width / 2);
        
                    Bitmap grayedOriginalImage = GetGrayScaledImage(originalImage);
                    Bitmap grayedNewImage = GetGrayScaledImage(newImage);
        
                    CoordinateList coordinateList =
                        GetImageDifference( 
                            grayedOriginalImage,
                            grayedNewImage );
        
                    if ( coordinateList.CalculateRectangles().Length > 0 )
                    {
                        using( Graphics graphics = Graphics.FromImage( newImage ) )
                        {
                            graphics.DrawRectangles(
                                new Pen( Color.BlueViolet, 1 ),
                                coordinateList.CalculateRectangles() );
                        }
                    }
        
                    grayedOriginalImage.Dispose();
                    grayedOriginalImage = null;
        
                    grayedNewImage.Dispose();
                    grayedNewImage = null;
        
                    return newImage;
                }
        
                //Method GetGrayScaledImage returns resultingBitmap
                private static Bitmap GetGrayScaledImage( Bitmap originalImage )
                {
                    Bitmap resultingBitmap =
                        new Bitmap( 
                            originalImage.Width, 
                            originalImage.Height, 
                            PixelFormat.Format32bppArgb );
        
                    BitmapData originalData =
                        originalImage.LockBits(
                            new Rectangle( 
                                0, 
                                0, 
                                originalImage.Width, 
                                originalImage.Height ),
                            ImageLockMode.ReadOnly,
                            PixelFormat.Format32bppArgb );
        
                    BitmapData resultingData =
                        resultingBitmap.LockBits(
                            new Rectangle( 
                                0, 
                                0, 
                                resultingBitmap.Width, 
                                resultingBitmap.Height ),
                            ImageLockMode.ReadOnly,
                            PixelFormat.Format32bppArgb );
        
                    int newPixel = 0;
        
                    unsafe
                    {
                        byte* originalPointer = ( byte* )originalData.Scan0;
                        byte* resultingPointer = ( byte* )resultingData.Scan0;
        
                        for( int yCoordinate = 0; yCoordinate < originalData.Height; ++yCoordinate )
                        {
                            for( int xCoordinate = 0; xCoordinate < originalData.Width; ++xCoordinate )
                            {
                                newPixel = 
                                    ( originalPointer[ 0 ] + 
                                    originalPointer[ 1 ] + 
                                    originalPointer[ 2 ] ) / 3;
        
                                resultingPointer[ 0 ] = ( byte )newPixel;     /* Blue   */
                                resultingPointer[ 1 ] = ( byte )newPixel;     /* Green  */
                                resultingPointer[ 2 ] = ( byte )newPixel;     /* Red    */
                                resultingPointer[ 3 ] = originalPointer[ 3 ]; /* Alpha  */
        
                                originalPointer += 4;
                                resultingPointer += 4;
                            }
        
                            originalPointer += 
                                originalData.Stride - ( originalData.Width * 4 );
        
                            resultingPointer += 
                                resultingData.Stride - ( resultingData.Width * 4 );
                        }
                    }
        
                    resultingBitmap.UnlockBits( resultingData );
                    originalImage.UnlockBits( originalData );
        
                    return resultingBitmap;
                }
        
                //Method GetImageDifference returns coordinateList
                private static CoordinateList GetImageDifference( Bitmap originalImage, Bitmap newImage )
                {
                    Bitmap resultingBitmap =
                        new Bitmap( 
                            originalImage.Width, 
                            originalImage.Height, 
                            PixelFormat.Format32bppArgb );
        
                    BitmapData originalData = 
                        originalImage.LockBits( 
                            new Rectangle( 
                                0, 
                                0, 
                                originalImage.Width, 
                                originalImage.Height ),
                            ImageLockMode.ReadOnly,
                            PixelFormat.Format24bppRgb );
        
                    BitmapData newData =
                        newImage.LockBits(
                            new Rectangle( 
                                0, 
                                0, 
                                newImage.Width, 
                                newImage.Height ),
                            ImageLockMode.ReadOnly,
                            PixelFormat.Format24bppRgb );
        
                    BitmapData resultingData =
                        resultingBitmap.LockBits(
                            new Rectangle( 
                                0, 
                                0, 
                                resultingBitmap.Width, 
                                resultingBitmap.Height ),
                            ImageLockMode.WriteOnly,
                            PixelFormat.Format24bppRgb );
        
                    CoordinateList coordinateList = new CoordinateList();
        
                    unsafe
                    {
                        byte* originalPointer = ( byte* )originalData.Scan0;
                        byte* newPointer = ( byte* )newData.Scan0;
                        byte* resultingPointer = ( byte* )resultingData.Scan0;
        
                        for( int yCoordinate = 0; yCoordinate < originalData.Height; ++yCoordinate )
                        {
                            for( int xCoordinate = 0; xCoordinate < originalData.Width * 3; ++xCoordinate )
                            {
                                int originalPixel = 
                                    ( originalPointer[ 0 ] + 
                                    originalPointer[ 1 ] + 
                                    originalPointer[ 2 ] );
        
                                int newPixel =
                                    ( newPointer[ 0 ] + 
                                    newPointer[ 1 ] + 
                                    newPointer[ 2 ] );
        
                                if( newPixel > originalPixel + 140 || 
                                    newPixel < originalPixel - 140 )
                                {
                                    resultingPointer[ 0 ] = 0;
        
                                    coordinateList.Add(
                                        new CoordinateList.PointOfInterest( 
                                            xCoordinate / 3, 
                                            yCoordinate ) );
                                }
                                else
                                {
                                    resultingPointer[ 0 ] = 255;
                                }
        
                                ++originalPointer;
                                ++newPointer;
                                ++resultingPointer;
                            }
        
                            originalPointer += 
                                originalData.Stride - ( originalData.Width * 3 );
        
                            newPointer += 
                                newData.Stride - ( newData.Width * 3 );
        
                            resultingPointer += 
                                resultingData.Stride - ( resultingData.Width * 3 );
                        }
                    }
        
                    resultingBitmap.UnlockBits( resultingData );
                    newImage.UnlockBits( newData );
                    originalImage.UnlockBits( originalData );
        
                    resultingBitmap.Dispose();
                    resultingBitmap = null;
        
                    return coordinateList;
                }
        Last edited by Ganon11; Jan 31 '08, 08:58 PM. Reason: had to split up code so it would show

        Comment

        • Ganon11
          Recognized Expert Specialist
          • Oct 2006
          • 3651

          #5
          Rest of the code:

          [code=cpp]
          //Method ResizeImage returns resultingImage
          private static Bitmap ResizeImage(
          Bitmap bitmap,
          int height,
          int width )
          {
          Bitmap resultingImage = new Bitmap( width, height );

          using( Graphics graphics =
          Graphics.FromIm age( ( Image )resultingImage ) )
          {
          graphics.DrawIm age(bitmap, 0, 0, width, height);
          }

          return resultingImage;
          }

          #region CoordinateList Inner-Class

          public class CoordinateList : CollectionBase
          {
          public PointOfInterest this[ int index ]
          {
          get { return ( PointOfInterest )this.List[ index ]; }
          }
          //Method Add
          public void Add( PointOfInterest pointOfInterest )
          {
          this.List.Add( pointOfInterest );
          }

          //Method CalculateEdges returns rectangles
          public Rectangle[] CalculateEdges( )
          {
          CoordinateList coordinateList = new CoordinateList( );

          PointOfInterest previousPointOf Interest =
          new PointOfInterest ( -1, -1 );

          int rowCounter = 0;

          foreach( PointOfInterest pointOfInterest in this.List )
          {
          if( ( ( pointOfInterest .XCoordinate >
          previousPointOf Interest.XCoord inate + THRESHOLD ||
          pointOfInterest .XCoordinate <
          previousPointOf Interest.XCoord inate - THRESHOLD ) &&
          ( pointOfInterest .YCoordinate >
          previousPointOf Interest.YCoord inate + THRESHOLD ||
          pointOfInterest .YCoordinate <
          previousPointOf Interest.YCoord inate - THRESHOLD ) ) ||
          rowCounter == 2 )
          {
          coordinateList. Add( pointOfInterest );

          rowCounter = 0;
          }

          if( pointOfInterest .YCoordinate !=
          previousPointOf Interest.YCoord inate )
          {
          ++rowCounter;
          }

          previousPointOf Interest =
          new PointOfInterest (
          pointOfInterest .XCoordinate,
          pointOfInterest .YCoordinate );
          }

          //int x = coordinateList. XCoordinate / coordinateList. XCoordinate.Cou nt;
          //int y = coordinateList. YCoordinate / coordinateList. XCoordinate.Cou nt;
          //target = new Rectangle(x, y, 10, 10);
          //coordinateList. Add(target);

          Rectangle[] rectangles =
          new Rectangle[ coordinateList. Count ];

          //edges filter
          for( int i = 0; i <= ( coordinateList. Count - 1 ); ++i )
          {
          rectangles[ i ] =
          new Rectangle(
          coordinateList[ i ].XCoordinate,
          coordinateList[ i ].YCoordinate,
          1,
          1);
          }

          return rectangles;
          }
          //Method CalculateRectan gles returns rectangles
          public Rectangle[] CalculateRectan gles( )
          {
          CoordinateList coordinateList = new CoordinateList( );

          PointOfInterest previousPointOf Interest =
          new PointOfInterest ( -1, -1 );

          PointOfInterest pointOfInterest =
          new PointOfInterest ( -1, -1 );

          foreach( PointOfInterest existingPointOf Interest in this.List )
          {
          if( ( existingPointOf Interest.XCoord inate >
          previousPointOf Interest.XCoord inate + THRESHOLD ||
          existingPointOf Interest.XCoord inate <
          previousPointOf Interest.XCoord inate - THRESHOLD ) &&
          ( existingPointOf Interest.YCoord inate >
          previousPointOf Interest.YCoord inate + THRESHOLD ||
          existingPointOf Interest.YCoord inate <
          previousPointOf Interest.YCoord inate - THRESHOLD ) )
          {
          pointOfInterest = existingPointOf Interest;
          }

          if( existingPointOf Interest.YCoord inate !=
          previousPointOf Interest.YCoord inate )
          {
          pointOfInterest .Height =
          previousPointOf Interest.YCoord inate -
          pointOfInterest .YCoordinate;

          pointOfInterest .Width =
          previousPointOf Interest.XCoord inate -
          pointOfInterest .XCoordinate;

          coordinateList. Add( pointOfInterest );
          }

          previousPointOf Interest =
          new PointOfInterest (
          existingPointOf Interest.XCoord inate,
          existingPointOf Interest.YCoord inate );
          }

          Rectangle[] rectangles =
          new Rectangle[ coordinateList. Count ];

          for( int i = 0; i <= ( coordinateList. Count - 1 ); ++i )
          {
          rectangles[ i ] =
          new Rectangle(
          coordinateList[ i ].XCoordinate,
          coordinateList[ i ].YCoordinate,
          coordinateList[ i ].Width,
          coordinateList[ i ].Height );
          }

          return rectangles;
          }

          //Method SortByYCoordina teAscending
          public void SortByXCoordina teAscending( )
          {
          IComparer sorter = new SortByXCoordina te();
          InnerList.Sort( sorter );
          }

          //Method SortByYCoordina teAscending
          public void SortByYCoordina teAscending( )
          {
          IComparer sorter = new SortByYCoordina te();
          InnerList.Sort( sorter );
          }

          //Method GetTarget (i created)
          /*public static Rectangle GetTarget()
          {
          int x = coordinateList. XCoordinate / coordinateList. XCoordinate.Cou nt;
          int y = coordinateList. YCoordinate / coordinateList. XCoordinate.Cou nt;
          target = new Rectangle(x, y, 10, 10);
          return target;
          }*/

          private const int THRESHOLD = 10;

          #region PointOfInterest Inner-Class

          public class PointOfInterest
          {
          //Property PointOfInterest
          public PointOfInterest ( int xCoordinate, int yCoordinate )
          {
          this.xCoordinat e = xCoordinate;
          this.yCoordinat e = yCoordinate;
          }

          #region Attributes
          //Property height returns height
          public int Height
          {
          get { return height; }
          set { height = value; }
          }
          //Property Width returns width
          public int Width
          {
          get { return width; }
          set { width = value; }
          }
          //Property XCoordinate returns xCoordinate
          public int XCoordinate
          {
          get { return xCoordinate; }
          set { xCoordinate = value; }
          }
          //Property YCoordinate returns yCoordinate
          public int YCoordinate
          {
          get { return yCoordinate; }
          set { yCoordinate = value; }
          }

          #endregion

          private int height = 0;
          private int width = 0;
          private int xCoordinate = -1;
          private int yCoordinate = -1;
          }

          #endregion

          #region Sorting Inner-Classes

          public class SortByXCoordina te : IComparer
          {
          // Method Compare returns ic1.CompareTo( ic2 )
          public int Compare( object compare1, object compare2 )
          {
          PointOfInterest pointOfInterest 1 =
          ( PointOfInterest )compare1;

          IComparable ic1 =
          ( IComparable )pointOfInteres t1.XCoordinate;

          PointOfInterest pointOfInterest 2 =
          ( PointOfInterest )compare2;

          IComparable ic2 =
          ( IComparable )pointOfInteres t2.XCoordinate;

          return ic1.CompareTo( ic2 );
          }
          }

          public class SortByYCoordina te : IComparer
          {
          //Method Compare returns ic1.CompareTo( ic2 )
          public int Compare( object compare1, object compare2 )
          {
          PointOfInterest pointOfInterest 1 =
          ( PointOfInterest )compare1;

          IComparable ic1 =
          ( IComparable )pointOfInteres t1.YCoordinate;

          PointOfInterest pointOfInterest 2 =
          ( PointOfInterest )compare2;

          IComparable ic2 =
          ( IComparable )pointOfInteres t2.YCoordinate;

          return ic1.CompareTo( ic2 );
          }
          }

          #endregion
          }

          #endregion
          }
          }[/code]

          Comment

          • Ganon11
            Recognized Expert Specialist
            • Oct 2006
            • 3651

            #6
            Originally posted by David24
            if i were an experienced programmer i would want the whole solution so i could actually test my modifications for functionality.. .that's fine though, i'll post the code. now, OF COURSE, the ENTIRE code needs to be posted because anything less would hinder comprehension. so instead of a simple post with a link to the source code, here's the annoying, tacky, eleventybillion page long code pasted to this post.
            I agree, it's not a perfect solution. However, imagine this situation:

            Poster A comes to the site and says "I need help, here's the source code and an executable" or whatever. Helper B comes, downloads the source code or executable or whatever, and tries to use it. Whoops! Its not a friendly program like Poster A said - it's actually a virus. Now Helper B is screwed, as well as Helper C and D, Moderator E, and anyone else who wanted to help out.

            If we see your code on the site, in a post, it can't do anything to our computer. We can now help you without having to worry about "Is this guy some lying jerk who wants to kill my computer?"

            So however annoying it is, it's for the protection of users like you. And, to be frank, if you don't like it, feel free to find help elsewhere. We have come up with the posting guidelines for a specific reason. If you'd like clarification, or have an honest issue with a part of the guidelines, feel free to raise them (the Miscellaneous Discussions section is the best place for this), but please don't just complain about them.

            MODERATOR

            Comment

            • David24
              New Member
              • Jan 2008
              • 13

              #7
              there's the code. we'll see if anyone can solve the problem.. (line 167 is the method i tried to create (which doesn't work))

              Comment

              • oler1s
                Recognized Expert Contributor
                • Aug 2007
                • 671

                #8
                if i were an experienced programmer i would want the whole solution so i could actually test my modifications for functionality
                No. We will make suggestions for you, and guide you in the right direction, but we will not repeatedly test and debug your code to get you ahead. That is work you must do on your own. Our suggestions will not necessarily be copy-paste answers either. Sorry to burst your bubble, about what to expect on programmer forums.

                What we actually want is a decent description of the problem. You described what you are working on, which is good. Unfortunately, you failed to describe what obstacle you have reached. You mentioned the two problems you were working on. It elicits a, "so what" from us. So? What's the problem in what you're working on? Is code not compiling? Runtime errors? Clueless how to approach the problem? What?

                Moreover, you have effectively dumped a large block of code, which is useless. The entire code is not in question, is it? It's a specific portion of the code that doesn't work. Moreover, "doesn't work" is a useless comment for programmers. Great. Is it not working because when the code runs, your lights in your room flicker? No? Something happens at runtime? What did you see? Not at runtime? Can't get it to compile? What was the error?

                You want good responses, you need to isolate the problem on your own, as best as you can. If you can't, describe your observations, and ask how you might narrow down the problem. See Eric Raymond's article on what ideal questions are like.

                Originally posted by Raymond
                You need to be precise and informative. This end is not served by simply dumping huge volumes of code or data into a help request. If you have a large, complicated test case that is breaking a program, try to trim it and make it as small as possible.

                This is useful for at least three reasons. One: being seen to invest effort in simplifying the question makes it more likely you'll get an answer, Two: simplifying the question makes it more likely you'll get a useful answer. Three: In the process of refining your bug report, you may develop a fix or workaround yourself.
                Maybe one of us will get around to helping you. Most likely, you'll get little information. It's a large code dump, effectively, with no help on your part in trying to find the solution. Trim it down, and give us more precise details, please.

                Comment

                • David24
                  New Member
                  • Jan 2008
                  • 13

                  #9
                  Originally posted by oler1s
                  ...
                  no problem.

                  Code:
                              //Method GetTarget (i created)
                              public static Rectangle GetTarget()
                              {
                                  //find the average x coordinate
                                  int x = coordinateList.XCoordinate / coordinateList.XCoordinate.Count;
                                  //find the average y coordinate
                                  int y = coordinateList.YCoordinate / coordinateList.XCoordinate.Count;
                                  //create a rectangle 10by10 pixels wide at the average location of x and y and store it as target
                                  target = new Rectangle(x, y, 10, 10);
                                  //return that coordinate
                                  return target;
                              }
                  this can be found on line 167

                  compile error:
                  The name 'coordinateList ' does not exist in the current context
                  The name 'target' does not exist in the current context

                  this was my attempt at a method for solving problem1.
                  there are likely several things wrong here. the method may be inside the wrong class, it doesn't refer to the array coordinateList correctly, or i may need to create an object instance of the class the coordinateList array is from... i dunno. like i said, i tried for at least a week to solve this with no luck.

                  Comment

                  Working...