Bugün gelen soruların biri bana eski bir çalışmamı hatırlattı. Daha önce yazdığım bir yazının kaybolduğunu farkettim. Blog sistemini sıkça değiştirdiğim için sanırım aralarda veri kaybı da oluyor. Neyse ki bu eski çalışmayı tüm eski yedekleri kurcalayıp buldum ve yeniden yayına koyuyorum...
Birçok resim işleme yönteminin ortak sorunu resimlerdeki kontrast ve parlaklık. Resimdeki her bir ayrıntı bilgisayar için çok önemli ve bu ayrıntılardaki ufak değişiklikler bilgisayar tarafından hemen algılanır. Yazacağımız nesne takip programı da bu sorunla karşı karşıya kalmaktan kurtulamayacak sanırım.
Haraket algılama ile başlayalım. Akan bir görüntü üzerinde bir cismin haraket ediyor olarak kabul edilebilmesi için görüntü üzerinde belli bir bölgede pixel değerlerinin sürekli değişiyor olması gerekir. Yukarıda bahsettiğim parlaklık sorunu da işte burada ortaya çıkıyor. Webcamler ile çalışacağımız için özellikle otomatik olarak ışık dengesi ayarlayan webcamler bize bu konuda sorun çıkaracaktır. Bu sorunu çözmek için pixellerde haraket belirtme ihtimali düşük olan değişiklikleri gözardı ettireceğiz. Haraketli görüntüyü oluşturan resimleri ikişer ikişer inceleyeceğiz. 1. resmin pixel değerlerini 2. resimin pixel değerleri ile karşılaştırıp, aralarında belirlediğimiz eşik değerinin üstünde fark bulunan pixelleri görüntü üzerinde işaretleyeceğiz. İkişer ikişer tüm resimlere aynı işlemi uyguladığımızda aslında haraket eden pixelleri işaretlemiş olacağız. Bu sayede cismin hızını pixel/saniye cinsiden bulabilmemiz de mümkün olur.
Nesne takibi de yukardaki yönteme dayanıyor. Yukardaki işlemleri uyguladıktan sonra işaretlediğimiz en ust, en alt, en sağ ve en sol pixeli belirlememiz gerekiyor. Bunu yapmak kolay. Daha sonra belirlediğimiz 4 noktayı köşe kabul eden dikdörgen şeklindeki bölgeyi aynen başka bir resme kopyalıyoruz. Böylece yeni resmimizde sadece haraket halindeki nesneyi görmemiz mümkün oluyor. Tabi haraketli görüntü elde edebilmek için bu işlemleri arka arkaya yapmamız lazım. Ancak bu yöntemin, 2.4 ghz işlemcili bilgisayar üzerinde saniyede 2-3 resimden fazlasını işleyemediğini söylemeliyim. Hızı arttırmak için tüm pixelleri taramak yerine, her pixelden sonra 4-5 pixel atlanarak işlem yapılabilir.
Konu nesne takibi iken başka bir yöntemden daha bahsedeyim. Bu yöntemle, haraket eden/etmeyen bir cismi işaretleyip onu takip etmeyi amaçlayacağız. Bunu ilk yöntem yapamaz, o yüzden nesne takibi konusunda bu daha başarılı olabilir. Öncelikle takip edilecek cismin rengini seçiyoruz. Tüm resmi tarayıp, bu renge benzer renk içeren pixelleri işaretliyor ve işaretli pixellerde, yukardaki yöntemde olduğu gibi kenar pixelleri (ust,alt...) belirleyip yine bu pixelleri köşe kabul eden dikdörtgen bölgeyi başka bir resme kopyalıyoruz. Bu yöntemde resimleri ikişer ikişer işlememize de gerek yok. Her bir resim bittiğinde webcamden yeni bir resim isteyip onu işleyerek haraketli görüntü sağlamaya çalışıyoruz. Hız 1. yöntemdekinden pek farklı değil. Ancak bazı sorunlarımız da var. Resim üzerinde cisme ait olmayan bir bölgede cismin rengi bulunmamalı. Bu yüzden fark eşiğini iyi seçmemiz lazım. Yine otomatik ışık denge ayarı yüzünden arasıra cisim rengini yeniden seçmemiz gerekebilir.
İkinci yöntemi kullanarak VB ile yazdığım programın ekran görüntüsü aşağıda(gerçek hızı bu kadar düşük değil tabi, aşağıdaki gif, aralıklarla çekilmiş resimlerle oluşturuldu):
Hazır VBden bahsetmişken webcamden resim alma API kodu :
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function capCreateCaptureWindow Lib "avicap32.dll" Alias "capCreateCaptureWindowA" (ByVal lpszWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hwndParent As Long, ByVal nID As Long) As Long
Const Baglan As Long = 1034
Const Kopar As Long = 1035
Const Resim_Al As Long = 1084
Const Kopyala As Long = 1054
Private Sub Resim_Al()
Dim Kamera As Long
Kamera = capCreateCaptureWindow("KameraPenceresi", 1, 0, 0, 0, 0, 0, 0)
SendMessage Kamera, Baglan, 0, 0
SendMessage Kamera, Resim_Al, 0, 0 ' Resim Al
SendMessage Kamera, Kopyala, 0, 0 'Resmi panoya kopyala
' resmi panodan picture1 nesnesine boya
Picture1.PaintPicture Clipboard.GetData, 0, 0, Picture1.Width, Picture1.Height, 0, 0, 640, 480
Clipboard.Clear ' Panoyu temizle
SendMessage Kamera, Kopar, 0, 0 ' Bağlantıyı kopar
End Sub Bu arada gereksiz bir ayrıntı da olsa; ağırlık merkezi cismi belirten pixellerin tamamının koordinatları toplamının bu pixellerin sayısına bölümünden elde edilebilir. Cismin gerçek ağırlık merkezi ile pek ilgisi yok.
Okunma Sayısı: 340
Yayınlanma Tarihi: 24 Ocak 2010 Pazar - 13:16
Anahtar Kelimeler: nesne, takip, haraket tespiti, motion detection, cisim, takibi, pixel, webcam, kamera, görüntü
Yorumlar ( 3 )
murat#1
10/02/2010, 18:23
merhaba.mükemmel bir çalışma olmuş tebrikler.ben bir soru sormak istiyorum.bu kodlar yazıldıgında webcamden resmi otomatik alıyor mu?birde bu kodlar haricinde yazılması gereken kodlar var mı?
Hüseyin Atasoy#2
11/02/2010, 15:01
Verdiğim kodlar sadece "SendMessage" API çağrısı kullanılarak webcamden nasıl resim isteneceğiyle ilgili. Kodda Resim_Al subı çağrıldığında webcamden picturebox1 içine bir resim aktarılır...
murat#3
11/02/2010, 19:45
teşekkürler
Yorum/Görüş Bildir