PDA

View Full Version : Stefan-Edge Detection Logic - Given by you.



atul
November 8, 2004, 10:59:11
Dear Stefan,

Thankyou very much for your help. I really appreciate your concern and help to me. I referred to the c# edge detection code given by you. I have implemented the same and tested it with Infrared Camera.

I am still not able to get the expected results. I personally feel that i am close to it since i have implemented the whole code logic given by you in my application properly.

I am sending you the delphi source code that i have implemented. please check the code and let me know what updations i have to make or where can i play around the code logic.

I am sending you two source codes as below:


I) With : ( (Abs( pPixel[0] + pPixel[1]+ pPixel[2]- pPixel[3]- pPixel[4] - pPixel[5]))/3 > Threshold)

{-----------------------------------------------------------------------------
Procedure: IsMotionDetected
Author: Atul Ashpalia
Description: Edge Detection Method to detect the motion
-----------------------------------------------------------------------------}
function TCommThread.IsMotionDetected(ACameraNo : Byte) : Boolean;
var
i, j, iArea, liSum, iPixelPoint : integer;
liCurPx, liNextCurPx, liKeyPx, liNextKeyPx : integer;

liKeyPx0,liKeyPx1,liKeyPx2,liKeyPx3,liKeyPx4,liKey Px5 : integer;
liCurPx0,liCurPx1,liCurPx2,liCurPx3,liCurPx4,liCur Px5 : integer;

pYuvBuf : PTYuvBuf;
curEdge : byte; keyEdge : byte; threshold : byte;
ChangedEdges : integer;
begin
//The below if routine gets executed only for the first time to copy the first image adress to asKeyBuf(Temp Memory).
//Next time it doesnot gets executed.
if iSetKeyMotion = 0 then
begin
ZeroMemory(@asKeyBuf, SizeOf(asKeyBuf)); //Initialises the memory
CopyMemory(@asKeyBuf, PChar(asYuvBuf[ACameraNo]), iQuadWidth * iQuadHeight * 2);
iSetKeyMotion := 1;
Exit;
end;

//Pointer to the Current Image Address
pYuvBuf := PTYuvBuf(asYuvBuf[ACameraNo]);

//Initializing the variables
curEdge := 0;
keyEdge := 0;
threshold := 50;
ChangedEdges := 0;

//Main Loop for comparing neighbouring pixels and inturn with the previous and the current frame images
for i := WorkConfig.Camera[ACameraNo].MotionDetectArea[iArea].Top to WorkConfig.Camera[ACameraNo].MotionDetectArea[iArea].Bottom - 1 do
begin
for j := WorkConfig.Camera[ACameraNo].MotionDetectArea[iArea].left to WorkConfig.Camera[ACameraNo].MotionDetectArea[iArea].right - 1 do
begin
iPixelPoint := (i * iQuadWidth) + (j);

//previous image
if asKeyBuf[ACameraNo][iPixelPoint] < 0 then
liKeyPx0 := 0
else
liKeyPx0 := asKeyBuf[ACameraNo][iPixelPoint];

if asKeyBuf[ACameraNo][iPixelPoint + 1] < 0 then
liKeyPx1 := 0
else
liKeyPx1 := asKeyBuf[ACameraNo][iPixelPoint + 1];

if asKeyBuf[ACameraNo][iPixelPoint + 2] < 0 then
liKeyPx2 := 0
else
liKeyPx2 := asKeyBuf[ACameraNo][iPixelPoint + 2];

if asKeyBuf[ACameraNo][iPixelPoint + 3] < 0 then
liKeyPx3 := 0
else
liKeyPx3 := asKeyBuf[ACameraNo][iPixelPoint + 3];

if asKeyBuf[ACameraNo][iPixelPoint + 4] < 0 then
liKeyPx4 := 0
else
liKeyPx4 := asKeyBuf[ACameraNo][iPixelPoint + 4];

if asKeyBuf[ACameraNo][iPixelPoint + 5] < 0 then
liKeyPx5 := 0
else
liKeyPx5 := asKeyBuf[ACameraNo][iPixelPoint + 5];

if ((ABS(liKeyPx0 + liKeyPx1 + liKeyPx2 - liKeyPx3 - liKeyPx4 - liKeyPx5))/5 > Threshold) then
keyEdge := 1
else
keyEdge := 0;


//current image
if pYuvBuf[iPixelPoint] < 0 then
liCurPx0 := 0
else
liCurPx0 := pYuvBuf[iPixelPoint];

if pYuvBuf[iPixelPoint + 1] < 0 then
liCurPx1 := 0
else
liCurPx1 := pYuvBuf[iPixelPoint + 1];

if pYuvBuf[iPixelPoint + 2] < 0 then
liCurPx2 := 0
else
liCurPx2 := pYuvBuf[iPixelPoint + 2];

if pYuvBuf[iPixelPoint + 3] < 0 then
liCurPx3 := 0
else
liCurPx3 := pYuvBuf[iPixelPoint + 3];

if pYuvBuf[iPixelPoint + 4] < 0 then
liCurPx4 := 0
else
liCurPx4 := pYuvBuf[iPixelPoint + 4];

if pYuvBuf[iPixelPoint + 5] < 0 then
liCurPx5 := 0
else
liCurPx5 := pYuvBuf[iPixelPoint + 5];

if ((ABS(liCurPx0 + liCurPx1 + liCurPx2 - liCurPx3 - liCurPx4 - liCurPx5))/5 > Threshold) then
curEdge := 1
else
curEdge := 0;


//if there is difference in pixel value then the 'ChangedEdges' value is incremented
if not (keyEdge = curEdge) then
Inc(ChangedEdges);
end;
end;

//initialises the temp memory
ZeroMemory(@asKeyBuf, SizeOf(asKeyBuf));

//copies the current image buffer to the temp memory. Now the temp memory will have the current image address
//and the the asYufBuf will take the next image address in the next run
CopyMemory(@asKeyBuf, PChar(asYuvBuf[ACameraNo]), iQuadWidth * iQuadHeight * 2);

//if ChangedEdges > 100, then it concludes that motion is detected
if (ChangedEdges > 100) then
Result := True
else
Result := False;
end;

************************************************** ***********


II) with : (Abs( pPixel[0] - pPixel[1]) > Threshold)

{-----------------------------------------------------------------------------
Procedure: IsMotionDetected
Author: Atul Ashpalia
Description: Edge Detection Method to detect the motion
-----------------------------------------------------------------------------}
function TCommThread.IsMotionDetected(ACameraNo : Byte) : Boolean;
var
i, j, iArea, liSum, iPixelPoint : integer;
liCurPx, liNextCurPx, liKeyPx, liNextKeyPx : integer;
pYuvBuf : PTYuvBuf;
curEdge : byte; keyEdge : byte; threshold : byte;
ChangedEdges : integer;
begin
//The below if routine gets executed only for the first time to copy the first image adress to asKeyBuf(Temp Memory).
//Next time it doesnot gets executed.
if iSetKeyMotion = 0 then
begin
ZeroMemory(@asKeyBuf, SizeOf(asKeyBuf)); //Initialises the memory
CopyMemory(@asKeyBuf, PChar(asYuvBuf[ACameraNo]), iQuadWidth * iQuadHeight * 2);
iSetKeyMotion := 1;
Exit;
end;

//Pointer to the Current Image Address
pYuvBuf := PTYuvBuf(asYuvBuf[ACameraNo]);

//Initializing the variables
curEdge := 0;
keyEdge := 0;
threshold := 50;
ChangedEdges := 0;

//Main Loop for comparing neighbouring pixels and inturn with the previous and the current frame images
for i := WorkConfig.Camera[ACameraNo].MotionDetectArea[iArea].Top to WorkConfig.Camera[ACameraNo].MotionDetectArea[iArea].Bottom - 1 do
begin
for j := WorkConfig.Camera[ACameraNo].MotionDetectArea[iArea].left to WorkConfig.Camera[ACameraNo].MotionDetectArea[iArea].right - 1 do
begin
iPixelPoint := (i * iQuadWidth) + (j);

//previous image
if asKeyBuf[ACameraNo][iPixelPoint] < 0 then
liKeyPx := 0
else
liKeyPx := asKeyBuf[ACameraNo][iPixelPoint];

if asKeyBuf[ACameraNo][iPixelPoint + 1] < 0 then
liNextKeyPx := 0
else
liNextKeyPx := asKeyBuf[ACameraNo][iPixelPoint + 1];

if (ABS(liKeyPx - liNextKeyPx) > Threshold) then
keyEdge := 1
else
keyEdge := 0;


//current image
if pYuvBuf[iPixelPoint] < 0 then
liCurPx := 0
else
liCurPx := pYuvBuf[iPixelPoint];

if pYuvBuf[iPixelPoint + 1] < 0 then
liNextCurPx := 0
else
liNextCurPx := pYuvBuf[iPixelPoint + 1];

if (ABS(liCurPx - liNextCurPx) > Threshold) then
curEdge := 1
else
curEdge := 0;

//if there is difference in pixel value then the 'ChangedEdges' value is incremented
if not (keyEdge = curEdge) then
Inc(ChangedEdges);
end;
end;

//initialises the temp memory
ZeroMemory(@asKeyBuf, SizeOf(asKeyBuf));

//copies the current image buffer to the temp memory. Now the temp memory will have the current image address
//and the the asYufBuf will take the next image address in the next run
CopyMemory(@asKeyBuf, PChar(asYuvBuf[ACameraNo]), iQuadWidth * iQuadHeight * 2);

//if ChangedEdges > 100, then it concludes that motion is detected
if (ChangedEdges > 100) then
Result := True
else
Result := False;
end;

************************************************** ************

The camera i am using is a high quality Infrared Night Vision Camera.

Testing:

when i focus the camera to an area where there is no motion but having light changes ( light flickering ), it still detects motion.
But in the first method, given above, it gives some hope of expected results since it stops recording in between and again starts the motion recording.

sorry for such a long mail.
Thanks to you in advance,

looking forward for your reply,
regards,
atul.

Stefan Geissler
November 8, 2004, 11:43:15
Hello Atul,

The problem using only one image is, that the noise produced by the camera can be detected as movement. Therefore you should play around with the threshold values and you should also visualize the edges, to see what happens.
If the light becomes darker, edges will be lost in order to the contrast goes down. Therefore a movement can be detected in changing light conditions. If you have a flickering light, you can be sure, the light is coming back. So you could accumulate the edges over a period of time by using e.g. 10 images to detect edges and compare them with the next 10 images. If an edge was detected in 3 of 10 images, there seems to be no edge. The there was an edge detected in 6 or more of 10 image, there could be an edge. So store a 1 in the edges array.
You also could add some images in sequence and calculate the average. This also removes noise and would remove the flickering of your light conditions. This would work with your first image difference algorithm.
I suggest to search the internet for motion detection algorithm and noise removement from images.
Try different methods to find one, that fits best to your light conditions.