İki Göz Arası Mesafeyi (Pupila mesafesi) ölçen HALCON çalışması

Yalnızca görüntü işleme çalışmalarına örnek olması açısından, 2 göz arası mesafeyi ölçen (puppila mesafesi) basit bir HALCON kodu aşağıda verilmiştir.

Mesafe pixel cinsinden ölçülmektedir. Görüntü alan cihaz (kamera, fotoğraf makinesi vb.) sabit ise, makinanın karşısındaki insanın bulunduğu yer de sabit ise, bu durumda basit bir dönüşüm ile, pixel den milimetreye geçiş yapılabilir. (Uygulama açısından gözlerin gelmesi gereken yere, hassas bir cetvel ya da mesafesi bilinen bir işaret koyarak kaç pixele denk düştüğü bulunabilir)

Şimdi HALCON koduna geçelim :

dev_set_draw('margin')
*Ekran fontunu set edelim
set_display_font (3600, 12, 'mono', 'true', 'false')
*Resmi dosyadan yükleyelim (Normalde kameradan direk alınır)
read_image (Image, 'C:/Users/Mustafa/Desktop/m1.jpg')
* Resmin ilgilendiğimiz bölgesini (gözlerin bulunduğu yer) belirtelim
gen_rectangle1 (ROI_0, 154.969, 72, 206.531, 255.75)
reduce_domain (Image, ROI_0, ImageReduced)
*koyu renkleri seçelim (göz bebekleri, kirpikler, saçlar vb.
threshold (ImageReduced, Regions, 0, 57)
closing_circle(Regions, RegionClosing, 3.5)
*içinde daire içeren şekilleri seçelim
opening_circle(RegionClosing, RegionOpening, 6)
connection(RegionOpening, ConnectedRegions)
*Belirli bir alandan büyük nesneleri seçelim
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 150, 500)
count_obj(SelectedRegions, Number)
if (Number = 2)
    *2 adet göz seçilmiş ise
    select_obj(SelectedRegions, Goz1, 1)
    select_obj(SelectedRegions, Goz2, 2)
    * her bir gözün tam merkezinin koordinatlarını bulalım
    area_center(Goz1, Area, Row1, Column1)
    area_center(Goz2, Area, Row2, Column2)
    *Artık sonuçları ekranda gösterelim
    dev_display(Image)
    dev_set_color('blue')
    dev_display(SelectedRegions)
    dev_set_color('green')
    disp_cross(3600, Row1, Column1, 12, 0)
    disp_cross(3600, Row2, Column2, 12, 0)
    dev_set_color('red')
    disp_arrow(3600, Row1 + 30, Column1, Row1 + 30, Column2, 1)
    disp_arrow(3600, Row1 + 30, Column2, Row1 + 30, Column1, 1)
    Dist := Column1-Column2
    disp_message (3600, Dist + ' px.', 'image', Row2+40, Column2 + 20, 'black', 'false')
endif

bu projede kullandığım insan yüzü resimlerini, http://www.uni-regensburg.de/Fakultaeten/phil_Fak_II/Psychologie/Psy_II/beautycheck/english/prototypen/prototypen.htm adresinden aldım.

orijinal resimlere oradan ulaşılabilir.

bu kodu çalıştırabilmek için, HALCON yüklü olmalıdır. En gelişmiş görüntü işleme kütüphanesi olan HALCON hakkında bilgi almak ve  ücretsiz tam versiyonu (sınırlı süreli) edinmek için bizimle irtibata geçebilirsiniz.

Tek bir Kod ile hem Siyah, hem de beyaz vidaların bulunması

HALCON komutlarından gray_range_rect ile, aynı kod kümesi işletilerek hem siyah, hem de beyaz yüzey üzerinde yer alan vidaların bulunması sağlanabilir.

Aşağıda yalın hali ile verilmiş HALCON kodu, yine aşağıda verilmiş her iki resim için de çalışmaktadır. (Resimler gerçek projeden alınmıştır. Projede Çamaşır makinası arka yüzeyindeki vidaların kontrol edilmesi istenmektedir. Makinalar Siyah, Beyaz, Gri vb. metalik ve mat renklerde olabilmektedir)

Projede kullanılan resimler (aşağıdaki resim galerisinden siyah ve beyaz makina resimlerini indirebilirsiniz)

HALCON kodu :

Burada işin büyük kısmı, gray_range_rect komutu tarafından halledilmektedir. Kodun tamamı :

dev_set_draw('margin')
*Beyaz resmi yükleyelim
read_image (Image, '024548.jpg')
gen_circle (ROI_0, 183.649, 233.052, 52.4687)
reduce_domain (Image, ROI_0, ImageReduced)
gray_range_rect (ImageReduced, ImageResult, 11, 11)
bin_threshold(ImageResult, RegionKara)
difference(ImageResult, RegionKara, RegionAk)
shape_trans(RegionAk, RegionTrans, 'convex')
dev_display(Image)
dev_display(RegionTrans)

