Bilgisayarlı görüde, görüntü gradyanlarındaki bilgilerden faydalanarak nesne tanımlaması yapan birçok algoritma vardır. HOG (Histogram of Oriented Gradients) bu algoritmalardan biridir. Histogramlar, sınıflandırılmış verilerin sütun grafiğidir. Her sütun, kutu (bin) olarak da adlandırılan belirli bir değer aralığına düşen bir veri grubunu gösterir. Orientation (yönlendirme) ise bir görüntüdeki gradyanların yönünü ifade eder. Kısacası HOG, bir görüntüdeki yönlü gradyanların histogramını üretir.
HOG algoritmasını daha iyi tanımak için, adım adım nasıl uygulandığına bakalım:
- Öncelikle, HOG bir görüntü alır ve her piksel için gradyan şiddetini (gradient magnitude) ve yönünü (gradient direction) hesaplar. 8*8 piksel boyutundaki bir hücrenin gradyanları yukarıdaki gibi gösterilmiştir. Her bir pikseldeki gradyan vektörünün yönü, piksel yoğunluğunun değişiminin yönünü; şiddeti (uzunluğu) ise komşu piksellere göre yoğunluğun ne kadar hızlı değiştiğini gösterir.
- HOG, girdi olarak verdiğimiz görüntüyü eşit boyutlardaki hücrelere bölecektir (aşağıdaki animasyondaki mavi pencereler). Hücrelerin boyutu kullanıcı tarafından ayarlanabilir ve görüntüde tespit etmek istediğimiz detayların ölçeğine göre seçilmelidir.
- Her hücredeki tüm piksellerin gradyan yönleri belirtilen sayıdaki kutulara göre gruplanıp bir histogram elde edilir. Kutuların (sütunların) yüksekliği, kutudaki gradyanların genliklerinin toplamı olacaktır. Sütun sayısı genellikle 9 olarak seçilir. Böylece her bir sütunun genişliği 20 derece olur.
- Hücreler eşit boyuttaki bloklar halinde gruplanacaktır (Aşağıdaki animasyondaki kırmızı kutu). Bu blok penceresinin görüntü üzerindeki hareket miktarına adım (stride) denir. Bloktaki hücre sayısı ve adım, kullanıcı tarafından belirlenen parametrelerdir. Adım, genellikle blok boyutunun yarısı olarak ayarlanır.
- Her hücre histogramı, bloktaki diğer hücrelere göre normalize edilecektir. Tüm bloklardan gelen normalleştirilmiş histogramlar uç uca eklenip tek bir özellik vektörü elde edilecektir. Bu özellik vektörüne HOG tanımlayıcısı denir.

HOG tanımlayıcısını oluşturmak için OpenCV’nin HOGDescriptor sınıfını kullanacağız. HOG tanımlayıcısının parametreleri, HOGDescriptor fonksiyonu kullanılarak ayarlanır. HOGDescriptor() fonksiyonunun parametreleri ve varsayılan değerleri aşağıda verilmiştir:
cv2.HOGDescriptor(win_size=(64, 128),
block_size=(16, 16),
block_stride=(8, 8),
cell_size=(8, 8),
nbins=9,
win_sigma=DEFAULT_WIN_SIGMA,
threshold_L2hys=0.2,
gamma_correction=true,
nlevels=DEFAULT_NLEVELS)
- win_size: Algılama penceresinin piksel cinsinden boyutu (genişlik, yükseklik). İlgi alanını tanımlar. Hücre boyutunun bir tamsayı katı olmalıdır.
- block_size: Piksel cinsinden blok boyutu (genişlik, yükseklik). Her blokta kaç hücre olduğunu tanımlar. Hücre boyutunun bir tamsayı katı olmalı ve algılama penceresinden daha küçük olmalıdır. Blok ne kadar küçük olursa, o kadar ince ayrıntı elde ederiz.
- block_stride: Piksel cinsinden blok adımı uzunluğu (yatay, dikey). Hücre boyutunun bir tamsayı katı olmalıdır. block_stride, bitişik bloklar arasındaki mesafeyi tanımlar, örneğin yatay olarak 8 piksel ve dikey olarak 8 piksel gibi. Blok adımının daha uzun olması, algoritmanın daha hızlı çalışmasını sağlar (çünkü daha az blok değerlendirilir), ancak algoritma iyi performans göstermeyebilir.
- cell_size: Piksel cinsinden hücre boyutu (genişlik, yükseklik). Hücrenin boyutunu belirler. Hücre ne kadar küçük olursa, o kadar ince ayrıntı elde edilir.
- nbins: Histogramın kutu (bin) sayısı. Histogramları oluşturmak için kullanılan açısal kutuların sayısını belirler. Daha fazla kutu ile daha fazla eğim yönü yakalanacaktır. HOG, işaretsiz gradyanlar kullanır, bu nedenle açısal kutular 0 ile 180 derece arasında değerlere sahip olacaktır.
- win_sigma: Gauss yumuşatma penceresi parametresi. HOG algoritmasının performansı, histogramları hesaplamadan önce her piksele bir Gauss penceresi uygulayarak blokların kenarlarına yakın pikselleri yumuşatarak geliştirilebilir.
- threshold_L2hys: L2-Hys (Lowe-style clipped L2 norm) yöntemi blokları normalleştirmek için kullanılır ve bir L2-normunu takiben kırpma ve yeniden normalleştirmeden oluşur. Kırpma, her blok için tanımlayıcı vektörün maksimum değerini verilen eşiğin değerine (varsayılan olarak 0.2) sahip olacak şekilde sınırlar.
- gamma_correction: Gama düzeltme ön işlemesinin gerekli olup olmadığını belirtir. Gama düzeltmesi, HOG algoritmasının performansını bir miktar artırır.
- nlevels: Maksimum algılama penceresi sayısı artışı.
HOG Tanımlayıcısı: [0.25606513 0.01537703 0.04601376 ... 0.08963854 0.02995563 0.08873854]
HOG Tanımlayıcısının boyutu: (34596,)
Elde ettiğimiz HOG Tanımlayıcısı (özellik vektörü), tüm bloklardaki hücrelerden elde edilen normalize edilmiş histogramların uç uca eklenerek elde edildiği uzun bir vektör olacaktır. HOG özellik vektörünün boyutu; toplam blok sayısı, blok başına düşen hücre sayısı ve histogramdaki kutu sayısının çarpımı kadar olacaktır.
HOG Tanımlayıcısını Görselleştirme
Scikit-image kütüphanesinin aksine OpenCV ile HOG Tanımlayıcısını görselleştirmenin kolay bir yolu yoktur, bu yüzden öncelikle özellik vektörümüz üzerinde bazı manipülasyonlar yapmalıyız. Hesaplamayı kolaylaştırmak için öncelikle HOG Tanımlayıcısını yeniden boyutlandıracağız. Daha sonra her hücrenin ortalama histogramını hesaplayacağız ve son olarak histogram kutularını vektörlere dönüştüreceğiz. Tüm vektörleri elde ettikten sonra her bir hücreye ait vektörleri çizeceğiz.

