CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Jan 2008
    Posts
    10

    Lightbulb Get the average of points

    i am modifying a simple motion detector from the Aforge Library. It simply compares 2 frames and draws the difference as semitransparent red pixels. I need to store the (constantly changing) average location of these red pixels (representing motion) as int targetX and int targetY. Here is the code:
    Code:
            public unsafe void ProcessFrame(Bitmap image)
            {
                BitmapData imageData = null;
    
                // check previous frame
                if (previousFrame == IntPtr.Zero)
                {
                    // save image dimension
                    width = image.Width;
                    height = image.Height;
                    frameSize = width * height;
    
                    // alocate memory for previous and current frames
                    previousFrame = Marshal.AllocHGlobal(frameSize);
                    currentFrame = Marshal.AllocHGlobal(frameSize);
                    // temporary buffer
                    if (suppressNoise)
                    {
                        tempFrame = Marshal.AllocHGlobal(frameSize);
                    }
    
                    // lock source image
                    imageData = image.LockBits(
                        new Rectangle(0, 0, width, height),
                        ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
    
                    // convert source frame to grayscale
                    ImageProcessingTools.GrayscaleImage(imageData, previousFrame);
    
                    // unlock source image
                    image.UnlockBits(imageData);
    
                    return;
                }
    
                // check image dimension
                if ((image.Width != width) || (image.Height != height))
                    return;
    
                // lock source image
                imageData = image.LockBits(
                    new Rectangle(0, 0, width, height),
                    (highlightMotionRegions) ? ImageLockMode.ReadWrite : ImageLockMode.ReadOnly,
                    PixelFormat.Format24bppRgb);
    
                // convert current image to grayscale
                ImageProcessingTools.GrayscaleImage(imageData, currentFrame);
    
                // pointers to previous and current frames
                byte* prevFrame = (byte*)previousFrame.ToPointer();
                byte* currFrame = (byte*)currentFrame.ToPointer();
                // difference value
                int diff;
    
                // 1 - get difference between frames
                // 2 - threshold the difference
                // 3 - copy current frame to previous frame
                for (int i = 0; i < frameSize; i++, prevFrame++, currFrame++)
                {
                    // difference
                    diff = (int)*currFrame - (int)*prevFrame;
                    // copy current frame to previous
                    *prevFrame = *currFrame;
                    // threshold
                    *currFrame = ((diff >= differenceThreshold) || (diff <= differenceThresholdNeg)) ? (byte)255 : (byte)0;
                }
    
                // calculate amount of motion pixels
                pixelsChanged = 0;
    
                if (suppressNoise)
                {
                    // suppress noise and calculate motion amount
                    AForge.Win32.memcpy(tempFrame, currentFrame, frameSize);
    
                    byte* motion = (byte*)currentFrame.ToPointer() + width + 1;
                    byte* temp = (byte*)tempFrame.ToPointer() + width + 1;
    
                    int widthM1 = width - 1;
                    int heightM1 = height - 1;
    
                    // erosion is used to suppress noise
                    for (int y = 1; y < heightM1; y++)
                    {
                        for (int x = 1; x < widthM1; x++, motion++, temp++)
                        {
                            // check if it is motion pixel
                            if (*motion != 0)
                            {
                                *motion = (byte)(temp[-width - 1] & temp[-width] & temp[-width + 1] &
                                    temp[width - 1] & temp[width] & temp[width + 1] &
                                    temp[1] & temp[-1]);
    
                                pixelsChanged += (*motion & 1);
                            }
                        }
                        motion += 2;
                        temp += 2;
                    }
                }
                else
                {
                    // calculate motion without suppressing noise
                    byte* motion = (byte*)currentFrame.ToPointer();
    
                    for (int i = 0; i < frameSize; i++, motion++)
                    {
                        pixelsChanged += (*motion & 1);
                    }
                }
    
                // highlight motion regions
                if (highlightMotionRegions)
                {
                    byte* src = (byte*)imageData.Scan0.ToPointer();
                    byte* motion = (byte*)currentFrame.ToPointer();
                    int srcOffset = imageData.Stride - width * 3;
    
                    // shift to the red channel
                    src += 2;
    
                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x++, motion++, src += 3)
                        {
                            *src |= *motion;
                        }
                        src += srcOffset;
                    }
                }
    
                // unlock source image
                image.UnlockBits(imageData);
            }

  2. #2
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: Get the average of points

    Hi !
    This doesn't seem to be C#, looks like C++
    Code:
    .....
     
    // pointers to previous and current frames
    byte* prevFrame = (byte*)previousFrame.ToPointer();
    byte* currFrame = (byte*)currentFrame.ToPointer();
    So you need to post there. And please ask a clear question there. Whats your problem ?
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  3. #3
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    1,080

    Re: Get the average of points

    It's C# alright. Note the "unsafe" key word in the method declaration.

    That said, JP is quite correct in saying that, if you want us to help, you should state clearly what the issue is. That's quite a bit of code you expect us to sift through without any idea of what we're looking for.
    Tutorials: Home & Learn | Start VB.NET | Learn VB.NET | C# Station | GotDotNet | Games in VB.NET 101 Samples: 2002 | 2003 | 2005 | More .NET 2.0 (VB.NET, C#) Articles: VB.NET | C# | ASP.NET | MoreFree Components: WFC | XPCC | ElementsEx | VBPP | Mentalis | ADO.NET/MySQL | VisualStyles | Charting (NPlot, ZedGraph) | iTextSharp (PDF) | SDF (CF) ● Free Literature: VB 2005 (eBook) | VB6 to VB.NET (eBook) | MSDN Magazine (CHM format) ● Bookmarks: MSDN | WinForms .NET | ASP.NET | WinForms FAQ | WebForms FAQ | GotDotNet | Code Project | DevBuzz (CF) ● Code Converter: C#/VB.NET | VB.NET/C# | VS 2005 add-in

  4. #4
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: Get the average of points

    Quote Originally Posted by jmcilhinney
    It's C# alright. Note the "unsafe" key word in the method declaration.
    Sorry Obviously not looked at this.
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  5. #5
    Join Date
    Jan 2008
    Posts
    10

    Re: Get the average of points

    ok, here's my question; how would i store the red pixels this motion detector draws as a list of points so i can then average their location? this code runs as unsafe so that it can run very fast and uses address and indirection operators which i vaguely understand..

    this bit of code is hard to comprehend. i've never seen an address operator used like this (*motion & 1). i don't understand what is really happening inside the for loop

    Code:
      // calculate motion without suppressing noise
                    byte* motion = (byte*)currentFrame.ToPointer();
    
                    for (int i = 0; i < frameSize; i++, motion++)
                    {
                        pixelsChanged += (*motion & 1);
                    }
    i don't understand this either
    Code:
     *src |= *motion;
    i can't find any good examples of what The OR assignment operator does except that it performs a bitwise logical OR operation on integral operands which doesn't help. i'm tryingto understand what the code in these two for loops does;
    Code:
     // highlight motion regions
                if (highlightMotionRegions)
                {
                    byte* src = (byte*)imageData.Scan0.ToPointer();
                    byte* motion = (byte*)currentFrame.ToPointer();
                    int srcOffset = imageData.Stride - width * 3;
    
                    // shift to the red channel
                    src += 2;
    
                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x++, motion++, src += 3)
                        {
                            *src |= *motion;
                        }
                        src += srcOffset;
                    }

  6. #6
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    1,080

    Re: Get the average of points

    That ampersand is not an address operator. A double ampersand is a logical AND operator while a single ampersand is a bitwise AND operator. A bitwsie AND will create a result where each bit is set if and only if the correspond bit is set in the first operand AND the second operand, e.g.
    Code:
    10101010
    11110000
    -------- AND
    10100000
    If you AND a value with 1 then the result will be 1 if the lowest order bit is set in the original value or zero if it's not. This:
    Code:
    *motion & 1
    is basically getting the value of the lowest order bit.

    Similarly a double pipe is a logical OR operator while a single pipe is a bitwise OR operator. A bitwsie OR will create a result where each bit is set if and only if the correspond bit is set in the first operand OR the second operand, e.g.
    Code:
    10101010
    11110000
    -------- OR
    11111010
    This:
    Code:
    *src |= *motion;
    is shorthand for this:
    Code:
    *src = *src | *motion;
    Last edited by jmcilhinney; February 13th, 2008 at 07:18 PM.
    Tutorials: Home & Learn | Start VB.NET | Learn VB.NET | C# Station | GotDotNet | Games in VB.NET 101 Samples: 2002 | 2003 | 2005 | More .NET 2.0 (VB.NET, C#) Articles: VB.NET | C# | ASP.NET | MoreFree Components: WFC | XPCC | ElementsEx | VBPP | Mentalis | ADO.NET/MySQL | VisualStyles | Charting (NPlot, ZedGraph) | iTextSharp (PDF) | SDF (CF) ● Free Literature: VB 2005 (eBook) | VB6 to VB.NET (eBook) | MSDN Magazine (CHM format) ● Bookmarks: MSDN | WinForms .NET | ASP.NET | WinForms FAQ | WebForms FAQ | GotDotNet | Code Project | DevBuzz (CF) ● Code Converter: C#/VB.NET | VB.NET/C# | VS 2005 add-in

  7. #7
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: Get the average of points

    Quote Originally Posted by David24
    ...i don't understand this either
    Code:
     *src |= *motion;
    All you have ti understand about C++ in this case is that the adress is src and what is stored under this adress you will get with *src, the ame is with motion. motion is the pointer to a storageplace and whats stored in it ( the vlue ) you get with*motion
    Code:
    src += srcOffset
    moves the pointer to the next adress where to get the next data.
    Code:
    pixelsChanged += (*motion & 1);
    The ambersand only would be used as an adress operato if it is &motion; in the given case the value stored on the adress of the pointer motion ( the value is *motion ) is the bitwiseAND with 0x00000001; so the result always compares the last bit of the motion value if it was set to one. If so the AND result is 1 if not its zero.
    The AND operator is used as a filter method tocheck if a defined bit is set or not.
    Does this help you or do you need more ?
    Last edited by JonnyPoet; February 13th, 2008 at 08:05 AM.
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  8. #8
    Join Date
    Jan 2008
    Posts
    10

    Re: Get the average of points

    both of your posts were helpful. do know of a good article that explains these aspects further, in more detail, or with more examples?

  9. #9
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: Get the average of points

    Quote Originally Posted by David24
    both of your posts were helpful. do know of a good article that explains these aspects further, in more detail, or with more examples?
    I'm sorry no as I have no actual books about old C and C++ I have learned this in the 80 th where this principes had been teached in a very extensive way. IMHO every simple basic book of C++ for beginners should teach such things
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  10. #10
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    1,080

    Re: Get the average of points

    There isn't really that much to it. Consider boolean logic. You know how to perform an AND, OR or XOR on two boolean values and what the expected results would be, yes? Bitwise logic is exactly the same. Bitwise logic really just performs boolean logic on each pair of corresponding bits. 1 represents True while 0 represents False and the results are exactly the same. Once you understand that it's all quite logical. That's a little bit of a nerd joke.
    Tutorials: Home & Learn | Start VB.NET | Learn VB.NET | C# Station | GotDotNet | Games in VB.NET 101 Samples: 2002 | 2003 | 2005 | More .NET 2.0 (VB.NET, C#) Articles: VB.NET | C# | ASP.NET | MoreFree Components: WFC | XPCC | ElementsEx | VBPP | Mentalis | ADO.NET/MySQL | VisualStyles | Charting (NPlot, ZedGraph) | iTextSharp (PDF) | SDF (CF) ● Free Literature: VB 2005 (eBook) | VB6 to VB.NET (eBook) | MSDN Magazine (CHM format) ● Bookmarks: MSDN | WinForms .NET | ASP.NET | WinForms FAQ | WebForms FAQ | GotDotNet | Code Project | DevBuzz (CF) ● Code Converter: C#/VB.NET | VB.NET/C# | VS 2005 add-in

  11. #11
    Join Date
    Jan 2008
    Posts
    10

    Re: Get the average of points

    i get it now (*motion & 1) is just a boolean operation returning 1 if true and 0 if false. how would i save the average of motion pixels as a point (of x and y coordinates)? essentially i want to store the average location of motion detected as a point..

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured