in ,

Kamera İle Nesne Sayma (Bölüm 4)

GÖRÜNTÜ İŞLEME TEKNİKLERİ İLE İNSAN SAYACI OLUŞTURMA 

Önceki bölümlerimizde verilen temel bilgilerden sonra bu projeyi hep birlikte adım adım gerçekleştireceğiz

Bu proje ile bir bölgeye giren veya bölgeden çıkan insanların sayısı ve yönü belirlenecektir. Bu blog serisini okumaya başlamadan önce daha önceki Makine görüşü ve görüntü işleme teknikleri ile ilgili yazmış olduğumuz blog yazılarımızı okumanızı tavsiye ediyoruz. 

Dünyanın koranavirüs ile mücadelesinde teknolojiye çok büyük görevlerin düştüğünü gördük. Yaratıcı ve faydalı çözümler, salgının yayılma hızının düşürülmesine katkıda bulunacaktır. Biz de insan sayacı projesi ile havaalanları, otogarlar, tren istasyonları, stadyumlar, alışveriş merkezleri, düğün salonları, mağazalar, marketler ve toplu taşıma araçları gibi kalabalık ortamlarda bulunan insan sayılarını belirleyerek, yoğunluk oluşmasını kontrol altına almayı hedeflemekteyiz. 

Projenin nasıl yapıldığını anlatmaya başlamadan önce insan sayma işleminin nasıl yapıldığından kısaca bahsedelim. Öncelikle tespit edilmek istenen nesnenin bir görüntü üzerinde bulunması gerekmektedir. Tespit işlemi için Background Subtraction, HOG, R-CNN, YOLO ve diğer derin öğrenme tabanlı algoritmalar kullanılabilmektedir. Biz bu projede Background Subtraction algoritmasını kullanacağız. Bu algoritma sayesinde hareketli ön plan sabit arka plandan çıkartılarak nesne izleme işlemi gerçekleştirilebilmektedir. 

Nesne frame üzerinde tespit edildiği zaman öncelikle bu nesneye geçici bir ID ataması gerçekleştirilecektir, bu geçici ID tespit edilen kişi kamera görüşünde bulunduğu sürece geçerli olacaktır. Kişi kamera görüşünden çıktığı zaman atanan ID hafıza alanından silinecektir. Daha sonra ise nesne izleme algoritması ile nesnenin ilerlediği yön tespit edilecektir. Tespit edilen nesnenin ağırlık merkezinin (x,y) koordinatları anlık olarak alınacaktır. Frame’in çeşitli niteliklerine bağlı olarak bir sonraki karede yeni nesne konumunu tahmin ederek bir video akışı etrafında hareket ederken nesne izlenecektir. 

Nesne tespit işleminde, yeni nesnelerin görüşe girip girmediği ve izleme aşamasında kaybolan nesnenin olup olmadığının kontrolleri yapılacaktır. Herhangi bir nesne tespit edilmiş ise nesnenin ağırlık merkezi koordinatları izlenecektir ve her bir framede bu işlemler güncellenecektir. Nesneleri izlemek için centroid izleme algoritması kullanılacaktır. Kısaca centroid izleme algoritmasından bahsedelim;

  • Öncelikle tespit edilen her nesnenin ağırlık merkezi hesaplanır.
  • Tespit edilen nesnenin anlık ağırlık merkezi ile önceki ağırlık merkezi arasındaki Öklid mesafesi hesaplanır. 
  • Centroid izleme algoritması ile aralarında minimum Öklid mesafesi olan centroid çiftlerine aynı geçici ID’si atanır.
  • Geçici ID ataması gerçekleştirilmiş nesne izlenerek yönü belirlenir ve sayma işlemi gerçekleştirilir. 
  • Nesne görüş alanında bulunduğu sürece bilgileri kayıt edilir. Nesnenin yönü, kimlik bilgileri, giriş ve çıkış saatleri metin olarak veri tabanına kayıt edilir. 
  • Tespit edilen nesne görüş alanından çıktığında veya kaybolduğunda nesnenin kaydı hafıza alanından silinir. Fakat gerekli bilgiler veri tabanında metin olarak saklanabilmektedir.

