Results 1 to 24 of 24

Thread: movement detection

  1. #1

    Thread Starter
    Hyperactive Member demon.KILER's Avatar
    Join Date
    Jul 2006
    Location
    I cannot remember !?
    Posts
    408

    Question 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"

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    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

  3. #3
    Frenzied Member
    Join Date
    Mar 2005
    Location
    Sector 001
    Posts
    1,577

    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.
    VB 2005, Win Xp Pro sp2

  4. #4

    Thread Starter
    Hyperactive Member demon.KILER's Avatar
    Join Date
    Jul 2006
    Location
    I cannot remember !?
    Posts
    408

    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"

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    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

  6. #6
    PowerPoster
    Join Date
    Jul 2002
    Location
    Dublin, Ireland
    Posts
    2,148

    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...

  7. #7

    Thread Starter
    Hyperactive Member demon.KILER's Avatar
    Join Date
    Jul 2006
    Location
    I cannot remember !?
    Posts
    408

    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"

  8. #8
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    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

  9. #9

    Thread Starter
    Hyperactive Member demon.KILER's Avatar
    Join Date
    Jul 2006
    Location
    I cannot remember !?
    Posts
    408

    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"

  10. #10

    Thread Starter
    Hyperactive Member demon.KILER's Avatar
    Join Date
    Jul 2006
    Location
    I cannot remember !?
    Posts
    408

    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"

  11. #11
    Raging swede Atheist's Avatar
    Join Date
    Aug 2005
    Location
    Sweden
    Posts
    8,018

    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.
    Rate posts that helped you. I do not reply to PM's with coding questions.
    How to Get Your Questions Answered
    Current project: tunaOS
    Me on.. BitBucket, Google Code, Github (pretty empty)

  12. #12

    Thread Starter
    Hyperactive Member demon.KILER's Avatar
    Join Date
    Jul 2006
    Location
    I cannot remember !?
    Posts
    408

    Re: movement detection

    thx Atheist
    VS 2005 .....Framework SDK 3.0

    "Its mostly the brave one who choose to not fight"

  13. #13
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    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

  14. #14
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    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

  15. #15

    Thread Starter
    Hyperactive Member demon.KILER's Avatar
    Join Date
    Jul 2006
    Location
    I cannot remember !?
    Posts
    408

    Re: movement detection

    VS 2005 .....Framework SDK 3.0

    "Its mostly the brave one who choose to not fight"

  16. #16
    Raging swede Atheist's Avatar
    Join Date
    Aug 2005
    Location
    Sweden
    Posts
    8,018

    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:
    1. Private Sub ProcessImage()
    2.         Dim file As String = SavedFilePath
    3.         PicCap.Image = Nothing
    4.         Dim bm As Bitmap
    5.         Try
    6.             bm = Image.FromFile(filename)
    7.         Catch ex As Exception
    8.             MessageBox.Show(ex.Message)
    9.             Exit Sub
    10.         End Try
    11.         Dim y As Integer
    12.         Dim r As Double = 0
    13.         Dim g As Double = 0
    14.         Dim b As Double = 0
    15.         Dim pxCount As Long = 0
    16.         'Loop through the image and add the rgb values to their respective variable.
    17.         For x as Integer = 0 To 319
    18.             For y as Integer = 0 To 239
    19.                 pxCount += 1
    20.                 r += bm.GetPixel(x, y).R
    21.                 g += bm.GetPixel(x, y).G
    22.                 b += bm.GetPixel(x, y).B
    23.             Next
    24.         Next
    25.         'The current NewR, NewG and NewB values comes from the PREVIOUS image, so those values goes into the "old" variables instead.
    26.         OldR = NewR
    27.         OldG = NewG
    28.         OldB = NewB
    29.         'And set the "New" variables with the current images R, G and B values divided by the number of pixels in the image.
    30.         NewR = r / pxCount
    31.         NewG = g / pxCount
    32.         NewB = b / pxCount
    33.         'Exit the sub if OldR is -1(That means that there was no previous image)
    34.         If OldR = -1 Then
    35.             Exit Sub
    36.         End If
    37.         'Here comes the code to compare the old and the new R, G and B values:
    38.         If OldR > NewR Then
    39.             If (OldR - NewR) >= Picky Then
    40.                 ListAdd(file)
    41.                 Exit Sub
    42.             End If
    43.         ElseIf NewR > OldR Then
    44.             If (NewR - OldR) >= Picky Then
    45.                 ListAdd(file)
    46.                 Exit Sub
    47.             End If
    48.         End If
    49.  
    50.         If OldG > NewG Then
    51.             If (OldG - NewG) >= Picky Then
    52.                 ListAdd(file)
    53.                 Exit Sub
    54.             End If
    55.         ElseIf NewG > OldG Then
    56.             If (NewG - OldG) >= Picky Then
    57.                 ListAdd(file)
    58.                 Exit Sub
    59.             End If
    60.         End If
    61.  
    62.         If OldB > NewB Then
    63.             If (OldB - NewB) >= Picky Then
    64.                 ListAdd(file)
    65.                 Exit Sub
    66.             End If
    67.         ElseIf NewB > OldB Then
    68.             If (NewB - OldB) >= Picky Then
    69.                 ListAdd(file)
    70.                 Exit Sub
    71.             End If
    72.         End If
    73.         'Dispose the bitmap.
    74.         bm.Dispose()
    75.     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.
    Rate posts that helped you. I do not reply to PM's with coding questions.
    How to Get Your Questions Answered
    Current project: tunaOS
    Me on.. BitBucket, Google Code, Github (pretty empty)

  17. #17

    Thread Starter
    Hyperactive Member demon.KILER's Avatar
    Join Date
    Jul 2006
    Location
    I cannot remember !?
    Posts
    408

    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"

  18. #18
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    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

  19. #19
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    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

  20. #20

    Thread Starter
    Hyperactive Member demon.KILER's Avatar
    Join Date
    Jul 2006
    Location
    I cannot remember !?
    Posts
    408

    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"

  21. #21
    Raging swede Atheist's Avatar
    Join Date
    Aug 2005
    Location
    Sweden
    Posts
    8,018

    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.
    Rate posts that helped you. I do not reply to PM's with coding questions.
    How to Get Your Questions Answered
    Current project: tunaOS
    Me on.. BitBucket, Google Code, Github (pretty empty)

  22. #22

    Thread Starter
    Hyperactive Member demon.KILER's Avatar
    Join Date
    Jul 2006
    Location
    I cannot remember !?
    Posts
    408

    Re: movement detection

    This code is my first tries with out adding atheist's code


    VB Code:
    1. Imports System.Runtime.InteropServices
    2. Imports System.IO
    3. Imports System.Text
    4. Imports System.Security.Cryptography
    5. Imports System.Threading.Thread
    6. Public Class Webcam
    7.     Public Event cammove()
    8.     Const WM_CAP As Short = &H400S
    9.  
    10.     Const WM_CAP_DRIVER_CONNECT As Integer = WM_CAP + 10
    11.     Const WM_CAP_DRIVER_DISCONNECT As Integer = WM_CAP + 11
    12.     Const WM_CAP_EDIT_COPY As Integer = WM_CAP + 30
    13.  
    14.     Const WM_CAP_SET_PREVIEW As Integer = WM_CAP + 50
    15.     Const WM_CAP_SET_PREVIEWRATE As Integer = WM_CAP + 52
    16.     Const WM_CAP_SET_SCALE As Integer = WM_CAP + 53
    17.     Const WS_CHILD As Integer = &H40000000
    18.     Const WS_VISIBLE As Integer = &H10000000
    19.     Const SWP_NOMOVE As Short = &H2S
    20.     Const SWP_NOSIZE As Short = 1
    21.     Const SWP_NOZORDER As Short = &H4S
    22.     Const HWND_BOTTOM As Short = 1
    23.  
    24.  
    25.     Dim hHwnd As Integer
    26.     Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
    27.         (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, _
    28.         <MarshalAs(UnmanagedType.AsAny)> ByVal lParam As Object) As Integer
    29.  
    30.     Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Integer, _
    31.         ByVal hWndInsertAfter As Integer, ByVal x As Integer, ByVal y As Integer, _
    32.         ByVal cx As Integer, ByVal cy As Integer, ByVal wFlags As Integer) As Integer
    33.  
    34.     Declare Function DestroyWindow Lib "user32" (ByVal hndw As Integer) As Boolean
    35.  
    36.     Declare Function capCreateCaptureWindowA Lib "avicap32.dll" _
    37.         (ByVal lpszWindowName As String, ByVal dwStyle As Integer, _
    38.         ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, _
    39.         ByVal nHeight As Short, ByVal hWndParent As Integer, _
    40.         ByVal nID As Integer) As Integer
    41.  
    42.     Declare Function capGetDriverDescriptionA Lib "avicap32.dll" (ByVal wDriver As Short, _
    43.         ByVal lpszName As String, ByVal cbName As Integer, ByVal lpszVer As String, _
    44.         ByVal cbVer As Integer) As Boolean
    45.     Dim defaultid As Integer
    46.     Function start(Optional ByVal Deviceid As Integer = 0)
    47.         Try
    48.             Timer1.Enabled = True
    49.             Timer2.Enabled = True
    50.             defaultid = Deviceid
    51.             Dim iHeight As Integer = picCapture.Height
    52.             Dim iWidth As Integer = picCapture.Width
    53.  
    54.             hHwnd = capCreateCaptureWindowA(Deviceid, WS_VISIBLE Or WS_CHILD, 0, 0, 640, _
    55.                 480, picCapture.Handle.ToInt32, 0)
    56.  
    57.  
    58.             If SendMessage(hHwnd, WM_CAP_DRIVER_CONNECT, Deviceid, 0) Then
    59.  
    60.                 SendMessage(hHwnd, WM_CAP_SET_SCALE, True, 0)
    61.  
    62.  
    63.                 SendMessage(hHwnd, WM_CAP_SET_PREVIEWRATE, 100, 0)
    64.  
    65.  
    66.                 SendMessage(hHwnd, WM_CAP_SET_PREVIEW, True, 0)
    67.  
    68.  
    69.                 SetWindowPos(hHwnd, HWND_BOTTOM, 0, 0, picCapture.Width, picCapture.Height, _
    70.                         SWP_NOMOVE Or SWP_NOZORDER)
    71.  
    72.  
    73.             Else
    74.                 DestroyWindow(hHwnd)
    75.  
    76.             End If
    77.             Timer1.Enabled = True
    78.             Return True
    79.         Catch ex As Exception
    80.             Return ex.Message
    81.         End Try
    82.  
    83.     End Function
    84.     Function stopwebcam()
    85.         Try
    86.             Dim Deviceid As Integer = defaultid
    87.  
    88.             SendMessage(hHwnd, WM_CAP_DRIVER_DISCONNECT, Deviceid, 0)
    89.             DestroyWindow(hHwnd)
    90.             Return True
    91.         Catch ex As Exception
    92.             Return ex.Message
    93.         End Try
    94.  
    95.     End Function
    96.     Function takephoto()
    97.         Try
    98.             Dim data As IDataObject
    99.             Dim img
    100.  
    101.             SendMessage(hHwnd, WM_CAP_EDIT_COPY, 25, 25)
    102.  
    103.             data = Clipboard.GetDataObject()
    104.             If data.GetDataPresent(GetType(System.Drawing.Bitmap)) Then
    105.                 img = CType(data.GetData(GetType(System.Drawing.Bitmap)), Image)
    106.  
    107.             End If
    108.             Return img
    109.  
    110.         Catch ex As Exception
    111.             Return ex.Message
    112.         End Try
    113.  
    114.     End Function
    115.     Dim hashone As String
    116.     Dim hashtwo As String
    117.     Dim issame As Boolean = False
    118.     Dim buffer() As Byte
    119.     Dim img1
    120.     Sub timer11()
    121.  
    122.         img1 = takephoto()
    123.  
    124.  
    125.         Dim ic As New ImageConverter
    126.         buffer = CType(ic.ConvertTo(p1.Image, GetType(Byte())), Byte())
    127.  
    128.         Dim Md5 As New MD5CryptoServiceProvider()
    129.         hashone = Convert.ToBase64String(Md5.ComputeHash(buffer))
    130.         ListBox1.Items.Add(hashone)
    131.         l1.Text = hashone
    132.         isnow = False
    133.  
    134.  
    135.  
    136.  
    137.  
    138.     End Sub
    139.     Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    140.         timer11()
    141.     End Sub
    142.  
    143.     Dim isnow As Boolean = True
    144.     Dim img2
    145.     Sub timer22()
    146.         img2 = takephoto()
    147.  
    148.  
    149.         Dim Md5 As New MD5CryptoServiceProvider()
    150.         Dim ic As New ImageConverter
    151.         Dim buffer2() As Byte
    152.         buffer2 = CType(ic.ConvertTo(p2.Image, GetType(Byte())), Byte())
    153.         hashtwo = Convert.ToBase64String(Md5.ComputeHash(buffer2))
    154.         l2.Text = hashtwo
    155.         ListBox2.Items.Add(hashtwo)
    156.         comp(buffer, buffer2)
    157.         isnow = True
    158.  
    159.     End Sub
    160.  
    161.     Private Sub Webcam_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    162.        
    163.         start()
    164.     End Sub
    165.     Private Sub comp(ByVal byte1() As Byte, ByVal byte2() As Byte)
    166.         Dim i As Integer = 0
    167.         Dim total As Integer = 0
    168.         Dim average As Integer = 0
    169.         Dim totalbytes = byte1.GetUpperBound(0) - 1
    170.         Try
    171.  
    172.             For i = 0 To byte1.GetUpperBound(0)
    173.                 If byte1(i) = byte2(i) Then
    174.                     total = total + 1
    175.                 End If
    176.             Next
    177.             average = CInt((total / totalbytes))
    178.             If average > 50 Then
    179.                 mo.Text = ""
    180.             Else
    181.                 mo.Text = "moving"
    182.             End If
    183.         Catch ex As Exception
    184.  
    185.         End Try
    186.     End Sub
    187.  
    188.     Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
    189.         timer22()
    190.     End Sub
    191. End Class
    VS 2005 .....Framework SDK 3.0

    "Its mostly the brave one who choose to not fight"

  23. #23
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    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

  24. #24

    Thread Starter
    Hyperactive Member demon.KILER's Avatar
    Join Date
    Jul 2006
    Location
    I cannot remember !?
    Posts
    408

    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
  •  



Click Here to Expand Forum to Full Width