|
-
February 9th, 2008, 08:52 PM
#1
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);
}
-
February 10th, 2008, 05:43 PM
#2
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
-
February 10th, 2008, 09:22 PM
#3
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.
-
February 11th, 2008, 07:39 AM
#4
Re: Get the average of points
 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
-
February 12th, 2008, 10:41 PM
#5
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
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;
}
-
February 12th, 2008, 10:57 PM
#6
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: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:is shorthand for this:
Code:
*src = *src | *motion;
Last edited by jmcilhinney; February 13th, 2008 at 07:18 PM.
-
February 13th, 2008, 07:55 AM
#7
Re: Get the average of points
 Originally Posted by David24
...i don't understand this either
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
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
-
February 18th, 2008, 07:30 PM
#8
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?
-
February 18th, 2008, 08:34 PM
#9
Re: Get the average of points
 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
-
February 18th, 2008, 09:45 PM
#10
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.
-
February 22nd, 2008, 12:48 PM
#11
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|