Sayma işlemi de frame üzerinde belirlenen iki adet referans çizgi ile gerçekleştirilmektedir. Ağırlık merkezinin hareketine bağlı olarak bu referans çizgiler kullanılarak sayma işlemi gerçekleştirilir. Yön negatif (yukarı hareket) ve ağırlık merkezi üstteki referans çizgisinin üzerinde ise bölgeden çıkan sayacı arttırılır, yön pozitif (aşağı hareket) ve ağırlık merkezi alttaki referans çizgisinin altında ise bölgeye giren sayacı arttırılır. Bu sayede bir bölgeye giren veya çıkan nesnelerin sayısı elde edilebilir. 

İnsan sayacı algoritmasının teorik olarak nasıl çalıştığımızı anladığımıza göre artık projeyi gerçeklemeye başlayabiliriz. Projeyi, bilimsel bilgi işleme için çok uygun olan Python programlama dili kullanılarak geliştireceğiz. Projede ağırlıklı olarak Python dilinin OpenCV ve Numpy kütüphanelerini kullanacağız. OpenCV, görüntü işleme ve makine görmesine dayanan özel bir kütüphanedir. İçerisinde birçok kolaylaştırılmış görüntü işleme fonksiyonunu barındırmaktadır. Birkaç satır kodla büyük görüntü işleme algoritmalarından faydalanabilmektedir. Yaygın olarak görüntü işleme tekniklerinin sağlam bir matematiksel arka planı vardır. OpenCV kütüphanesi kendi içerisinde birçok matematiksel denklemini barındırmaktadır. Görüntüler matrislerden oluştuğu için görüntü işleme projelerinde bol miktarda matrislerle işlem yapılmaktadır. Numpy kütüphanesi, birkaç satır kodla büyük matris ve dizi işlemlerini kolayca yapabilmektedir. Bu sebeple projemizde Numpy kütüphanesini kullanacağız. 

Şimdi İnsan Sayacı projesini nasıl yaptığımızı adım adım açıklamaya başlayalım.

ADIM-1: Kameradan Görüntü Alma 

Projede gerçek zamanlı olarak anlık görüntü işleme uygulanacaktır. Bu yüzden kameradan canlı olarak anlık görüntü çekme işleminin gerçekleştirilmesi gerekmektedir. Anlık olarak çekilen bu görüntüler frame olarak adlandırılmaktadır. Her frame bir görüntü karesidir. Saniyede çekilen frame sayısı ne kadar fazla olursa video o kadar pürüzsüz olacaktır. OpenCV kullanarak kameradan anlık olarak frame çekmek için VideoCapture nesnesi oluşturmamız gerekmektedir. Bu frame yakalama nesnesi aşağıdaki kod satırı ile oluşturulur. 

1. frameCapture = cv2.VideoCapture(0) 

ADIM-2: Arka Planın Çıkartılması 

Arka plan çıkarma birçok görüntü tabanlı uygulamada önemli bir ön işleme adımıdır. Algoritma genel olarak görüntülerdeki gölgeleri algılama ve nesne izleme işlemi için geliştirilmiştir. Bu algoritma her piksel için uygun sayıda gauss dağılımı seçer ve aydınlatma değişiklikleri nedeniyle değişen görüntülere daha iyi uyum sağlamaktadır. Bu algoritma sayesinde gölgenin algılanıp algılanmayacağı seçilebilmektedir. OpenCV’de arka plan çıkarma işlemi aşağıdaki kod satırındaki fonksiyon ile gerçekleştirilmektedir. 

1. background = cv2.createBackgroundSubtractorMOG2(history=132, 
2. varThreshold=50, detectShadows=False)

Bu fonksiyonda detectShadow parametresi gölgelerin algılanıp algılanmayacağını belirlemektedir. Parametre False değerine eşit ise gölgeler algılanmaz, parametre True değerine eşitse gölgeler algılanarak gri renkle işaretlenmektedir. 

ADIM-3: Frame’lerin Okunması 

Sonsuz bir döngü açılarak VideoCapture nesnesi ile yakalanan her bir frame okunacaktır. OpenCV’de frame okuma işlemi aşağıdaki kod satırındaki fonksiyon ile gerçekleştirilmektedir. 

1. while frameCapture != None: 
2. 
3. ret, frame = frameCapture.read() 

read() fonksiyonu bir bool değer de döndürmektedir. Bu değer ret değişkeninde saklanmaktadır. Frame okuma işlemi başarılı şekilde gerçekleşirse True değeri döndürülür.

Şekil 1.1. Okunan bir frame karesi 

ADIM-4: Kontast ve Parlaklığın Ayarlanması 

Parlaklık, görüntünün aydınlığını ve koyuluğunu ifade eder. Aynı zamanda bir ışık kaynağı tarafından oluşturulan parlaklık etkisidir. Kontrast ise, nesneler veya bölgeler arasındaki parlaklık farkı olarak ifade edilmektedir. Ayrıca kontrast, nesne tanıma özelliğini parlaklıktan etkileyen miktar olarak da tanımlanmaktadır. Nesnelerin birbirinden ayrılmasını kolaylaştıran bir etkidir. Kontrast ve parlaklık ayarlaması yapılmış görüntü aşağıdaki denklem yardımıyla hesaplanmaktadır. 

𝑓(𝑖,𝑗) fonksiyonu giriş görüntü piksellerini, 𝑔(𝑖,𝑗) çıktı görüntü piksellerini temsil etmektedir. α parametresi kontrastı, β parametresi parlaklığı ayarlamaktadır. β parametresi her piksele sabit bir değer ekleyerek görüntünün doygunluğunu ayarlayabilmektedir. α parametresi ise renk seviyelerinin yayılımını değiştirerek kontrastı ayarlayabilmektedir. 

OpenCV’de tüm bu kontrast ve parlaklık ayarlaması aşağıdaki kod satırındaki fonksiyon ile gerçekleştirilmektedir. 

1. brightnessAndContrast = cv2.convertScaleAbs(frame, alpha=0.8, 
2. beta=-20)

Şekil 1.2. Parlaklık ve kontrast ayarlaması uygulanmış görüntü 

ADIM-5: Görüntülerin Renk Formatının Değiştirilmesi 

İnsan sayma işlemi için görüntülerdeki renkler kullanılmayacağı için her bir frame gri formata dönüştürülecektir. Gri görüntü 8 bittir ve 256 farklı renk alabilmektedir. Bu formatta 0 Siyah, 255 beyaz renk anlamına gelmektedir. 

OpenCV’de frame’lerin gri formata dönüştürülmesi aşağıdaki kod satırında bulunan fonksiyon ile sağlanmaktadır. 

1. gray = cv2.cvtColor(gamma, cv2.COLOR_BGR2GRAY)

Şekil 1.4. Görüntünün gri formata dönüştürülmesi 

ADIM-6: Görüntülere Smoothing İşleminin Uygulanması 

Kameradan alınan görüntülerde çoğu zaman görüntünün algılanmasını zorlaştıran bir miktar gürültü bulunmaktadır. Alınan görüntü sinyalleri düşük yoğunluğa sahip olduğu zaman görüntü üzerinde parazitlenme olacaktır. Bu parazitlenmeyi kaldırmak için de ağırlıklı olarak gauss bulanıklığı kullanılmaktadır. 

Parazitlenmeyi kaldırmak için bu projede Bilateral Filtresi kullanılmıştır. Bu filtre kenarları keskin tutar ve nesne sınırlarını başarılı bir şekilde belirlemektedir. Ayrıca bu filtre gürültü gidermede oldukça etkilidir. Bilateral filtresi iki adet Gauss Filtresi değeri almaktadır. İlk Gauss Filtresi, yumuşatma işlemi için nesneye yakın pikselleri dikkate almaktadır. İkinci Gauss Filtresi de, bulanıklaştırma için yalnızca merkezi piksele benzer yoğunluklardaki pikselleri dikkate almaktadır. Kullanılan bu iki Gauss Filtresi sayesinde nesnenin kenarlarındaki pikseller büyük yoğunluk değişimine sahip olacağından nesnenin kenarları korunacaktır. 

