OpenCV ile Kenar Belirleme Algoritmaları

Görüntü üzerinde kenar tespiti yapmak; o görüntüdeki nesneleri tespit etmek, saymak ve özelliklerini belirlemek amacıyla kullanılabilir. Kenar belirleme algoritmaları en temel anlatımıyla, görüntü üzerindeki piksellerin renk değerlerinin bir birlerinden farklılaşması ile belirlenir.

Bir görüntü matrisinden kesit

Yukarıdaki görsele baktığınızda farklılaşmanın nereden başladığını tahmin edebilir misiniz? Gördüğünüz üzere 4 ve 152 numaralı matris elemanları arasında keskin bir renk geçişi olmuş, bu renk geçişi (gürültü olmadığı taktirde) iki farklı nesnenin başlangıç ve bitiş çizgilerini ifade edebilir. İşte bu geçişler bizim için kenar çizgilerini ifade etmektedir. Örnek matrisimiz görüldüğü üzere gri (Gray) renk uzayına sahip bu renk uzayında matris elemanları yani pikseller 0-255 arasında renk değerlerine sahipti eğer görüntümüzü siyah-beyaz renk uzayına çevirir ve 0-1 aralığında renk kodları alması işimizi kolaylaştırmaz mı? İşte bu noktada kenar çıkarımı yapmadan Thresholding (Eşikleme) yapmamız işe yarayabilir. Bu uygulama şeklinde her algoritma kendisine has çıkarımlar yaparak tespit edebilir, bu yüzden görüntümüz de hangisinin daha iyi sonuç verdiğini deneyerek göreceğiz. Aşağıdaki görselde kenar çıkarma algoritması uygulanmış bir görüntü görmektesiniz. Bu görüntü üzerinde geçen kolileri saymak için ideal bir yöntem olabilir mi?

Kenar belirlemek için geliştirilmiş bir çok algoritma vardır ve bu algoritmaların neredeyse tamamına yakını OpenCV içerisinde mevcuttur.

Kenar Belirleme Algoritmaları

  • Canny
  • Sobel
  • Prewitt
  • Lablacian
  • Zero-Cross

Bu algoritmalar içerisinden Canny algoritması verdiği başarılı sonuçlar neticesinde en sık kullanılandır.

Java ile Örnek Uygulama

Canny kenar detektörü ile kenar çıkarma işlemi yapacak olursak;

Imgproc.Canny(input_mat, detected_edges_mat, lowThreshold, maxThreshold, kernel_size );

input mat kenar tespiti yapacağımız matrisimiz, detected_edges_mat işlem sonucu kenarları tespit edilmiş mat nesnemiz, eşikleme yani thresholding yapacağımız için istediğimiz minimum değeri , maxThreshold ise eşikleme için kullanılmasını istediğimiz maksimum eşik değeri, kernel_size  parametresi ise çekirdek matrisi tanımlamaktadır bu rada önerilen matris değerlerini kullanabilir özel matris oluşturabilir istersek de boş bırakarak varsayılan çekirdek matrisin kullanılmasını sağlayabiliriz.

 public static void main(String args[]) {
        String NATIVALIBRARYx64 = "res//lib//x64//opencv_java310";
        System.loadLibrary(NATIVALIBRARYx64);
        Mat imageInMat = Imgcodecs.imread("C:\\Users\\mesutpiskin\\Desktop\\mevlana.jpg");
        Mat canny = new Mat();
        Imgproc.Canny(imageInMat, canny, 50, 150);
        Imgcodecs.imwrite("C:\\Users\\mesutpiskin\\Desktop\\canny.jpg", canny);
    }

Diğer algoritmaları kullanmak istersek yine Imgproc altından ulaşılabilir olacaktır.

Çıktı,