23 Ocak 2017 Pazartesi

Python - OPENCV Yaya Tespiti (Görüntü İşleme)


Yaya tanıma (pedestrian detection) video takip, kişi davranış analizi, akıllı arabalar için sürücü destek sistemi gibi farklı uygulamalarda kullanılabilir. Yaya tespiti probleminde makine öğrenmesi teknikleri yaygın olarak kullanılmaktadır, bu tekniklerde eğitilmiş sınıflandırıcılar ile görüntü içerisindeki yaya tespit edilmeye çalışılır. Sınıflama yapılırken yani bizim örneğimizde görüntüdeki insanları bulurken, uygun bir sınıflandırıcı bulmak kadar bulunacak nesneye ait olan seçici/ayırt edici bir özelliğin (feature) çıkarılabilir olması da çok önemlidir. Yayaların tanınması probleminde HOG (Histograms of Oriented Gradient) ile özellik çıkarılması yönteminin başarılı sonuçlar verdiği gösterilmiştir.

                 


HOG sadece kişi tanıma değil farklı nesnelerin tanınmasında da özellik çıkarımı için kullanılmaktadır ve OPENCV içerisinde implementasyonu gerçekleştirilmiştir. Bizim örneğimizde HOG kullanarak görüntü üzerindeki insanları tanımaya çalışacağız. Burada tahmin edeceğiniz üzere görüntü üzerinde bir pencere dolaştırmak ve bu pencerelerde arama yapmak gerekecek, Çünkü amacımız kişileri bulmak ve bir dikdörtgen içerisine almak. Görüntü üzerinde pencere gezdiriyoruz diyelim, kişileri neye göre ve nasıl tanıyacağız. Yani gezdirilen pencerenin içinde ağaç mı var, tabela mı, araba mı yoksa insan mı? Cevabını aradığımız soru bu!. İşte burada yazının başında bahsettiğimiz HOG iyi sonuçlar verdiği için tercih edilmekte. Tabi burada bir tanıma işlemi yapmak istediğimiz için, aslında bir makine öğrenmesi tekniği uygulamamız gerekiyor. Yani önce bir grup etiketlenmiş veriye HOG ile özellik çıkarımı yapıp, seçtiğimiz bir sınıflandırıcıya verip, bu sınıflandırıcıyı eğitmemiz gerekiyor. Daha sonra verdiğimiz yeni bir girdide, sınıflandırıcımız öğrenme kapasitesine göre bize bir cevap veriyor.

Neyseki OPENCV içerisinde halihazırda eğitilmiş HOG + Linear SVM modeli mevcut. Biz de bunu kullanarak görüntü ya da video üzerinde yaya tanıma işlemini gerçekleştirebiliriz. Bu yazı kapsamında vereceğim örnekte KAIST Multispectral Pedestrian Detection  veri seti kullanılmıştır Bu veri setinin avantajı RGB + Thermal band içermesidir. Hem böylelikle yaya tespitine örnek vermekle birlikte thermal bandının bu problemde kullanımının getirdiği avantajları da görmüş olacağız.

Şimdi kodlara başlayacak olursak; ( imutils kurmak için : pip install imutils )

.mat formatındaki görüntüyü okumak için

"""
Created on Mon Jan 23 11:07:09 2017

@author: ibrahim
"""

# Goruntuyu yeniden boyutlandırmak icin gerekli kütüphane
import imutils
from imutils.object_detection import non_max_suppression

import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt
import cv2

# initialize the HOG descriptor/person detector
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

path = 'image_matlab/'
goruntu = 'set01_V003_I00699.mat'
mat_contents = sio.loadmat(path + goruntu)
I = mat_contents["im"]


Görüntüyü okuyup I değişkenine atmış olduk. Dikkatinizi çekmek istediğim nokta, bu görüntü 4 bandlı bir görüntü ve son bandı thermal görüntüyü içeriyor. İlk olarak sadece görüntünün ilk 3 bandını(RGB) kullanalım.

image = I[:,:,0:3]

image = imutils.resize(image, width=min(800, image.shape[1]))
orig = image.copy()

hog.detectMultiScale ile parametre olarak verdiğimiz görüntü üzerinde pencere gezdiriliyor ve OPENCV'de default tanımlı eğitilmiş veri seti üzerinden sınıflandırma sonucu elde ediliyor!!!!

# detect people in the image
(rects, weights) = hog.detectMultiScale(image, winStride=(4, 4),
padding=(8, 8), scale=1.01)
# draw the original bounding boxes
for (x, y, w, h) in rects:
     cv2.rectangle(orig, (x, y), (x + w, y + h), (0, 0, 255), 2)

Buraya kadar görüntüdeki kişileri bulup dikdörtgen içerisine aldık. Gördüğünüz gibi kod çok kısa, zaten özellik çıkarımı, eğitme işlemi vs hiçbirşey ile uğraşmadık herşeyi hazır kullandık. Unutmayalım ki; kendi spesifik problemimiz için bu işlemleri biliyor ve yapabiliyor olmamız son derece önemli!!! Herneyse şimdi bir sonraki aşama olan non-maxima suppression(NMS) işlemine bakacak olursak: bu şu anlama geliyor:

Kişileri bulduk dikdörtgen içine aldık, bunu yapmak için görüntü üzerinde pencere gezdirdik. Buradaki sorun aynı kişinin pencerenin kaydırılmasına bağlı olarak tekrar tekrar bulunabilecek olması. Bu problemi elimine etmek için non-maxima suppression işlemi uygulanıyor, yani üst üste binen dikdörtgenlerin kesişme oranına göre(overlapThresh) eleme işlemi gerçekleştiriyor.

# apply non-maxima suppression to the bounding boxes using a
# fairly large overlap threshold to try to maintain overlapping
# boxes that are still people
rects = np.array([[x, y, x + w, y + h] for (x, y, w, h) in rects])
pick = non_max_suppression(rects, probs=None, overlapThresh=0.5)
# draw the final bounding boxes
for (xA, yA, xB, yB) in pick:
    cv2.rectangle(image, (xA, yA), (xB, yB), (0, 255, 0), 2)
# show the output images
plt.figure(0)
plt1=plt.imshow(orig)
plt.figure(1)
plt2=plt.imshow(image)



Görüntümüzün thermal band içerdiğinden bahsetmiştik, fakat sadece üç bandı kullandık. Şimdi yukarıdaki kodda sadece bir satırı güncelleyip, aynı işlemi sadece thermal band için gerçekleştirirsek;

Kodda yapılacak düzenleme :   image = I[:,:,3]




Gördüğünüz üzere, thermal band ile soldaki kişileri de algıladık fakat iki kişiyi bir kişi olarak algıladı. Thermal bandı kullanmak bize bir avantaj sağladı gibi, peki thermal band ile RGB görüntüyü birleştirsek ne olur!

RGB ile thermal bandı birleştirmek için kullandığım yöntem:
  • ilk olarak görüntünün görünür ksımını (yani RGB görüntüyü) YCC ye dönüştürdüm
  • Daha sonra dönüştürülmüş görüntünün ilk bandına thermal bandı yerleştir.

Yukardaki işlem için kodları vermeyeceğim, basit bir araştırma ile bulunabilir. Ben kendi yazdığım fonksiyonu çağırıyorum, içerisini doldurmak size kalmış.

image = Fonksiyonlar.color_transform(I,'YCC')

RGB ve Thermal birleştirilmiş görüntüyü kullanırsak sonuç :



Yukarıdaki kodda NMS için eşik değeri 0.5 olarak kullandık, ve üstteki görüntüde(ortada) gördüğünüz gibi çakışma meydana geldi. Eşik değeri 0.4 olarak ayarlarsak elde edeceğimiz sonuç ise aşağıdaki olacaktır. Yalnız bu defa da, ortadaki bir adet fazla dikdörtgen kaybolurken, soldaki doğru olarak bulunan bir kişiyi de kaybetmiş olduk. Yani burada da bir optimum nokta var, hayatın her bir noktasında olduğu gibi!!! Ayrıca şunu da fark ettiniz ki, RGB ve thermal bandı birleştirince false pozitifler artmış oldu, yani getirisi olduğu gibi götürüsü de oldu. Burada araştırılması gereken nokta her iki bilgiyi aynı anda nasıl daha elverişli kullanabiliriz?? Yazımı burada noktalıyorum, umarım her ne kadar giriş aşamasında bilgiler de olsa birilerine faydası dokunur...


5 yorum:

  1. Merhaba İbrahim Bey,
    İmutilsi pip install ile yüklüyorum ancak import ederken yüklü olmadığını söylüyor. Kodlama bilgim yok ancak tutoriallarla bir şeyler yapmaya çalışıyorum. Oluşturduğum virtual environmentte kullanmak üzere komut penceresi üzerinden imutilsi yüklüyorum ve sonra virtual environmentimi jupyter notebookta açıyorum. Ancak import imutils dediğimde yüklü olmadığını söylüyor. Nasıl çözebilirim. İyi günler dilerim.

    YanıtlaSil
  2. Merhaba, oluşturduğunuz sanal ortama imutils kuruyorsunuz sanırım. Kurulumda bir hata almadıysanız ve imutils kurduğunuz sanal ortamda programı çalıştırıyorsanız import ettiğinizde hata almamanız gerekiyor. sanal ortamla ilgili bir sıkıntı olabilir belki, imutils i sanal ortam dışında "default" ortama da kurabilirsiniz.

    YanıtlaSil
  3. Bu yorum bir blog yöneticisi tarafından silindi.

    YanıtlaSil
  4. Hocam tespit yaparken video fps değeri kaç alıyorsunuz. Benzer işlemleri yaptığımda fps değerim 10'dan yukarı çıkamıyor. Hızlandırabilmek için verebileceğiniz bir tavsiye var mı?

    YanıtlaSil
    Yanıtlar
    1. Şu an hatırlamıyorum hızını, fakat daha fazla doğruluk ve hız için GPU'nuz da varsa eğer derin öğrenme yöntemini deneyebilirsiniz. Hali hazırda eğitilmiş modeller insan tanımada daha başarılı.

      Sil