OpenCV’de Bilateral Filtresi aşağıdaki kod satırında bulunan fonksiyon ile uygulanmaktadır.

1. smoothing=cv2.bilateralFilter(gray,d=5,sigmaColor=75,sigmaSpace=75)

Bu fonksiyonda d parametresi her piksel merkezinin çapını, sigmaColor renk uzayındaki standart sapmayı, sigmaSpace koordinat uzayındaki standart sapmayı belirtmektedir. 

Şekil 1.5. Görüntüye bilateral filtresinin uygulanması 

ADIM-7: Gamma Değerinin Ayarlanması 

Gamma düzeltmesi, giriş görüntüsünün piksellerinde doğrusal olmayan bir işlem gerçekleştirerek görüntünün doygunluğunun değişmesine sebep olmaktadır. Algoritmanın uygulanabilmesi için görüntü piksel yoğunluklarının [0, 255] aralığından [0, 1] aralığına ölçeklenmesi gerekmektedir. Gamma düzeltmesi için aşağıdaki denklem kullanılmaktadır.

 𝑂𝑢𝑡𝑝𝑢𝑡= 𝐼𝑛𝑝𝑢𝑡 x 1 /𝐺𝑎𝑚𝑚𝑎 

OpenCV’de gamma değerinin ayarlanması aşağıdaki kod satırında bulunan fonksiyon yardımıyla gerçekleştirilmektedir. 

1. gammaValue = 1.0 / 0.8 
2. table = np.array([(((i+1) / 255.0) ** gammaValue) * 255 
3. for i in np.arange(0, 256)]).astype(“uint8”) 
4. gamma= cv2.LUT(brightnessAndContrast, table)

Şekil 1.3. Gamma düzeltmesinin uygulanması 

ADIM-8: Arka Planın Çıkartılması 

Tespit işlemi arka plan çıkarma işlemi ile sağlanmaktadır. Arka planı çıkartılmış frame güncellenerek nesne tespit edilmeye çalışılır. Kamera görüş alanına giren insanın bulunduğu alan, arka planı çıkarılan frame alanında bulunmamaktadır. Bu yüzden hareketli ön plan, sabit arka plandan çıkartılarak insan tespit edilmektedir. Böylece ofise giren veya ofisten çıkan insanlar nesne izleme algoritmalarıyla izlenebilecek şekle gelmiş olmaktadır. 

Python’da bulunan aşağıdaki fonksiyon ile ön plan güncellenerek nesne tespit edilmektedir. 

1. forGroundMask= background.apply(smoothing) 

Şekil 1.6. Nesne tespit işleminin gerçekleştirilmesi 

ADIM-9: Görüntü Segmantasyonu ile Eşikleme 

Görüntü segmantasyonu belirli bir piksel kümesini ayırmak ve gruplamak için kullanılmaktadır. Projemizde görüntü piksel değerleri 0 ile 255 arasında bir değer almaktadır. Görüntüyü Binary formata dönüştürmek için eşikleme işlemi uygulanmaktadır. Bir eşik değeri belirlenir ve tüm piksel değerleri bu eşik değeri ile karşılaştırılır. Piksel, eşik değerinden küçük veya eşitse piksel değeri siyah renk yapılır. Piksel, eşik değerinden büyükse piksel değeri beyaz yapılır. Bu sayede görüntü sadece iki renk alarak ön plan, arka plandan daha net bir şekilde ayrılabilmektedir. 

OpenCV’de eşikleme işlemi aşağıdaki kod satırında bulunan fonksiyon aracılığı ile yapılmaktadır. 

