|
-
Nov 3rd, 2006, 06:52 PM
#1
Thread Starter
Hyperactive Member
movement detection
hi every on I got the Webcam to work and I also made to take pictures
the only thing i need to do is have a clue where to start for finding movement detection
thx for the future help
VS 2005 .....Framework SDK 3.0
"Its mostly the brave one who choose to not fight"
-
Nov 3rd, 2006, 07:01 PM
#2
Re: movement detection
I haven't worked on it myself, and there is probably a better format, but consider it like this:
An image stored as a bitmap would be an array of color values. Movement happens when the new image doesn't match the existing image. You could compare byte by byte to look for change, but I suspect that you'd get plenty of noise that way. I would be trying a solution of averaging bytes in the image to compress it down to a smaller size, and comparing the averaged saved image to the new averaged image, while allowing for a little tolerance for change.
My usual boring signature: Nothing
 
-
Nov 3rd, 2006, 07:15 PM
#3
Re: movement detection
Maybe you could compare the file size of the images. Both my cams generate different sizes when something moves(appears) but maybe not all (cams) are like that.
-
Nov 4th, 2006, 11:58 AM
#4
Thread Starter
Hyperactive Member
Re: movement detection
I view my webcam in a picture box
i tryed converting the bmp into bytes and compare then but for some resons the bytes differ even when the cam is facing a white wall with no movements ...... it tryed to determine how much they differ , they match by only 12% or 8%
thx for the future help
I will post my code soon I am in my other computer
Last edited by demon.KILER; Nov 4th, 2006 at 12:05 PM.
VS 2005 .....Framework SDK 3.0
"Its mostly the brave one who choose to not fight"
-
Nov 4th, 2006, 12:31 PM
#5
Re: movement detection
Well, you're on your way. I expected that they would vary a pretty good amount. Even if you had one byte per pixel, a ten percent change might not be all that noticeable.
The next thing I would try would be to section the image into 9,16, or 25 square images (those are square numbers, of course). Then average all the bytes, and look for a change when the average changes by 10% or so. The idea being that the change in an individual pixel would probably be pretty silly, but the change in the average value of a region of the image would be significant.
If the camera was pointed at a blank wall, and the individual pixels are changing by 10% or so, would the average value change by 10%? Probably not, unless those changes are biased in one direction or the other. Therefore, averaging a bundle of pixels should dampen the fluctuations in any individual pixel. Thus, you want a number of pixels to average, but what number? Well, if your image is square, then divide it into sufficient sub-sections that a change in a single subsection would be significant. This could be as big as averaging the entire image, and looking for a change as small as 1% or so. Alternatively, if the field of view is wide enough, you might want to catch a change in a quarter of the image, a ninth of the image, etc.
An alternative to consider would be to think about what would happen if the camera was looking at a room, and a person walked into the room. They would intrude onto one side of the image, then move across the image. Therefore, averaging a couple of columns of pixels might also make sense.
The last consideration would be the rate of change. If a light is flipped on in the room with the camera, all pixels will jump upward by a considerable amount, as will the average (any average). However, if you are comparing images every half hour, then sunrise would have the same impact. Thus, do you compare by the second, the minute, etc. The answer depends on what you are expecting to capture.
My usual boring signature: Nothing
 
-
Nov 4th, 2006, 01:01 PM
#6
Re: movement detection
It's a bit off the wall, but could you do an XOR operation on the two images? Any differences would indicate change therefore movement...
-
Nov 4th, 2006, 01:30 PM
#7
Thread Starter
Hyperactive Member
Re: movement detection
how do I that XOR ???
Shaggy Hiker I am trying urs now
Last edited by demon.KILER; Nov 4th, 2006 at 01:51 PM.
VS 2005 .....Framework SDK 3.0
"Its mostly the brave one who choose to not fight"
-
Nov 4th, 2006, 02:22 PM
#8
Re: movement detection
The XOR solution won't work if you have as much fluctuation in your bytes as you report.
My usual boring signature: Nothing
 
-
Nov 4th, 2006, 07:57 PM
#9
Thread Starter
Hyperactive Member
Re: movement detection
checking pixels by pixels took for ever
VS 2005 .....Framework SDK 3.0
"Its mostly the brave one who choose to not fight"
-
Nov 5th, 2006, 04:39 PM
#10
Thread Starter
Hyperactive Member
Re: movement detection
The next thing I would try would be to section the image into 9,16, or 25 square images (those are square numbers, of course). Then average all the bytes, and look for a change when the average changes by 10% or so. The idea being that the change in an individual pixel would probably be pretty silly, but the change in the average value of a region of the image would be significant.
I don't know how to do that
I am looking in internet to do that
VS 2005 .....Framework SDK 3.0
"Its mostly the brave one who choose to not fight"
-
Nov 5th, 2006, 04:55 PM
#11
Re: movement detection
Ive done an app that takes a picture every 10th second and it compares the picture with the previous one to detect changes. Im not on pc right now but when i am i can show u my code.
-
Nov 5th, 2006, 05:11 PM
#12
Thread Starter
Hyperactive Member
VS 2005 .....Framework SDK 3.0
"Its mostly the brave one who choose to not fight"
-
Nov 5th, 2006, 10:19 PM
#13
Re: movement detection
If you have your pixels in a 2D array (equating to the x,y of the image), then the first thing I would try would be to calculate an average value for each x or each y by summing the pixels in the column/row, and dividing by the number of columns/rows. This is probably the fastest technique, and may well be sufficient. If the image is 320x240, then getting an average the 320 columns might be sufficient. I'd try that before going for anything more. However, I'd mostly try that because it would be relatively easy. By the way, if the array is only 1D, then you would average each N bytes, where N is the number of columns (320 in the above example).
A better technique would be to take a bundle of images real fast, and average them. If you could take a picture every 1/10th second, then you'd have ten in a second. Averaging them pixel by pixel would be SLOW, but ideal. For one thing, you could calculate the average and standard deviation of the pixels, and say that anything more that 2 standard deviations from the average is a change. However, like I said, this would be SLOW. However, why bother checking every pixel? How much area does a single pixel cover, a tenth of a centimeter? Less? You might divide the image into a bunch of regions (in your head, it doesn't have to be done in reality), and pick a pixel, or a couple of pixels in each region and only calculate the values for them. This would vastly reduce the number of calculations. A change in any one might be enough of a trigger, or you might go for a change in multiple regions, so that your detector is sensitive enough to catch a human moving through the region, but would let the cat through.
My usual boring signature: Nothing
 
-
Nov 5th, 2006, 10:27 PM
#14
Re: movement detection
Funny thing about this question is that I have considered doing something like this myself, but I don't yet know whether I will or not. Thinking about this question has helped me think about how I will handle it if I ever do end up doing it. I'm leaning towards the idea of averaging the pixels and figuring the standard deviation, but I'd be looking for fish, so I'd have to use some pretty small regions, or all of the pixels. It would be easier in black and white since....well, I'm off onto a different issue.
Keep on posting.
My usual boring signature: Nothing
 
-
Nov 6th, 2006, 12:28 PM
#15
Thread Starter
Hyperactive Member
VS 2005 .....Framework SDK 3.0
"Its mostly the brave one who choose to not fight"
-
Nov 6th, 2006, 05:49 PM
#16
Re: movement detection
This is what I used to compare two images, I know it looks a bit **** and so...but keep in mind that it was a long time since i wrote it...and hey, it works for me 
Ive written some explanation comments in the code, please ask if anything is unclear.
VB Code:
Private Sub ProcessImage()
Dim file As String = SavedFilePath
PicCap.Image = Nothing
Dim bm As Bitmap
Try
bm = Image.FromFile(filename)
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Sub
End Try
Dim y As Integer
Dim r As Double = 0
Dim g As Double = 0
Dim b As Double = 0
Dim pxCount As Long = 0
'Loop through the image and add the rgb values to their respective variable.
For x as Integer = 0 To 319
For y as Integer = 0 To 239
pxCount += 1
r += bm.GetPixel(x, y).R
g += bm.GetPixel(x, y).G
b += bm.GetPixel(x, y).B
Next
Next
'The current NewR, NewG and NewB values comes from the PREVIOUS image, so those values goes into the "old" variables instead.
OldR = NewR
OldG = NewG
OldB = NewB
'And set the "New" variables with the current images R, G and B values divided by the number of pixels in the image.
NewR = r / pxCount
NewG = g / pxCount
NewB = b / pxCount
'Exit the sub if OldR is -1(That means that there was no previous image)
If OldR = -1 Then
Exit Sub
End If
'Here comes the code to compare the old and the new R, G and B values:
If OldR > NewR Then
If (OldR - NewR) >= Picky Then
ListAdd(file)
Exit Sub
End If
ElseIf NewR > OldR Then
If (NewR - OldR) >= Picky Then
ListAdd(file)
Exit Sub
End If
End If
If OldG > NewG Then
If (OldG - NewG) >= Picky Then
ListAdd(file)
Exit Sub
End If
ElseIf NewG > OldG Then
If (NewG - OldG) >= Picky Then
ListAdd(file)
Exit Sub
End If
End If
If OldB > NewB Then
If (OldB - NewB) >= Picky Then
ListAdd(file)
Exit Sub
End If
ElseIf NewB > OldB Then
If (NewB - OldB) >= Picky Then
ListAdd(file)
Exit Sub
End If
End If
'Dispose the bitmap.
bm.Dispose()
End Sub
What im doing if it detects any changes is just to call the ListAdd sub, but you can ofcourse change it to whatever you like. And oh, almost forgot..the "Picky" (hehe) variable is a value that the user sets in settings to change how sensitive it should be. (A value from 1 to 24, where 4 is default, 1 is very sensitive and 25 is very unsensitive)..
Im almost embarrased to show this old code...but if its to any help to you then its good.
-
Nov 6th, 2006, 06:07 PM
#17
Thread Starter
Hyperactive Member
Re: movement detection
this code is perfect except It will take for ever .......
didn't u see my last post It is almost like that one I got it from the internet
thx for ur help
this looks challenging
VS 2005 .....Framework SDK 3.0
"Its mostly the brave one who choose to not fight"
-
Nov 6th, 2006, 11:01 PM
#18
Re: movement detection
Yeah, that loop will take a looooong time because of the number of pixels, but do you need all of them? Why not just slap a Step 10 onto the end of both For statements.
As it stands, you will be looping a total of 76,800 times. By doing the step 10, you will cut that down to 768, a significant reduction. So what do you lose? Some resolution, but not all that much. You can figure out how much directly by taking the width of the field of view and divide by 320.
Make it a Step 12, and you cut it by a factor of 144, which would be even faster. Just figure out how wide a single pixel covers, and you can calculate the rough accuracy you need to capture the type of motion you are expecting. Then you can figure out how many pixels you really need to check.
My usual boring signature: Nothing
 
-
Nov 6th, 2006, 11:06 PM
#19
Re: movement detection
You may be able to get a further minor speed increase by changing those If statements to:
If Math.Abs(NewG-OldG)>picky then
This removes one conditional in favor of an absolute value. Depending on the implementation of abs, this would probably be a bit faster.
My usual boring signature: Nothing
 
-
Nov 7th, 2006, 05:46 PM
#20
Thread Starter
Hyperactive Member
Re: movement detection
yeah : but Not fast enough for what I am doing Comapring every 4 sec with that loop the user's computer will be messsssssed up
Any way for now I am going try and use this for now
the MD5 hash thing does not work
I am going to post my whole messed up code today take a look at it an inform me for any changes .....I did not do every thing by myself most of them is from internet but I now know how to do that
VS 2005 .....Framework SDK 3.0
"Its mostly the brave one who choose to not fight"
-
Nov 7th, 2006, 06:09 PM
#21
Re: movement detection
Good points here by shaggy. Nah I think it'll do just fine comparing it every 4th seconds, just put it in a thread..and set its priority to whatever is needed.
-
Nov 7th, 2006, 07:36 PM
#22
Thread Starter
Hyperactive Member
Re: movement detection
This code is my first tries with out adding atheist's code
VB Code:
Imports System.Runtime.InteropServices
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography
Imports System.Threading.Thread
Public Class Webcam
Public Event cammove()
Const WM_CAP As Short = &H400S
Const WM_CAP_DRIVER_CONNECT As Integer = WM_CAP + 10
Const WM_CAP_DRIVER_DISCONNECT As Integer = WM_CAP + 11
Const WM_CAP_EDIT_COPY As Integer = WM_CAP + 30
Const WM_CAP_SET_PREVIEW As Integer = WM_CAP + 50
Const WM_CAP_SET_PREVIEWRATE As Integer = WM_CAP + 52
Const WM_CAP_SET_SCALE As Integer = WM_CAP + 53
Const WS_CHILD As Integer = &H40000000
Const WS_VISIBLE As Integer = &H10000000
Const SWP_NOMOVE As Short = &H2S
Const SWP_NOSIZE As Short = 1
Const SWP_NOZORDER As Short = &H4S
Const HWND_BOTTOM As Short = 1
Dim hHwnd As Integer
Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, _
<MarshalAs(UnmanagedType.AsAny)> ByVal lParam As Object) As Integer
Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Integer, _
ByVal hWndInsertAfter As Integer, ByVal x As Integer, ByVal y As Integer, _
ByVal cx As Integer, ByVal cy As Integer, ByVal wFlags As Integer) As Integer
Declare Function DestroyWindow Lib "user32" (ByVal hndw As Integer) As Boolean
Declare Function capCreateCaptureWindowA Lib "avicap32.dll" _
(ByVal lpszWindowName As String, ByVal dwStyle As Integer, _
ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, _
ByVal nHeight As Short, ByVal hWndParent As Integer, _
ByVal nID As Integer) As Integer
Declare Function capGetDriverDescriptionA Lib "avicap32.dll" (ByVal wDriver As Short, _
ByVal lpszName As String, ByVal cbName As Integer, ByVal lpszVer As String, _
ByVal cbVer As Integer) As Boolean
Dim defaultid As Integer
Function start(Optional ByVal Deviceid As Integer = 0)
Try
Timer1.Enabled = True
Timer2.Enabled = True
defaultid = Deviceid
Dim iHeight As Integer = picCapture.Height
Dim iWidth As Integer = picCapture.Width
hHwnd = capCreateCaptureWindowA(Deviceid, WS_VISIBLE Or WS_CHILD, 0, 0, 640, _
480, picCapture.Handle.ToInt32, 0)
If SendMessage(hHwnd, WM_CAP_DRIVER_CONNECT, Deviceid, 0) Then
SendMessage(hHwnd, WM_CAP_SET_SCALE, True, 0)
SendMessage(hHwnd, WM_CAP_SET_PREVIEWRATE, 100, 0)
SendMessage(hHwnd, WM_CAP_SET_PREVIEW, True, 0)
SetWindowPos(hHwnd, HWND_BOTTOM, 0, 0, picCapture.Width, picCapture.Height, _
SWP_NOMOVE Or SWP_NOZORDER)
Else
DestroyWindow(hHwnd)
End If
Timer1.Enabled = True
Return True
Catch ex As Exception
Return ex.Message
End Try
End Function
Function stopwebcam()
Try
Dim Deviceid As Integer = defaultid
SendMessage(hHwnd, WM_CAP_DRIVER_DISCONNECT, Deviceid, 0)
DestroyWindow(hHwnd)
Return True
Catch ex As Exception
Return ex.Message
End Try
End Function
Function takephoto()
Try
Dim data As IDataObject
Dim img
SendMessage(hHwnd, WM_CAP_EDIT_COPY, 25, 25)
data = Clipboard.GetDataObject()
If data.GetDataPresent(GetType(System.Drawing.Bitmap)) Then
img = CType(data.GetData(GetType(System.Drawing.Bitmap)), Image)
End If
Return img
Catch ex As Exception
Return ex.Message
End Try
End Function
Dim hashone As String
Dim hashtwo As String
Dim issame As Boolean = False
Dim buffer() As Byte
Dim img1
Sub timer11()
img1 = takephoto()
Dim ic As New ImageConverter
buffer = CType(ic.ConvertTo(p1.Image, GetType(Byte())), Byte())
Dim Md5 As New MD5CryptoServiceProvider()
hashone = Convert.ToBase64String(Md5.ComputeHash(buffer))
ListBox1.Items.Add(hashone)
l1.Text = hashone
isnow = False
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
timer11()
End Sub
Dim isnow As Boolean = True
Dim img2
Sub timer22()
img2 = takephoto()
Dim Md5 As New MD5CryptoServiceProvider()
Dim ic As New ImageConverter
Dim buffer2() As Byte
buffer2 = CType(ic.ConvertTo(p2.Image, GetType(Byte())), Byte())
hashtwo = Convert.ToBase64String(Md5.ComputeHash(buffer2))
l2.Text = hashtwo
ListBox2.Items.Add(hashtwo)
comp(buffer, buffer2)
isnow = True
End Sub
Private Sub Webcam_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
start()
End Sub
Private Sub comp(ByVal byte1() As Byte, ByVal byte2() As Byte)
Dim i As Integer = 0
Dim total As Integer = 0
Dim average As Integer = 0
Dim totalbytes = byte1.GetUpperBound(0) - 1
Try
For i = 0 To byte1.GetUpperBound(0)
If byte1(i) = byte2(i) Then
total = total + 1
End If
Next
average = CInt((total / totalbytes))
If average > 50 Then
mo.Text = ""
Else
mo.Text = "moving"
End If
Catch ex As Exception
End Try
End Sub
Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
timer22()
End Sub
End Class
VS 2005 .....Framework SDK 3.0
"Its mostly the brave one who choose to not fight"
-
Nov 7th, 2006, 07:54 PM
#23
Re: movement detection
Woooof, will that ever work? You already stated that comparing two bytes almost never produced an equality, yet you are doing it anyways without any wiggle room.
You can still improve the code by using Atheists 'picky' comparison. Just compare whether abs(byte1(i)-byte2(i))<Picky, where Picky is the amount of flux you are willing to allow for the two to still be considered a match.
You can also speed it up quite a bit by not comparing all the bytes, as I stated before. You don't get the same benefit from adding Step 10 to the loop in comp(), since it will only cut the pixel count by a factor of 10, rather than 100, but of course, you could fix that by increasing the Step.
My usual boring signature: Nothing
 
-
Nov 7th, 2006, 08:05 PM
#24
Thread Starter
Hyperactive Member
Re: movement detection
yeah this was a messed up code
VS 2005 .....Framework SDK 3.0
"Its mostly the brave one who choose to not fight"
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
|