# Otsu methodu
Bilgisayarla görme ve görüntü işlemede, otomatik görüntü eşikleme yapmak için Nobuyuki Otsu (大津展之 Ōtsu Nobuyuki) tarafından oluşturulan Otsu methodu kullanılmaktadır. En basit haliyle, algoritma pikselleri ön plan ve arka plan olmak üzere iki sınıfa ayıran tek bir yoğunluk eşiği döndürmektedir. Bu eşik, sınıf içi yoğunluk varyansını en aza indirerek veya eşdeğer olarak, sınıflar arası varyansı maksimize ederek belirlenmektedir. Otsu'nun yöntemi, Fisher's Discriminant Analysis'in tek boyutlu ayrık bir analoğudur. Jenks optimizasyon yöntemiyle ilgilidir ve yoğunluk histogramında gerçekleştirilen global olarak en uygun k-ortalamalara eşdeğerdir. Çok seviyeli eşiklemenin genişletilmesi orijinal belgede açıklanmıştır ve o zamandan beri hesaplama açısından verimli uygulamalar önerilmiştir.


## Otsu methodu.
Algoritma, iki sınıfın ağırlıklı bir toplamı olarak tanımlanan sınıf içi varyansı en aza indiren eşiği kapsamlı bir şekilde arar.
σ^2_w(t)=ω_0(t)σ^2_0(t)+ω_1(t)σ^2_1(t)
ω_0 ve ω_1 ağırlıkları, t eşiği ile ayrılan iki sınıfın olasılıklarıdır. σ^2_0 ve σ^2_1 bu iki sınıfın varyanslarıdır.
ω_0,1(t) sınıf olasılığı, histogramın L kutularından aşağıdaki gibi hesaplanır:
 ω_0(t) amp; =∑_i=0^t-1 p(i)
 ω_1(t) amp; =∑_i=t^L-1 p(i)
2 sınıf için, sınıf içi varyansı en aza indirmek, sınıflar arası varyansı en üst düzeye çıkarmakla eşdeğerdir.
 σ^2_b(t) amp; =σ^2-σ^2_w(t)=ω_0(μ_0-μ_T)^2+ω_1(μ_1-μ_T)^2 
 amp; =ω_0(t) ω_1(t) [μ_0(t)-μ_1(t)]^2
Bu, ω sınıf olasılıkları cinsinden ifade edilir. Sınıf μ anlamına gelir. Burada sınıf μ_0(t), μ_1(t) ve μ_T anlamına gelir.
 μ_0(t) amp; = ∑_i=0^t-1 i p(i)/ω_0(t)
 μ_1(t) amp; = ∑_i=t^L-1 i p(i)/ω_1(t)
 μ_T amp; = ∑_i=0^L-1 ip(i)
Aşağıdaki ilişkiyi bunlarla açıklayabiliriz:
 ω_0μ_0+ω_1μ_1 amp; = μ_T 
 ω_0+ω_1 amp; =1
Sınıf olasılıkları ve sınıf ortalamaları yinelemeli olarak hesaplanabilir. Bu fikir etkili bir algoritma sağlamaktadır.


### Algoritma.
  - Her yoğunluk seviyesinin histogramı ve olasılıkları hesaplanır.
  - İlk ω_i(0) ve μ_i(0) ayarlanır.
  - Adım adım t = 1, … tüm olası eşikler maksimum yoğunluk için hesaplanır.
   - ω_i ve μ_i güncellenir.
   - σ^2_b(t) hesaplanır.
  - İstenen eşik maksimum σ^2_b(t) değerine karşılık gelir.


### MATLAB veya Octave uygulaması.
histogramSayacı farklı gri düzeylerinde (8 bitlik görüntüler için tipik) bir gri tonlamalı görüntünün 256 elemanlı bir histogramıdır.
function seviye = otsu(histogramSayacı)
total = sum(histogramSayacı); % görüntüdeki toplam piksel sayısı
%% OTSU otomatik eşiklemesi
top = 256;
toplamB = 0;
wB = 0;
maksimum = 0.0;
toplam1 = dot(0:top-1, histogramSayacı);
for ii = 1:top
 wF = total - wB;
 if wB > 0 && wF > 0
 mF = (toplam1 - toplamB) / wF;
 val = wB * wF * ((toplamB / wB) - mF) * ((toplamB / wB) - mF);
 if ( val >= maksimum )
 seviye = ii;
 maksimum = val;
 end
 end
 wB = wB + histogramSayacı(ii);
 toplamB = toplamB + (ii-1) * histogramSayacı(ii);
