Başlangıç > Donanım/Yazılım > Ortanca filtresi ( median filter )

Ortanca filtresi ( median filter )

Ortanca filtresi, özellikle görüntü işlemede sıklıkla kullanılan bir filtredir. Görüntüyü keskinleştirmek veya gürültüyü azaltmak için kullanılır fakat daha basit işler içinde kullabilir. Bunu bir örnekle anlatalım.

Gürültülü ortamda ADC okuma işinde uygulanan en yaygın yöntemlerden biri; okunan değerleri bir diziye yerleştirmek ve n kadar okuma sonunda bütün değerlerin ortalamasını almaktır. Fakat bu yöntem gürültünün geniliğine ve n sayısına göre sonucu gerçek değerden saptırır.

ADC girişine uyguladığımız gürültülü gerilimin 1000 değeri civarında olması gerektiğini ve 6 adet örnek sonunda da tüm değerlerin ortalamasını aldığımızı düşünelim ve bu 6 değer içerisinde de 2 adet gürültülü peak değeri olsun.

ADC nin aldığı değerlerin ise sırasıyla 996, 1718, 1002, 993, 1692, 1003 olduğunu düşünelim. Değerlere şöyle bir göz attığımızda 1718 ile 1692 nin gürültü olduğunu veya yanlış ölçtüğünü rahatlıkla söyleyebiliriz. Diğerleri ise asıl olması gereken 1000 değerinden çok az sapmıştır ve bunlarıda ölçüm hatası olarak adlandırabiliriz. Bu 6 sayının ortalamasını aldığımızda ise 1234 sayısını elde ederiz. Yani 6 adet okuma sonunda filtrelenmiş değer 1234 dür. Birde ortanca filtresini uygulayarak bakalım.

Sayıları tekrar yazarsak 996, 1718, 1002, 993, 1692, 1003 . Bu sayıları 3 erli gruplar halinde ele alıp her 3 erli grubun ortancasını asıl sayı ile yer değiştirelim. Yanlız ilk ve son sayılar için kendilerini birer kez daha yazarak 3 er grup oluşturacağız.

1. gurup: ilk sayı 2 kez yazılarak 996, 996, 1718 bu üç sayının ortancası 996 dır. O halde ilk sayının yeni değeri ( değişmedi ) 996 dır.

2. gurup: 996, 1718, 1002 bu üç sayının ortancası 1002 dır. O halde ikinci sayının yeni değeri ( değişti ) 1002 dir.

3. gurup: 1718, 1002, 993 bu üç sayının ortancası 1002 dır. O halde üçüncü sayının yeni değeri ( değişmedi ) 1002 dir.

4. gurup: 1002, 993, 1692 bu üç sayının ortancası 1002 dır. O halde dördüncü sayının yeni değeri ( değişti ) 1002 dir.

5. gurup: 993, 1692, 1003 bu üç sayının ortancası 1003 dür. O halde beşinci sayının yeni değeri ( değişti ) 1003 dür.

6. gurup: son sayı 2 kez yazılarak 1692, 1003, 1003 bu üç sayının ortancası 1003 dür. O halde son sayının yeni değeri ( değişmedi ) 1003 dür.

Buna göre 996, 1718, 1002, 993, 1692, 1003 sayılarının yeni değerleri 996, 1002, 1002, 1002, 1003, 1003 dür. Görüldüğü üzere gürültüden kaynaklı 1718 ve 1692 sayıları kaybolmuştur. Yeni değerlerin ortalaması ise 1001,3 dür.

Değerleri ortanca filtresine sokmadan önce ortalama 1234 idi, ortanca filtresi sonucundaki ortalama ise 1001,3 oldu. Görüldüğü gibi ortaca filtresinden sonra değerlerin ortalamasını almak ile değerlerin ortalamasını doğrudan almak arasında ciddi bir fark var.

Ortanca filtresi dokunmatik ekran ve dijital terazi uygulamalarında sıklıkla kullanılmaktadır.

Örnek bir C kodu aşağıdaki gibidir.

#define ADC_SAMPLE_PIECES     10

unsigned int wADCValues[ADC_SAMPLE_PIECES];