1. ret, threshold= cv2.threshold(forGroundMask, thresh=127, 
2. maxval=255, type=cv2.THRESH_BINARY)

threshold() fonksiyonunda kullanılan parametrelerin tanımları aşağıda açıklanmıştır; 

thresh: Eşik değerinin girildiği parametredir. Piksel değeri bu thresh parametresine göre siyah veya beyaz renk değerini almaktadır. 

maxval: Karşılaştırma sonucunda piksele atanacak maksimum değerdir. Genellikle 1 veya 255 değeri atanır. Çünkü görüntü binary formata dönüştürüldüğü için piksel değerleri her zaman iki değer alabilecektir. Matrisin anlaşılır olması için 1 veya 255 değerleri verilmektedir. Siyah değeri de her zaman 0 olmaktadır. Yani threshold işleminden sonra piksel değeri 0-1 veya 0-255 piksel değer çiftlerini alabilmektedir. 

type: Uygulanacak eşikleme türünün belirtildiği parametredir. 

Şekil 1.7. Görüntüye eşikleme işleminin uygulanması 

ADIM-10: Frame Üzerinde Oluşan Parıltının Kaldırılması 

Parıltı, aşırı ve kontrolsüz parlaklığın neden olduğu bir hatadır. Parıltı piksel değeri 180’den büyük olan kısımlarda gerçekleşmektedir. Bu yüzden ilk olarak piksel değerinin 180’den büyük olduğu kısımlarını bulmamız gerekmektedir. Frame’e threshold işlemi uygulanarak binary formata dönüştürülür ve eşik değeri 180 seçilerek parlak olan kısımların beyaz olarak görünmesi sağlanır. Bu işlemleri OpenCV kütüphanesi kullanılarak aşağıdaki fonksiyon yardımıyla bulunmuştur. 

1. def ShineRemove(_frame, _threshold): 
2. 
3. gray = cv2.cvtColor(_frame, cv2.COLOR_BGR2GRAY) 
4.
5. smoothing= cv2.GaussianBlur(gray, (9,9), 0) 
6. 
7. _,thresh = cv2.threshold(smoothing, 180, 255, 
8. cv2.THRESH_BINARY) 
9. 
10. erode = cv2.erode(thresh, None, iterations=2) 
11. 
12. dilate= cv2.dilate(erode, None, iterations=4) 
13. 
14. labels = measure.label(dilate, neighbors=8, background=0) 
15. 
16. mask = np.zeros(thresh.shape, dtype=”uint8″) 
17. 
18. for label in np.unique(labels): 
19. 
20. if label == 0: 
21. continue 
22. 
23. labelMask = np.zeros(thresh.shape, dtype=”uint8″) 
24. 
25. labelMask[labels == label] = 255 
26. 
27. numPixels = cv2.countNonZero(labelMask) 
28. 
29. if numPixels > 300: 
30. mask = cv2.add(mask, labelMask) 
31. 
32. result = np.where(mask != 255, _threshold, _threshold * 0) 
33. 
34. return result

Ne düşünüyorsunuz?

Barış ULUSOY, Elektronik Mühendisi tarafından yazıldı.

T3 Otomasyon bilgi ve tecrübelerini endüstri ile paylaşmak ve hizmet vermek maksadıyla Fatih ALTINTAŞ tarafından 2006 yılında Sakarya’da kuruldu, 2011 yılında limited olarak kurumsallaşmanın temellerini atmış oldu. Taahütlerini yerine getiren, sorumlu, güvenilir, insana önem veren, yenilikçi ve müşteri odaklı iş anlayışı ile yüksek standartlarda hizmet veren, mutlu çalışanlara sahip bir şirket olmak. Müşteri odaklı iş anlayışıyla otomasyon çözümleri üreterek, hızlı, kaliteli ve ekonomik çözümler sunmaktır.

Yorumlar

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Yükleniyor...

0

Kamera İle Nesne Sayma (Bölüm 3)

Kamera İle Nesne Sayma (Bölüm 5) – Son Bölüm