Şimdi HOG görüntüsünü ve histogramını daha iyi anlamak için hem orijinal hem de HOG görüntüsündeki çeşitli hücreleri daha yakından inceleyelim.
zoom_hog_cell(16, 2)

Görüntüde yatay bir kenarı içine alan bir hücre seçtik. Kenarlar, görüntüde piksel yoğunluğun aniden değiştiği alanlardır. Gradyanları incelediğimizde yüksek oranda dikey yönde değişimler görüyoruz. Bu nedenle histogramda da gördüğümüz üzere 90 derecelik kutu diğer kutulara göre oldukça baskın olacaktır.
zoom_hog_cell(27, 19)

Dikey bir kenarı içeren hücredeki piksel gradyanlarına baktığımızda, piksel yoğunluğu değişimlerinin baskın olarak yatay, 180 dereceye yakın yönde olduğunu görüyoruz. Bu nedenle, histogramdaki 170–180 derecelik kutunun diğer kutulara nazaran baskın olmasını bekliyoruz. Fakat histograma baktığımızda aynı zamanda 0–10 derecelik kutunun da baskın olduğunu görüyoruz. Bunun nedeni aslında HOG algoritmasının işaretsiz gradyanlar kullanmasıdır, yani 0 ve 180 derecelik gradyanları aynı yönde kabul edebiliriz.
zoom_hog_cell_2(22, 14)

Son olarak bir de çapraz bir kenarı içeren hücreyi inceleyelim. Çapraz yöndeki bir kenarın olduğu görüntüde piksel yoğunluğu değişimi de çapraz yönde olacağından gradyanlarda çapraz yönde olacaktır. Görüntüdeki çapraz kenar 45 dereceye yakın olduğundan, 40–50 derecelik kutuda baskın gradyan şiddeti görmeyi bekliyoruz. Histogramda da zaten bunu gözlemliyoruz. Fakat 40–50 derecelik kutuya eşlik eden, daha az şiddetli fakat baskın iki kutu daha görüyoruz. Bunun nedeni, histogramlar oluşturulurken, kutunun sınırlarına yakın olan açılardaki gradyanlar, bitişik kutulara orantılı olarak katkıda bulunur. Örneğin, 40 derecelik açıya sahip bir gradyan, 30 derecelik ve 50 derecelik kutunun tam ortasındadır. Bu nedenle, gradyanın şiddeti 30 derecelik ve 50 derecelik kutulara eşit olarak bölünür. En baskın kutuya eşlik eden bitişik daha az şiddetli kutular görmemizin nedeni budur.
Bu yazımda nesne tanımlamasında yaygın olarak kullanılan HOG algoritmasını inceledik, bir görüntüden Python programlama dili ve OpenCV kütüphanesini kullanarak HOG özellik vektörünü elde ettik. HOG görüntüsünü ve histogramları daha yakından inceleyerek daha iyi anlamaya çalıştık ve yorumladık. Tüm kaynak koda ve HOG özellik tanımlayıcısı kullanarak, görüntüler üzerinde kümeleme yaptığım bir uygulamaya göz atmak istersiniz aşağıdaki link ile ulaşabilirsiniz. Umarım okurken ve uygularken keyif almışsınızdır. Bir sonraki yazımda görüşmek üzere!