unsigned int wGetMedianFilteredResult(unsigned int *p)
{
char cResult;
unsigned char i;
unsigned int wLastValue;
unsigned int wFirstValue;
unsigned int wReturned;
unsigned int MedianFilterBuffer[ADC_SAMPLE_PIECES];
wLastValue=*(p+ADC_SAMPLE_PIECES-1);
wFirstValue=*p;

for (i = 0; i < ADC_SAMPLE_PIECES; i++) {

 if(i==0) {
  cResult=0;
   if(wFirstValue<*(p)) cResult++;
    else cResult–;
   if(wFirstValue<*(p+1)) cResult++;
    else cResult–;
   if( (wFirstValue==*(p))||(wFirstValue==*(p+1)) ) MedianFilterBuffer[i]=wFirstValue;
    else if(cResult==0) MedianFilterBuffer[i]=wFirstValue;
  cResult=0;
   if(*(p)<wFirstValue) cResult++;
    else cResult–;
   if(*(p)<*(p+1)) cResult++;
    else cResult–;
   if( (*(p)==*(p+1))||(*(p)==*(p+1)) ) MedianFilterBuffer[i]=*(p);
    else if(cResult==0) MedianFilterBuffer[i]=*(p);
  cResult=0;
   if(*(p+1)<wFirstValue) cResult++;
    else cResult–;
   if(*(p+1)<*(p)) cResult++;
    else cResult–;
   if( (*(p+1)==wFirstValue)||(*(p+1)==*(p)) ) MedianFilterBuffer[i]=*(p+1);
    else if(cResult==0) MedianFilterBuffer[i]=*(p+1);
  p++; continue;
 }

 if(i==ADC_SAMPLE_PIECES-1) {
  cResult=0;
   if(*(p-1)<*(p)) cResult++;
    else cResult–;
   if(*(p-1)<wLastValue) cResult++;
    else cResult–;
   if( (*(p-1)==*(p))||(*(p-1)==wLastValue) ) MedianFilterBuffer[i]=*(p-1);
    else if(cResult==0) MedianFilterBuffer[i]=*(p-1);
  cResult=0;
   if(*(p)<*(p-1)) cResult++;
    else cResult–;
   if(*(p)<wLastValue) cResult++;
    else cResult–;
   if( (*(p)==wLastValue)||(*(p)==wLastValue) ) MedianFilterBuffer[i]=*(p);
    else if(cResult==0) MedianFilterBuffer[i]=*(p);
  cResult=0;
   if(wLastValue<*(p-1)) cResult++;
    else cResult–;
   if(wLastValue<*(p)) cResult++;
    else cResult–;
   if( (wLastValue==*(p-1))||(*(p+1)==*(p)) ) MedianFilterBuffer[i]=wLastValue;
    else if(cResult==0) MedianFilterBuffer[i]=wLastValue;
  p++; continue;
 }

 cResult=0;
  if(*(p-1)<*(p)) cResult++;
   else cResult–;
  if(*(p-1)<*(p+1)) cResult++;
   else cResult–;
  if( (*(p-1)==*(p))||(*(p-1)==*(p+1)) ) MedianFilterBuffer[i]=*(p-1);
   else if(cResult==0) MedianFilterBuffer[i]=*(p-1);
 cResult=0;
  if(*(p)<*(p-1)) cResult++;
   else cResult–;
  if(*(p)<*(p+1)) cResult++;
   else cResult–;
  if( (*(p)==*(p+1))||(*(p)==*(p+1)) ) MedianFilterBuffer[i]=*(p);
   else if(cResult==0) MedianFilterBuffer[i]=*(p);
 cResult=0;
  if(*(p+1)<*(p-1)) cResult++;
   else cResult–;
  if(*(p+1)<*(p)) cResult++;
   else cResult–;
  if( (*(p+1)==*(p-1))||(*(p+1)==*(p)) ) MedianFilterBuffer[i]=*(p+1);
   else if(cResult==0) MedianFilterBuffer[i]=*(p+1);
 p++;
}
wReturned=0;
for (i = 0; i < ADC_SAMPLE_PIECES; i++) wReturned+=MedianFilterBuffer[i];
wReturned/=ADC_SAMPLE_PIECES;

return wReturned;
}

Yukarıdaki kodlarda ADC_SAMPLE_PIECES, ADC den alınan örnek sayısıdır. Bu değer değiştirilerek filtrasyon genişliği artırılabilir. unsigned int wADCValues[ADC_SAMPLE_PIECES] ise ADC sonuçlarının tutulduğu tampon bellektir. Her ADC ölçüm sonucunu bu alana kaydırmalı olarak kaydetmek gerekir. unsigned int wGetMedianFilteredResult(unsigned int *p) fonksiyonu ise işaret edilen tampon bellekteki değerleri ortanca filtresine tabi tutup sonucun ortalamasını geri döndürür.

  1. ORHAN YILMAZ
    13 Mart 2014, 12:04

    Selamlar,
    Daha önce hiç duymadığım bir filtreyi sayenizde öğrendim. Çok teşekkür ederim. Fakat olaya çok fazla hakim olamadım. Sonuç ortanca değere göre bulunduğuna göre diziyi parçalamak yerine tamamında bu işlemi yapamazmıyız. Deneme yaptım yakın değerler buluyorum. Ama denk düşüyor olabilir diyerek size danışmak istedim.

    • Freelancer
      14 Mart 2014, 05:06

      Aslında bu filtrenin amacı matris veya dizi içerisideki gürültüyü gidermek. bir elemanın filtrelenmesi komşu elemanların değerlerine bağlı olarak değiştiğinden parçalama yerine tamamını almak şeklinde bir işlem tanımlı değil. kısacası amaç bir diziden filtrelenmiş tekbir değer elde etmek değil.

      mesela filtrelenecek bir dizimiz olsun.
      3 erli filtrelemek istendiğinde dizinin n inci elemanın yeni değeri
      dizinin n-1, n, n+1 elemanlarının ortancası olacak ve yeni değer n inci elemanın yerine yazılacaktır. Ayrıca filtreleme işlemi boyunca orjinal dizi içerisindeki hiçbir eleman modifiye edilmez ve filtrelenmiş değerler başka bir dizi içerisinde saklanır.

      • 26 Ağustos 2014, 10:49

        Cevabınız için teşekkürler. Ben de biraz göz attım. Dediğiniz gibi görüntü işlemede karıncalanma dediğimiz gürültü faktörlerini silmek için kullanılabiliyor sanırım. Ayrıca çekirdekler halinde yazıldığında FPGA gibi platformlara uygulanması da çok kolay.
        Bilgi için tekrar teşekkürler.

  2. yusuf karış
    20 Nisan 2016, 22:49

    merhaba ben öncelikle mühendıslık son sınıf ogrencsıyım.

    sınav sorusu olarak elimizde söyle bir soru var.

    3 adet resim dusunelım;

    a) resminde orjınal resım, b)resminde orjınal resme 100 kez 3*3 medyan fıltre uygulanmıs resım ve c) resmınde ise orjınal resme 100 kez 3*3 ortalama filtre uygulanmıs resim verilmiştir. b) ve c) resminde oluşan farkın nedenlerini açıklayınız diyor.

    şimdiden teşekkurler cvp için…

  1. 08 Kasım 2011, 21:14

Yorum bırakın