Programın HDevelop ortamındaki görüntüsü

Kod, vidayı belirleyip, etrafını yeşil daire ile çerçevelemiştir.

Aynı kod, siyah resim için uygulandığında, yine doğru çalıştığı görülecektir.

Sonuç olarak, farklı renk skalaları için, farklı farklı threshold değerleri ve farklı kod öbekleri ile çalışmak yerine hepsi için çalışabilen bu kod, basitliğiyle avantaj sunmaktadır.

USB pratikliğinde çalışan GigE Ethernet Kamera

Türkiye distribütörü olduğumuz iDS firması, GigE uEye CP isimli yeni kamerasının tanıtımını yaptı. ueye CP; dünyadaki en küçük Ethernet kamera ve, ethernet kablosunun dışında ayrıca bir besleme kaynağına ihtiyaç duymuyor olması gibi son derece göz alıcı özelliklere sahiptir.

Tipik USB kameralarda olduğu gibi, sadece ethernet kablosunun takılması, hem data (görüntü) hem de kameranın çalışması için enerji (power) ihtiyacının karşılanması anlamına geliyor. Etkileyici derecede küçük tasarımı ile birlikte düşünüldüğünde, Yapay Görme sektöründe bol miktarda kullanacağımız bir model olması muhtemel.

Kamera hakkında detaylı bilgi ve video tanıtımları için iDS web sitesini ziyaret edebilirsiniz.

HALCON Temelleri

HALCON üzerine referans site çok fazla olmamasından dolayı (benim bildiğim hiç yok) bu blog sitesinde HALCON temel fonksiyonları ve gittikçe ilerleyen seviyelerde örnekler vermeyi uygun gördüm.

Aşağıdaki örnek proje, resimdeki belirlenen bir nesneye, en yakın diğer nesneyi bulma örneği. Bu örnek dikkatle incelenirse, kendi içinde dikkat edilmesi gereken bir “TRICK” içeriyor. Bunu da hemen takip eden makalede açıklamayı düşünüyorum.

Yukarıdaki resimde (sağ tuşa tıklayarak orijinal halini görebilir / kaydedebilirsiniz) somunu seçip, somuna en yakın civatayı bulup, aralarındaki mesafeyi pixel cinsinden yazan bir HALCON kodu geliştirelim.

Sonuçta ekran görüntüsü soldakine benzer bir şey olacak. Sistem önce somunu belirleyecek, daha sonra somuna en yakın civatayı, ve aralarındaki mesafeyi bulacak.

Bunun için öncelikle somunun belirlenmesi, daha sonra distance_rr_min komutu ile iki region arasındaki minimum mesafenin bulunması işlemi söz konusu olacaktır.

HALCON koduna dönersek

set_display_font (3600, 12, 'mono', 'true', 'false')
read_image (Image, 'C:/Users/mvs/Desktop/SC.bmp')
bin_threshold (Image, Region)
connection (Region, ConnectedRegions)
*Çok küçük parçalar, noktasal kirlilikler varsa eleyelim
select_shape(ConnectedRegions, SelectedRegions, 'area', 'and', 150, 99999)
count_obj(SelectedRegions, Number)
if (Number > 0)
    *nesnelerin içinde var olan boşlukları dolduralım
    fill_up_shape(SelectedRegions, RegionFillUp, 'area', 1, 100)
    *içinde 1 adet delik olan nesneyi bul
    select_shape (RegionFillUp, Somun, 'holes_num', 'and', 1, 1)
    count_obj(Somun, Number)
    if (Number = 1)
        difference(RegionFillUp, Somun, RegionDifference)
        union1(RegionDifference, RegionUnion)
        distance_rr_min(Somun, RegionUnion, MinDistance, Row1, Column1, Row2, Column2)
        dev_set_color('blue')
        disp_arrow(3600, Row1, Column1, Row2, Column2, 2)
        disp_message (3600, MinDistance, 'image', Row2 - 20, Column2 + 20, 'green', 'false')
    endif
endif

şeklinde bir kod işimizi fazlasıyla görür.

Burada fill_up_shape komutunun etkisi aşağğıdaki resimde görülebilir:

fill_up_shape yerine fill_up kullanılsaydı, somun simit şeklinde olmayıp içi dolu daire şekline gelecekti.

Örnekte, somunu seçmek için, içindeki boşlık sayısı 1 olan nesneleri arattım. Duruma göre bir çok farklı alternatif denenebilirdi. dairesellik, (circularity), alan (area) vb. gibi.

Bu örnekte hala eksik olan ve dikkatli olunmaması durumunda ciddi hatalara neden olabilecek bir kod var. Bir sonraki makalede buna değineceğim.