Sayfalar

21 Ekim 2017 Cumartesi

Python - Selective Search Segmentation

Segmentasyonda amaç bir görüntüdeki farklı nesneleri ayırt edebilmek için her bir piksele bir sınıf değeri atamaktır. Yani görüntüdeki şekil ya da renk olarak birbirlerinden ayrılan her bir kapalı alan içerisindeki piksellere aynı sınıf değeri atama işlemidir. Nesne tanıma ise bir görüntüde aranan bir nesneyi bulma işlemidir. 

Örneğin görüntüde aradığımız şey kuşlar olsun; Bir sistemimiz/algoritmamız var diyelim, bu sisteme bir görüntüyü girdi olarak veriyoruz ve çıkışında görüntünün herbir pikseli için kuş bulunma olasılığını/kuşa ait olan pikselleri ya da bulunan kuşları içeren bir dikdörtgen alanın koordinat ve uzunluklarını hesaplayıp döndürüyor. Bu şekilde bir görüntü üzerinde herhangi bir nesneyi arayabilmek için sliding window (kayan pencere) ile daha önce eğitilmiş bir model kullanılarak istenilen nesne görüntü üzerinde aranır. Daha önceki bir yazımda yaya tanıma işlemini OpenCV'de tanımlı HOG+Linear SVM modelini kullanarak gerçekleştirmiştik. 

Kayan pencere ile nesne aramaya alternatif olarak, görüntüye segmentasyon algoritmaları uyguladıktan sonra bulunan bölgeler bazında nesne arama işlemi de gerçekleştirebiliriz. Yani görüntüyü ilk olarak alt parçalara ayırıp, segment(bölge-nesne) adaylarını bulabiliriz, böylece kayan pencere ile tüm görüntü üzerinde dolaşmak (her bir alt görüntü için nesne tanıma modelini çalıştırmak) gibi performans isteyen konvolüsyon işlemini yapmamıza gerek kalmayabilir. Sliding window (kayan pencere) işlemine alternatif olan bu yöntem Region Proposal olarak adlandırılmaktadır ve Selective Search algoritması popüler bir region proposal (bölge önerme) algoritmasıdır.

Bölge önerme algoritması kabaca, girdi olarak aldığı bir görüntüdeki nesne bulunma ihtimali olan alanları (bknz: objectness) çevreleyen kutucukları (alt görüntü alanlarını) hesaplar. Daha sonra ise bulunan bu alt alanlarda nesne tanıma modelleri kullanılarak sınıflama işlemi gerçekleştirilebilir.

Selective search Felzenswalb and Huttenlocher superpiksel algoritmasını kullanarak hiyerarşik segmentasyon hesaplama temelli bir yaklaşımdır. F&H algoritması python skimage kütüphanesi ile şu şekilde uygulanabilir.


import numpy as np
import matplotlib.pyplot as plt
from skimage.segmentation import felzenszwalb
import cv2

img = cv2.imread('dogs.jpg')
segments = felzenszwalb(img, scale=100, sigma=2, min_size=50)


fig = plt.figure()

ax1 = fig.add_subplot(2,1,1)
ax1.axes.get_xaxis().set_visible(False)
ax1.axes.get_yaxis().set_visible(False)
ax1.imshow(img)

ax2 = fig.add_subplot(2,1,2)
ax2.axes.get_xaxis().set_visible(False)
ax2.axes.get_yaxis().set_visible(False)
ax2.imshow(segments,cmap='Paired')

Selective search algoritması F&H algoritması ile başlangıç segmentlerini bulduktan sonra, her bir segment bölgesini bölge adayı olarak listeye ekler. Daha sonra ise benzer olan segmentleri gruplayarak segment adayı sayısını azaltır ve bu işlemi iteratif olarak tekrarlar. Her bir iterasyonda daha büyük bir bölge adayı bulunur ve aday listesine eklenir, böylece hiyerarşik bir yapıda  küçükten büyüğe doğru bir segment listesi hazırlanmış olur.
Kullanılan benzerlik kriterleri ve daha ayrıntılı bilgi için şu linkteki yazıyı inceleyebilirsiniz.

Selective search (https://github.com/AlpacaDB/selectivesearch)
''' https://github.com/AlpacaDB/selectivesearch '''
img_lbl, regions = selectivesearch.selective_search(img, scale=500, sigma=0.9, min_size=100)

sorted_regions = sorted(regions, key=lambda k: k['size']) 

selected = []
for r in sorted_regions:
   
    if len(r['labels'])>5 or r['size']<1000:
#        print(len(r['labels']))
        continue
    
    selected.append(r)
    

for r in selected:
    x = r['rect'][0]
    y = r['rect'][1]
    w = r['rect'][2]
    h = r['rect'][3]
    cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),1)
    

cv2.imshow("img",img)
Bulunan bölge adayı sayısı aslında bir hayli fazla, fakat biz bazı filtrelemeler yaparak bir çok bölgeyi elimine ettik ve üstte görmüş olduğunuz alanlar geriye kaldı. Aşağıda selective_search fonksiyonunun geri döndürdüğü 'regions'  ların 'size' a göre sıralanmış halinin içeriğini görüntülüyoruz. Her bir bölgeyi içine alan dikdörtgen koordinatları, etiket değerleri ve büyüklükleri ile saklanıyor.


Bu yazımızda selective search ile nesne adayı bölgelerin nasıl bulunduğuna dair basit bir örnek gerçekleştirmiş olduk. OpenCV 3.3 ile çeşitli nesneler için eğitilmiş derin öğrenme modellerinin kullanılmasına destek verildiğini düşünürsek, hali hazırda eğitilmiş bazı modelleri kullanarak çeşitli nesnelerin tanınması işlemini kolayca gerçekleştirebiliriz. Belki bununla ilgili bir yazıyı da ilerleyen zamanda hayata geçirebiliriz. 


Her türlü görüş, öneri ve sorularınızı bekleriz...


2 yorum:

  1. Hocam gerçekten dikkat çekici ve popüler konulara değiniyorsunuz. Teşekkürler :)

    YanıtlaSil
  2. Faydalı olduysa ne mutlu bana. İyi çalışmalar...

    YanıtlaSil