Nån som har koll på om "Motion Detection" går att ordna i VB. Hej Jag har tänkt mig så här: Det bästa sättet är att prova sig fram:-) Hej igen Med en vanlig for-loop tar 2500 PIXEL Ca 1 sek Kan du eller nån annan inte skriva ett exempel? Nu vet jag ju inte hur du ska använda detta men en idé är att ge användaren möjlighet att markera vilken del av bilden som inte får ändras utan att ge larm. Tex så kan du ha en kamera riktat mot en bil. Det finns träd, buskar osv som kan röra på sig. Genom att användaren kan markera tex själva bilen eller kanske enbart en dörr så slipper du bruset samt minder antal pixlar som ska jämföras. Detta är ingen ny idé utan det finns i en del av dom övervakningsutrustningarna som säljs. hej Hej igen Jo utan dem går det mkt fortare. Men som det är nu gör ju loopen inget utan bara går igenom. Hej Behövs inte vara trassligt med olika störningar. Börja med att titta på vad ni vill ska larma. En person som går för bi tex. Då sker förändringar vertikalt genom bilden. Menar du att en referens-bild skall tagas bara var 60:e sekund. Programmet ska inte användas till nåt övervakningssytem så det måste inte vara sådär 100% tillförlitligt. Hejsan sven... Skulle det inte vara snabbare med GetBitmapBits eller GetDIBits? Hej Hej Hej Jag kör på en 500 MHz, men vill ju att det ska gå på mindre. HejMotion
Alltså om man har en webkamera kunna avgöra om nåt rör sig i bilden.
Kod eller ocx för att jämföra bilder.Sv: Motion
det borde gå med API GetPixel
om man då tar ner bilden till tex 100 * 100 pixel
så blir det 100000 pixel att scanna ,tar säkert inte mer
än 100 ms att utföra och jämföra.
Tror
SvenSv: Motion
Först tar programmet en bild
Sen tar den en till
Sedan jämför den pixlarna, t.ex. pixel 1x1 om den har ändrats mycket.
Om den har ändrats lite så är det ju bara kamerans flimmer.
Men skulle detta överhuvudtaget gå i Visual Basic?
Hur långt tid skulle det ta att gå igenom en bild? [352x288] Ca 100.000 pixels...Sv: Motion
Du kan även göra rutinen till en dll, det kan gå lite snabbare att använda en sådan funktion i vb. Räcker inte farten kanske du känner någon som kan skriva den i c++ och göra en dll åt dig.
/PelleSv: Motion
>Sedan jämför den pixlarna, t.ex. pixel 1x1 om den har ändrats >mycket.
Det skall inte vara något problem.Man får välja ut ett område
på bilden som är strategiskt tex en vit bakgrund som
plötsligt skymms av något mörkt.
Man får checka minst 1000 pixel någonstans .
Intressant projekt jag hjälper gärna till med scanner program
mvh
SvenSv: Motion
att gå igenom och registrera färgen på varje.
Exempel:
------
Dim xyColor As Long, xpix As Long, ypix As Long
Dim i As Long, j As Long
xpix = picBild.ScaleWidth
ypix = picBild.ScaleHeight
For j = 0 To ypix - 1
For i = 0 To xpix - 1
DoEvents
xyColor = picBild.Point(i, j)
Text4 = Text4 + 1 'Antal pixel kollade
Next i
Next jSv: Motion
Jag vet inte hur jag skall få det fortare :(Sv: Motion
Lycka till.
/JanneSv: Motion
Det finns många vinklar på detta problem.
Hur ändras dagsljuset mm. Eventuellt får man ta en referens bild
en gång i minuten m.m. Dvs man måste skräddarsy för
den miljö som skall övervakas.
Sven igen
Intressan projekt skall skriva ett exempel när jag morrnat mig
DSSv: Motion
>Text4 = Text4 + 1 'Antal pixel kollade
Den här raden stjäl massor av tid, DoEvents själ tid
När det är så liten loop kan du ta bort dessa.
mvh
SvenSv: Motion
Jag har program med motion-funktion som funkar bra (dock inte källkoden).
De kollar hela bilden, men antagligen inte varje pixel utan kanske varannan eller var 3:e.
De jämför bild 1 med bild 2, sen bild 2 med bild 3 osv.
Man kan ställa in känslighet, beroende på hur mkt kamerans flimmer stör.
Att det går över från dag till natt kommer ett sånt program inte att reagera på, då det inte är alls så känsligt.
Jag har även sett mer avancerade tekninker som kollar olika linjer i bilden. Alltså konturer. Men det skall inte vara nödvändigt.Sv: Motion
Så är min gruntanke också .Man lagrar referensbildspixel i
en referensArray.
Sedan tar man ett snapshot med jämna intervaler och jämför
aktuell pixel med den som ligger Arrayen
referensArrayen bör väl uppdateras sådär varje minut
Använder API GetPixel
Har testat lite skall hela bilden med 352*288 så kommer jag
inte unde 1.5 sek med en 200 mhz processor.
Lite smålurigt med flimmer ,bilstrålkastare,åskblixter mm.
Funderar vidare
mvh
SvenSv: Motion
Tex åska ger förmodligen förändring över hela bilden (tex bild 2) och då ska den hoppa över den bilden och istället jämföra 1 med 3.
Strålkastare är trassligare men dessa brukar komma med hög fart och svepa på samma sätt. Man får helt enkelt lära programmet att känna igen sådant.
Nyfiken, vad har du tänkt att använda det till?
Har själv en timelaps-video som spelar in dygnet runt på en del platser runt/i huset och den ökar på inspelningen när ett larm går.
/JanneSv: Motion
Om en bild tages varje sekund och en referens-bild tages va 60:e sek, händer väl följande:
Bild 1 tages Sekund 1 och du sitter framför kameran
Du springer snabbt bort från kameran och är därifrån innan Sekund 5.
Om Sekund 5-60 ska jämföras med Bild 1 från Sekund 1,,, kommer bild 5-60 anses vara Motion.
Så man måste väl ta en referens-bild i sekunden.Sv: Motion
Det var tänkt att användas inomhus, så eventuella blixtar och sånt tänkte jag inte på.
Det är meningen att det ska vara kopplat till en webkamera och ta bilder när nån går förbi, Eller om nåt annat rör sig.
---
Hur jämför man med VB om en pixel ändrats mycket?
Alltså den ska ju inte reagera om pixelen ändrats från
RGB(123,123,123)
till
RGB(123,125,123)
(Den borde kanske jämföra mörkheten i pixelen.)
Nåt förslag?Sv: Motion
Exempel på kod:
'KPD-Team 1999
'URL: http://www.allapi.net/
'E-Mail: KPDTeam@Allapi.net
'Create a new project, add a command button and a picture box to the project, load a picture into the picture box.
'Paste this code into Form1
Private Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Private Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Dim PicBits() As Byte, PicInfo As BITMAP, Cnt As Long
Private Sub Command1_Click()
GetObject Picture1.Image, Len(PicInfo), PicInfo
ReDim PicBits(1 To PicInfo.bmWidth * PicInfo.bmHeight * 3) As Byte
GetBitmapBits Picture1.Image, UBound(PicBits), PicBits(1)
For Cnt = 1 To UBound(PicBits)
PicBits(Cnt) = 255 - PicBits(Cnt)
Next Cnt
SetBitmapBits Picture1.Image, UBound(PicBits), PicBits(1)
Picture1.Refresh
End SubSv: Motion
<Ta en referensbild .
Ja om det är inomhus skulle det väl räcka gott och väl med en
referens i minuten om den då är samma som den förra med
några procent fel /känslighet så blir den ny referens
Sedan skall du givetvis jämföra scanna minst en gång i sekunden.
Chefen kommer övervakning ?
Rgb värdet får du bäst med GetPixel.
Jag tror att bilden skall vara i gråskala 256 färger.
DSSv: Motion
Ett litet test program som du kan "spåna" kring
Option Explicit
'En PictureBox 352*288 namn TestPic
'En Command1 och en Command2
'Simulera bildändring
Private Declare Function GetPixel Lib "gdi32" _
(ByVal hdc As Long, ByVal x As Long, _
ByVal y As Long) As Long
Dim RefArray(6336) As Long 'standard bilden
Dim PicArray(6336) As Long 'testbild
Dim Start As Single
Private Sub Command1_Click()
'Ladda in Nollbild referens
Call ReferensPic
End Sub
Private Sub Command2_Click()
'Ladda in momentan bild för test
Dim i As Long, diff As Long
Call TestPicture
For i = 0 To 6336
If RefArray(i) <> PicArray(i) Then _
diff = diff + 1
Next 'i
diff = diff * 100 / 6336
MsgBox "Bilden har ändrats " & diff & " procent"
End Sub
Private Sub ReferensPic()
Dim x As Long, y As Long, k As Long
Start = Timer
For x = 1 To 351 Step 4 'scanna vertikalt 4 pixels hopp
For y = 1 To 287 Step 4
RefArray(k) = GetPixel(TestPic.hdc, x, y)
k = k + 1
Next 'y
Next 'x
MsgBox Timer - Start
End Sub
Private Sub TestPicture()
Dim x As Long, y As Long, k As Long, i As Long
For x = 1 To 351 Step 4 'scanna vertikalt
For y = 1 To 287 Step 4
PicArray(k) = GetPixel(TestPic.hdc, x, y)
k = k + 1
Next 'y
Next 'x
End Sub
'DSSv: Motion
Jag hade redan gjort ett fungerande exempel.
Inte så bra kodat än, ska optimera det,
men det funkar iallafall
Om du har webkamera kan du se att det funkar!
Källkoden:
http://w1.444.telia.com/~u44402237/motion.zipSv: Motion
Det ser skitbra ut .Du har förmodligen en snabb processor.
Rent allmänt så tex dina Mod funktioner i BasModulen
är tidskrävande,DoEvents själ tid som bara den.
Tycker fortfarande att du skall kolla in GetPixel och göra Compare
på den istället.
Din principlösning verkar helt Ok ,jag tänkte i lite andra banor.
Jag lägger koden i min godislåda för ev framtida bruk.
ha det
SvenSv: Motion
Mod funktionerna gör om till RGB för att sedan kolla hur det röda,gröna och blåa
ändrar sig.
Som det är nu får en av dem ändras högst 10 upp eller ner.
Finns det snabbare/bättre sätt att få det i RGB?
Eller går det jämföra pixlarna på annat sätt?
Det räcker inte med att den kollar om det är
samma färg. Den ska kolla om det är nästan samma
också ju.
Jag hade redan tagit bort DoEvents i For-loopen.
Den DoEvents som ligger i början av 1-sekunds-loopen, påverkar den
For-satserna också?
Tar jag bort den funkar det inte och programmet blir oåtkomligt.
(Det är ju denna loopen som driver runt programmet annars jämför
det ju bara en gång).
Vad har GetPixel för fördelar?Sv: Motion
>Vad har GetPixel för fördelar?
Den ger dig RGB värdet i form av LongInteger,väldigt nyanserat
Men framför allt du slipper VB s "långsamma" runtime att bli
inblandad.Du hämtar direkt från Windows operativsystem.
Dvs inga omvägar via VB tolken.Vill du öka farten skall du
absolut gå den vägen.
>Mod funktionerna gör om till RGB för att sedan kolla hur det >röda,gröna och blåa ändrar sig.
>Som det är nu får en av dem ändras högst 10 upp eller ner.
GetPixel lämnar tex 16234 för en färg du slipper Hexomvandling
om nu 16234 har ändrats till 16250 så betyder det att någon
av R G B har ändrats lite.
Skall kolla din kod en gång till och komma med förslag där du
kan byta ut RGB mot GetPixel.
Ok på att du inte kan ta bort det ena DoEvents.
DS