end
end
Matlab, sırasıyla Otsu methodu ve Multi Otsu methoduyla uygulanan Görüntü İşleme Araç Kutusu'nda graythresh() ve multithresh() yerleşik fonksiyonlarına sahiptir.


## Sınırlamalar.
Otsu methodunda, histogramın iki modlu dağılıma sahip olduğu ve iki tepe arasında derin ve keskin bir vadiye sahip olduğu varsayılabilirse, nispeten iyi bir performans sergilemektedir. Ancak nesne alanı, arka plan alanıyla karşılaştırıldığında nesne alanı küçükse, histogram artık iki modluluk göstermez. Ve nesnenin varyansları ve arka plan yoğunlukları, ortalama farkla karşılaştırıldığında büyükse veya görüntü, ek gürültü tarafından ciddi şekilde bozulursa, gri seviye histogramının keskin vadisi bozulmaktadır. Ardından, Otsu'nun yöntemiyle belirlenen olası yanlış eşik, segmentasyon hatasıyla sonuçlanmaktadır. (Burada nesne boyutunu, nesne alanının tüm görüntü alanına oranı ve ortalama farkı, nesnenin ve arka planın ortalama yoğunluklarının farkı olarak tanımlıyoruz)
Ampirik sonuçlar, nesne segmentasyonu için kullanılan global eşikleme tekniklerinin performansının (Otsu algoritması dahil) küçük nesne boyutu, ön plan ve arka plan pikselleri arasındaki küçük ortalama fark, nesneye ait olan ve nesneye ait olan piksellerin büyük varyansları ile sınırlı olduğunu göstermektedir.


## İyileştirmeler.
Otsu methodunun sınırlamalarını ele almak için çeşitli uzantılar geliştirilmiştir. Bir popüler uzantı, gürültülü görüntülerde nesne bölütleme görevi için daha iyi performans gösteren iki boyutlu Otsu methodudur. Burada, segmentasyon sonuçlarını iyileştirmek için belirli bir pikselin yoğunluk değeri, yakın komşuluğunun ortalama yoğunluğu ile karşılaştırılmaktadır.
Her pikselde, komşuların ortalama gri seviye değeri hesaplanır. Verilen pikselin gri seviyesi L kadar ayrık değerlere bölünür ve ortalama gri seviyesi de aynı L değerlerine bölünür. Ardından bir çift oluşturulur: (i, j) her pikselin gri seviyesi ve komşuların ortalaması. Her çift, L×L olası 2 boyutlu kutulardan birine aittir . Her bir (i, j) çiftinin toplam sayısı f_ij fonksiyonu olarak verilir. N görüntüsündeki toplam piksel sayısına bölünür, 2 boyutlu bir histogramda birleşik olasılık kütle fonksiyonunu tanımlar:
P_ij = f_ij/N, ∑_i=0^L-1∑_j=0^L-1 P_ij=1
2 boyutlu Otsu methodu, 2 boyutlu histograma dayalı olarak aşağıdaki gibi geliştirilmiştir.
İki sınıfın olasılıkları şu şekilde gösterilebilir: 
 ω_0 amp; = ∑_i=0^s-1∑_j=0^t-1 P_ij
 ω_1 amp; = ∑_i=s^L-1∑_j=t^L-1 P_ij
İki sınıfın yoğunluk ortalama değer vektörleri ve toplam ortalama vektör aşağıdaki gibi ifade edilebilir:
 μ_0 amp; =[μ_0i, μ_0j]^T = [∑_i=0^s-1∑_j=0^t-1 i P_ij/ω_0, ∑_i=0^s-1∑_j=0^t-1 j P_ij/ω_0]^T 
 μ_1 amp; =[μ_1i, μ_1j]^T = [∑_i=s^L-1∑_j=t^L-1 i P_ij/ω_1, ∑_i=s^L-1∑_j=t^L-1 j P_ij/ω_1]^T 
 μ_T amp; =[μ_Ti, μ_Tj]^T = [∑_i=0^L-1∑_j=0^L-1 i P_ij, ∑_i=0^L-1∑_j=0^L-1 j P_ij]^T
Çoğu durumda köşegen dışı olasılık ihmal edilebilir, bu nedenle doğrulaması kolaydır:
ω_0+ω_1 ≅1
ω_0μ_0+ω_1μ_1 ≅μ_T
Sınıflar arası ayrık matris şu şekilde tanımlanır:
S_b = ∑_k=0^1ω_k[(μ_k-μ_T)(μ_k-μ_T)^T]
Ayrık matrisin izi şu şekilde ifade edilebilir:
 amp; tr(S_b) 
 = amp; ω_0[(μ_0i-μ_Ti)^2 + (μ_0j-μ_Tj)^2] + ω_1[(μ_1i-μ_Ti)^2 + (μ_1j-μ_Tj)^2] 
 = amp; (μ_Tiω_0-μ_i)^2 + (μ_Tjω_0-μ_j)^2/ω_0(1-ω_0)
μ_i = ∑_i=0^s-1∑_j=0^t-1iP_ij
μ_j = ∑_i=0^s-1∑_j=0^t-1jP_ij
Tek boyutlu Otsu methoduna benzer şekilde, optimal eşik (s,t), tr(S_b)maksimize edilerek elde edilir.


### Algoritma.
s ve t tek boyutlu Otsu methoduna benzer şekilde yinelemeli olarak elde edilmektedir. s ve t değerleri, maksimum tr(S_b) elde edilene kadar değiştirilir.
max,s,t = 0;
for ss: 0 to L-1 do
 for tt: 0 to L-1 do
 evaluate tr(S_b);
 if tr(S_b) > max
 max = tr(S,b);
 s = ss;
 t = tt;
 end if
 end for
end for
return s,t;
tr(S_b) fonksiyonunu değerlendirmek ve zaman performansını iyileştirmek için hızlı bir özyinelemeli dinamik programlama algoritması kullanılabilir. Bununla birlikte, dinamik programlama yaklaşımıyla bile, 2d Otsu methodu hala büyük zaman karmaşıklığına sahiptir. Bu nedenle, hesaplama maliyetini azaltmak için birçok araştırma yapılmıştır.
P_ij, i * P_ij ve j * P_ij üzerinde toplamalar yapılarak 3 tablo oluşturulur. Çalışma zamanı karmaşıklığı maksimum (O(N_pixels), O(N_bins*N_bins)) olur. Eşik açısından yalnızca kaba çözünürlük gerekiyorsa, N_bins azaltılabilir.


### Matlab uygulaması.
Fonksiyon giriş ve çıkışları:
hists; gri tonlamalı değer ve komşu ortalama gri tonlamalı değer çiftinin 256×256 2D histogramıdır.
total; verilen görüntüdeki çiftlerin sayısıdır. 2D histogramın her bir yöndeki kutularının sayısı ile belirlenir.
threshold; elde edilen eşik değeridir.
function threshold = otsu_2D(hists, total)
maximum = 0.0;
threshold = 0;
helperVec = 0:255;
mu_t0 = sum(sum(repmat(helperVec',1,256).*hists));
mu_t1 = sum(sum(repmat(helperVec,256,1).*hists));
p_0 = zeros(256);
mu_i = p_0;
mu_j = p_0;
for ii = 1:256
 for jj = 1:256
 if jj == 1
 if ii == 1
 p_0(1,1) = hists(1,1);
 else
 p_0(ii,1) = p_0(ii-1,1) + hists(ii,1);
 mu_i(ii,1) = mu_i(ii-1,1)+(ii-1)*hists(ii,1);
 mu_j(ii,1) = mu_j(ii-1,1);
 end
 else
 p_0(ii,jj) = p_0(ii,jj-1)+p_0(ii-1,jj)-p_0(ii-1,jj-1)+hists(ii,jj);
 mu_i(ii,jj) = mu_i(ii,jj-1)+mu_i(ii-1,jj)-mu_i(ii-1,jj-1)+(ii-1)*hists(ii,jj);
 mu_j(ii,jj) = mu_j(ii,jj-1)+mu_j(ii-1,jj)-mu_j(ii-1,jj-1)+(jj-1)*hists(ii,jj);
 end
 if (p_0(ii,jj) == 0)
 continue;
 end
 if (p_0(ii,jj) == total)
 break;
 end
 tr = ((mu_i(ii,jj)-p_0(ii,jj)*mu_t0)^2 + (mu_j(ii,jj)-p_0(ii,jj)*mu_t1)^2)/(p_0(ii,jj)*(1-p_0(ii,jj)));
 if ( tr >= maximum )
 threshold = ii;
 maximum = tr;
 end
 end
end
end