Ürünlerin Tip ve Sayı Eşleştirmesi

TAYSAD’daki FARPLAS fabrikasına parça tanıma sistemimiz devrede. Tek kameralı, bilgisayarlı, sensörlü, dijital i/o modüllü, kabinli bir sistem kuruldu.

Toyota araçlarının bir çok plastik parçalarının boyaması gerçekleşiyor. Bu ürünlerin tip ve sayısını buluyoruz ve Doruk Otomasyon ile haberleşip etiket çıktısı alınıyor. Haberleşme Web Servisi ile çift taraflı yapılıp, ürün bilgisi ve sayısı bilgileri aktarılıyor.

Yaklaşık 30 farklı parçanın tip-sayı eşleştirmesi yapılıyor. Ön-Arka Sağ-Sol kapı iç kısmı, Ön-Arka Sağ-Sol kapı çıtaları, Yakıt deposu kapakları, Orta konsol kısımları, Bagaj çıtaları vb.

ürün tanıma 2

20160806_110814_HDR--

HALCON 13 ve yeni özellikler

HALCON 13, Kasım 2016’da kullanıma sunuldu. Yeni özellikleri, filtreleri, geliştirmeleri ve paralel işlemler ile hız konusunda yapılan iyileştirmeleri anlatalım.

Geliştiriciler için;

Halcon arayüzünde geliştirme yaparken, artık bütün kontrol ve ikonik değişkenlerine breakpoint konulabiliyor. Bunları Quick Navigation’dan izleyebilirsiniz.

Dokümantasyon’da notlar daha detaylı, düzenli, kısımlara ayrılmış, listeli halde.

Halcon kodu export edilip Visual Studio’da projenize eklendiyse, kullandığınız Halcon değişkenlerini watch edip izleyebiliyorsunuz.

Birkaç ayar ile uzaktaki sisteminizin Halcon üzerinden debug’ını yapabilirsiniz. Halcon’u hDevEngine ile çalıştırıp, projenizden Halcon dosyasını çalıştırarak kullanıyorsanız; uzaktan pc erişimi ile canlı proje üzerinde (sistem uzakta bir fabrikada da olabilir) Halcon arayüzü üzerinden breakpoint koyup debug yapılabiliyor. Sistem çalışırken Halcon dosyasındaki breakpoint koyduğunuz yere düşüyor, böylece siz değişkenleri görüp adım adım devam edebiliyorsunuz.

Görüntü işleme;

Yeni birçok görüntü işleme filtreleri eklendi.

bilateral_filter eklendi. Görüntüdeki geçiş noktalarını değil, yüzey kısımlarında yumuşatma yapmak için kullanılabilir, kenarı yakalamak isteyip yüzeydeki parazitleri gidermek istiyorsanız. Guided_filter da bunun gibi çalışıyor ve az daha hızlı. Bununla birlikte bilateral_filter kullanırken, hızını ve kalitesini parametrelerle ayarlayabilirsiniz.

Yeni bir threshold yöntemi; MSER (Maximally Stable Extremal Regions), yani en stabil olan threshold sonucu.
segment_image_mser komutu ile görüntü üzerinde keskin yada yumuşak geçişlerde de olsa, koyu açık ya da ikisi için de region’ları alabiliyorsunuz.

Texture inspection yöntemleri geliştirildi.

Datacode, QRcode fonksiyonları geliştirildi. Bulanık, yamuk açılı, kontrastı kötü, yazı kalitesi düşük, mürekkebi az-fazla gelse de kodları bulma oranları arttırıldı.

Barcode’lar parazitli olsa da bulabiliyor. Barkodun bir kısmı silinik gelse de, bar çubukları üzerinde okunabilen bir nokta var ise okur, bu şekilde bütün çubukların okunabilen yerlerini alır ve barkodun tamamını tanıyabilir.

OCR (karakter tanıma, yazı okuma) okuma oranları daha arttırıldı.

Dot print (nokta vuruşlu) yazılarda (sanayide döküm malzemeler üzerindeki gibi) okuma oranları geliştirildi.

Find_ncc_models komutu artık çoklu model tanımayı da destekliyor. Ayrıca görüntü üzerinde tanımada iyileştirmeler var.

3 Boyutlu Görme;

Kullanılan bazı komutlarda parametre eklemeleri var. Point Cloud (Nokta Bulutu) çıkarmaları, Kalibrasyonu, Yüzey modelleme komutları, Matching komutları geliştirildi.

HALCON arayüzündeki grafik ekranda da bazı yenilikler var.

set_window_param ile “region_quality” low-good değerleri verilerek, region kenarları daha hassas gösterilebilirsiniz.
set_window_param ile “anti_aliasing” true-false değerleri verilerek, kenarlar daha yumuşak yada keskin gösterilebilir.
dev_set_color’da artık renkler hex kodu olarak da verilebilirsiniz.
Ekranda yazı yazma göstereceğimiz zaman, top-bottom, left-right-center ile hizalanabilir.
Ekranda bir mesaj yazıldığında zoom in – zoom out yapıldığında bile mesajın da ona göre tekrar hizalanması sağlanıyor.

Komutlarda Hızlanma;

Artık neredeyse bütün komutlar fonksiyonlar kendi içinde paralel process ile işleniyor. Yani hepsinde bir hızlanma mevcut, bazıları ise çok daha hızlanmış durumda. Örneğin aşağıdaki komutlarda yüzde kaç hızlanma olmuş görelim;

threshold, %180
dyn_threshold, %400
mean_image, %300
trans_from_rgb, %325
find_shape_model, %300
scale_image, %300
find_text, %300
edges_color, %80

Shape based matching, Deformable shape based matching işlemleri,
OCR (karakter tanıma, yazı okuma) işlemlerinde de hızlandırmalar yapıldı.

 

HALCON 13 artık daha hızlı, daha verimli. Seneler içinde HALCON, biz görüntü işleme geliştiricileri için işimizi epeyce kolaylaştırdı..

 

HALCON 13 çıktı

Evet, görüntü işleme kütüphanesi olarak kullandığımız HALCON’un yeni versiyonu 1 kasım 2016’da çıkıyor.

Lansmanı için Almanya-Münih’e MVTEC’in merkezine gittik ve HALCON 13’ün yeni özelliklerini gördük, bununla ilgili detayları bir sonraki yazımda yazacağım.

halcon13days

 

 

 

 

 

 

Şimdilik aşağıdaki sayfadan inceleyebilirsiniz.

HALCON 13 Release

 

C, C++, C#, VB, Delphi ile Profesyonel Görüntü İşlemeye Giriş – IV

Önceki ilk 3 makalede, HALCON görüntü işleme kütüphanesinin kurulması ve örneklerin çalıştırılmasını anlatmıştık. Şimdi sıfırdan görüntü işleme temellerine giriş yaparak, basit bir uygulama geliştirmeye başlayabiliriz. Uygulamayı Visual Studio içinde derlemeden önce, HALCON kendi geliştirme ortamı olan HDevelop üzerinde geliştireceğiz. Uygulamayı HDevelop ile geliştirip, test ettikten sonra, herşey tam istediğimiz gibi çalışıyor ise, HDevelop bizim için kod üretecektir. (.NET C# vs…) son aşama olarak, bu üretilmiş kodu biraz süsleyerek, formlar, butonlar, menüler vb. kendi tasarımımız, çalışan bir uygulamaya sahip olacağız.

Burada tekrar değinmekte fayda var, HDevelop, HALCON görüntü işleme kütüphanesinin geliştirme ortamıdır. Kod yazabildiğimiz editör, görüntü işlemede yardımcı olacak tüm araçlar ve sihirbazlar barındırır. Görüntü işlemeye ilişkin neredeyse tüm işimizi HDevelop içinden yaparız.

Şimdi temel görüntü işleme bilgilerine, kaldığımız yerden devam edelim.

Görüntü işleme uygulamalarında, sanılanın aksine renkli kameralardan çok daha fazla oranda monochrome kameralar kullanılır. (Eğer renk ile ilintili bir analiz yapılmayacak ise) (Bu linkte, monokrom kameraların tercih edilme sebepleri kısaca anlatılıyor.)

8 bit, monochrome bir kamera ile alınan görüntüde,

0 : Tamamen Siyah
255 : Tamamen Beyaz

olarak kodlanacaktır. 1 Mega pixel tamamen siyah bir görüntü, pratik olarak 1 MByte 0 demektir. (jpg, bmp gibi dosyalarda, dosyanın / paketlerin başında özel header / başlık bilgileri vb. olabilir)

Özet olarak bilinmesi gereken, 0=siyah, 255=beyaz, ara değerler = gri tonlamalar şeklinde özetlenebilir.

(Eğer webcam, cep telefonu kamerası vb. kameralar ile çalışıyorsanız, haliyle renkli fotoğraflar alacaksınız demektir. Bu durumda, şimdilik bilmeniz gereken, renkli fotoğraf Kırmızı, Yeşil ve Mavi (R G B) olmak üzere 3 kanaldan oluşmaktadır. Ve her bir kanalda yine 0:tam siyah, 255:tam beyaz olarak kullanılabilir. Biz HALCON a alışmak ve temel görüntü işleme fonksiyonları hakkında biraz bilgi sahibi olabilmek için, HALCON ile yüklü gelen örnek resimler ile devam edeceğiz.)

Şimdi bu kadar basit bir bilgi ile, en önemli görüntü işleme fonksiyonu olan Threshold üzerine konuşalım. Threshold, bir görüntüde, pixelleri renklerine bakarak seçme işlemidir. (Tekrar edelim : 0= siyah, 255=beyaz)

Şimdi HDevelop isimli HALCON geliştirme ortamını açıp, ilk uygulamamızı yazmaya başlayalım. Önce HDevelop’u çalıştıralım. Hadi Bismillah.

 

 

 

 

 

 

 

 

 

 

 

 

HDevelop ortamı aşağıdaki şekilde yüklenecektir. Dilerseniz yardım dosyalarından ya da MVTec web sayfasından HDevelop ile ilgili daha fazla bilgi alabilirsiniz. Ya da, yolumuza devam edelim, ileride aklınıza geldikçe yardım dosyalarına göz atabilirsiniz.

HDevelop, 4 pencereden oluşan MDI bir uygulamadır. Genellikle sağ alt köşede, editör yer alır. Burası, kod yazdığımız alandır. HDevelop kod yazma dili, kendisine özgü bir script dilidir. Syntax olarak, pascal a benzer. Biraz programlama becerisi olanlar, kolayca uyum sağlar.

Artık ilk kodumuzu yazmaya hazırız. (Not : HDevelop başlarken lisans ile ilgili bir hata vermiş ise, demek ki geçerli bir HALCON lisansınız yok. Bu durumda bizden deneme lisansı istemeniz gerekmektedir.)

Ve işte ilk komutumuz : read_image. Adı üstünde, bir dosyadan resim okur/yükler. HALCON ve HALCON örnek resimleri düzgün yüklendi ise, HDevelop editöründe yazacağınız

read_image(Image, ‘rings_and_nuts’)

kodunu, F5 ile çalıştırdığınızda, ekran görüntüsü aşağıdaki gibi olmalıdır.

Resimden de görüldüğü gibi, HDevelop 4 kısımdan (pencere) oluşmaktadır. Kod yazdığımız editör, Operatör penceresi, Grafik penceresi ve değişkenlerin değerlerini gözlemlediğimiz Değişken penceresi.

yazdığımız kod satırının üzerine 2 kez tıkladığımızda, o satırdaki görüntü işleme fonksiyonu operatör penceresinde açılır (parametrelerini inceleyip değiştirebilmemiz için)

Bu operatör penceresi, yeni başlayanların çok sık kullanacağı, profesyonelleştikçe, daha az ihtiyaç duymakla birlikte, sürekli elinizin altında olması gerekli bir yardımcıdır. Parametreleri seçebilmeniz için değerler önerir, parametreler bir listeden seçilebilir ve çok daha hızlı kod yazmanıza olanak sağlar.

Burada, read image dediğimizde, hemen bir liste sundu ve ben listeden istediğimi seçerek, yazma zahmetinden kurtuldum. Operatör penceresine biraz daha yakından bakarsak, oradaki şekillerin bize bazı bilgiler verdiğini görürüz.

Programcılıkla ilgilenenlerin kolaylıkla anlayacağı şekilde;

read_image(Image, ‘fabric’)

ifadesi, fabric isimli bir resmin okunup, sonucun Image isimli bir değişkene koyulacağı anlamına gelir. Eğer bunu C# ile kodlayacak olsaydık,

void read_image(out Image, “fabric.jpg”);

gibi bir eşdeğeri olacaktı. HDevelop, read_image fonksiyonunda dosya uzantısını yazmazsak, geçerli tüm resim formatlarını (bmp, jpg, png.. arar)

sonuçta, ekranın sol üst penceresinde, (Graphics Window) resim yüklenecektir.

Artık ilk görüntü işleme uygulamamıza geçelim. Uygulamamız şöyle olsun : rings_and_nuts isimli resim dosyasında, kaç adet nesne (somun, dişli) var?

Bunun cevabı, ekranda siyah ya da siyaha yakın (gri tonlarda) kaç adet nesne var?
programımız basitçe şu şekildedir.

read_image(Image, ‘rings_and_nuts’)
threshold(Image, Region, 0, 128)

F5 e basarak çalıştırdığımızda, aşağıdaki gibi bir ekran görüntüsü oluşacaktır. (F2 ile başa dönebilirsiniz, F6 ile adım adım çalıştırabilirsiniz)

Görüldüü gibi, ekranda verdiğimiz aralığa uyan pixeller, kırmızı ile boyandı. gözle saydığımda 7 nesne (somun, dişli) görüyorum. Bunu HALCON a saydıralım.

Connection komutu :

Connection threshold sonucu seçilmiş pixellerden oluşan kümeyi (region) birbirine değmeyen bağımsız nesneler dizisine ayırır.

programıma 1 satır daha eklersem;

read_image(Image, ‘rings_and_nuts’)threshold
(Image, Region, 0, 128)
connection(Region, ConnectedRegions)

şeklini alır, ve çalıştırdığımda da ekran görüntüsü aşağıdaki gibi olur.

HDevelop, belli olsun diye, her nesneyi ayrı bir renge boyadı (ilk başta hepsi kırmızı idi ve tek bir nesne idi)

şimdi nesne sayısını veren komut count_obj ile sonucu öğrenebiliriz.

Programımı;
read_image(Image, ‘rings_and_nuts’)
threshold(Image, Region, 0, 128)
connection(Region, ConnectedRegions)
count_obj(ConnectedRegions, Number)
set_tposition(3600, 220, 180)
write_string(3600, Number)

şekline uyarlayıp çalıştırırsam, ekranda row:220, column:180 pozisyonuna gidip, nesne adedini yazacaktır. Buradaki 3600, grafik penceresinin ID sidir. Tek bir grafik penceresi var ise 3600, 2 si 3601 … ID numarasını alır. İleride daha detaylı değinilecektir. Şimdilik bilmemiz gereken, ekrana (3600 nolu pencereye) “Merhaba Dünya!” yazmak istiyorsak write_string(3600, ‘Merhaba Dünya!’) şeklinde bir kod yazmamız gerektiğidir.

Ekrana 8 yazdırdıysanız, buraya kadar başarıyla geldiniz demektir. Bir yerlerde takıldıysanız, mail ya da yorum ile yardım isteyebilirsiniz.

Bir sonraki derste, select_shape fonksiyonunu göreceğiz ve buradan C# uygulamasına geçeceğiz.

Sonraki Bölüme geçmek için tıklayınız…

Plastik parçalar üzerindeki yüzüklerin kontrolü

Otomotiv sektöründe hizmet veren bir firma için yüzük kontrol sistemini devreye aldık. Sistemde 3 farklı ürün bulunmaktadır. Her bir üründe yüzüğün takılacağı yerler ve renkler farklılık göstermektedir. Bu ürünler modellenerek kontrol edilmesi istenen ürünlerin doğru veya hatalı olarak ayrıştırılması sağlanmıştır.

Operatör tarafından kullanıcı girişi yapılabilen, kontrol edilecek modelin listeden seçilebileceği ve sistemin çalıştırılması veya durdurulması gibi işlemleri içeren bir arayüz tasarlanmıştır.

Sistem, konveyör sistemi üzerinde bölmelere ayrılmış bir bandın ilerlerken mekanik sensör yardımıyla adım adım durdurulması, fotoğraf çekilmesi, bu fotoğrafın bilgisayar üzerindeki yazılım ile işlenerek ürünlerin doğru veya hatalı olarak tespit edilmesi, bu bilgilerin ekranda gösterilmesi ve farklı kovalara atılması işlemlerinden oluşmaktadır.

Kontrol edilecek ürünler farklı pozisyonlarda geleceği için bu ürünlerin ve yüzüklerin aranacağı bölgelerin modellenen ürünlere göre döndürülmesi gerekmektedir. Bu işlemi sağlayan HALCON kodu:

// Kontrol edilecek ürünün fotoğrafının okunması
read_image (Image, 'C:/Projects/M1_175740.bmp')
// Matching(Eşleştirme) için kullanılacak modelin okunması
read_shape_model ('C:/Projects/P1-N.shm', ModelId)
//  Matching(Eşleştirme) işlemi
find_shape_model (Image, ModelId, rad(0), rad(360), 0.5, 1, 0.5,['least_squares','max_deformation 2'], [7,1],0.75,ModelRow, ModelColumn, ModelAngle,ModelScore)
    if (ModelScore > 0.75)
        get_shape_model_contours (ModelContours, ModelId, 1)
        hom_mat2d_identity (HomMat)
        hom_mat2d_rotate (HomMat, ModelAngle, 0, 0, HomMat)
        hom_mat2d_translate (HomMat, ModelRow, ModelColumn, HomMat)
        affine_trans_contour_xld (ModelContours, TransContours, HomMat)
        gen_rectangle1 (ModelRegion, 396.643, 361.944, 816.643, 1134.52)
        area_center (ModelRegion, ModelRegionArea, RectificationRow, RectificationCol)
        hom_mat2d_identity (Rectification)
        hom_mat2d_translate (Rectification, RectificationRow-ModelRow, RectificationCol-ModelColumn, Rectification)
        // Ürünün döndürülmesi
        hom_mat2d_rotate (Rectification, -ModelAngle, RectificationRow, RectificationCol,Rectification)
        affine_trans_image (Image, RectifiedImage, Rectification, 'constant', 'false')
    endif

Doğru ve hatalı olarak tespit edilen ürünlerin ekran görüntüleri :

partition_dynamic kullanımı

Bir region üzerinde işlem yaparken sık sık connection komutu ile region da kaç adet nesne olduğu ile ilgileniriz. connection komutu, birbirinden bağımsız nesneleri seçeceği için, nesneler arasında 1 pixel lik dahi bağlantı olsa, onu tek bir nesne olarak algılayacaktır. Özellikle OCR işlemi gibi, her nesnenin ayrı olarak değerlendirilmesi gereken durumlarda, bu problemi gidermek gerekir. Yollardan biri partition_dynamic komutunun kullanılmasıdır.

 

Yukarıdaki resimde görüldüğü gibi, 1 ve 2 ile 6 ve 7 arasını birer çizgi ile birleştirdim. Burada threshold komutu ile bir region oluşturduğumda ve hemen sonra connection ile her bir rakamı seçmek istediğimde,

yukarıdaki gibi bir seçim yapacaktır. (1-2 ve 6-7 nin tek bir nesne olarak seçildiğine dikkat edin)

partition_dynamic komutu tam da bu gibi durumlarda istenen sonuçları üretebilir. partition_dynamic, nesneleri dikey olarak bölmeye yarayan bir komuttur. Ortalama bir nesnenin genişliğini belirtip, belirli bir yüzde toleransı da verdiğimizde, komut nesleneri olması gerektiği yerden parçalayacaktır. (Aşağıdaki resimdeki gibi)

 

partition_dynamic komutuna verilecek, ideal nesne genişliği ne olmalıdır?

nesne genişliğini komutla ya da HDevelop içindeki Feature Inspection aracı ile görebiliriz.

Yukarıdaki resimde görüldüğü gibi, seçtiğim nesnenin özelliklerini (features) gözlemledim. İlgilendiğim width değerinin 85 olduğunu gördüm. Programda direk olarak bu değeri kullanabilirim.

Dilersem daha dinamik bir yapı kurarak, olması gereken değeri kendim belirlerim. Aşağıdaki kod, hem sabit olarak bu 85 değerini kullanan, hem de dinamik olarak kendi belirlediği değere göre (tuple_median) çalışan HDevelop kodudur.

 

read_image (Image, 'C:/Users/Mustafa/Desktop/Adsız.png')
threshold (Image, Regions, 0, 139)
connection(Regions, ConnectedRegions)
* Sabit 85 değerine göre partition
partition_dynamic(ConnectedRegions, Partitioned, 85, 20)

*kendi belirleyeceği değere göre partition
smallest_rectangle1(ConnectedRegions, Row1, Column1, Row2, Column2)
W := Column2 - Column1
tuple_median (W, WOrta)
partition_dynamic(ConnectedRegions, Partitioned, WOrta, 20)

Dikiş Varlık Kontrolü

Dynamic Threshold ve Shock Filter Kullanımı

Yakın zamanda yaptığımız bir projede, yapılacak kontrollerden biri kumaşın desenini algılamaktı. Texture olarak bilinen bu çalışma, görüntü işlemenin en zor yanlarından biridir. Her ne kadar HALCON texture algılama üzerine bol miktarda fonksiyon barındırsa da, texture gibi genel bir konuda, her hangi bir fonksiyondan sihirli bir işlev beklenemez. Yapılması gereken, projeye özgü kodlamada bulunmak…

Projede, kumaşın deseni kadar, kenarında dikiş olup olmadığının da kontrol edilmesi gerekiyordu.

Resimdeki orijinal resimde göründüğü gibi, araba koltuk başlığının yan tarafında dikiş olup olmadığının belirlenmesi gerekiyordu. İlk başta kolay gibi görünen bazı uygulamalar, iplik renginin değişmesi, kumaş renginin / deseninin değişmesi vb. faktörlerden dolayı hiç hata vermeden çalışacak bir yapıda olmalıydı. aşağıdaki kod, dikiş izini hatasız olarak tesbit edebilen bir HALCON kodudur. (Denemek için bu resmi alarak kaydedebilirsiniz.)

 

sonuç görüntü :

HALCON kodu

 

read_image (Image, 'K.bmp')
bin_threshold (Image, Region) 
reduce_domain (Image, Region, ImageReduced)
shock_filter(ImageReduced, SharpenedImage, 0.5, 10, 'canny', 1)
gray_opening_shape(SharpenedImage, ImageOpening, 25, 25, 'octagon')
gray_closing_shape(SharpenedImage, ImageClosing, 25, 25, 'octagon')
dyn_threshold (ImageOpening, ImageClosing, RegionDynThresh, 50, 'not_equal')
dilation_circle(RegionDynThresh, RegionDilation, 5)
connection(RegionDilation, ConnectedRegions)
select_shape(ConnectedRegions, SelectedRegions, 'area', 'and', 1000, 99999)
count_obj(SelectedRegions, Number)
if (Number > 0)
    skeleton(SelectedRegions, Skeleton)
    dev_set_line_width(2)    
    *set_line_style (3600, [20,10])
    dev_display(Image)
    dev_display(Skeleton)
endif

Burada asıl işi yapan dynamic_threshold kullanımıdır. shock_filter alınan görüntüde, kenarları belirginleştirmeye yarar. (Datamatrix, karekod, barkod okuma vb. işlemlerde önerilir) Kodda comment edilmiş set_line_style (3600, [20,10]) kodunu da açıp çalıştırırsanız, bulanan dikiş çizgisinin, kesikli olarak gösterildiğini göreceksiniz. set_line_style, HALCON çizgi gösterim biçimini formatlama fonksiyonudur.

OCR Öncesi Resmi Döndürme

HALCON ile OCR işlemine başlamadan önce, resmin üzerindeki yazının yatay eksene paralel olacak şekilde döndürülmesi gerekmektedir.

resmi döndürdükten sonra ise,

haline gelecektir. Burada, sadece resmi değil, resimle birlikte Region da döndürmek gerekeceğinden, rotate_image komutu yerine transformation komutları (HomMat2DRotate) kullanmak gerekecektir.

Region ile birlikte döndürme yapan HALCON kodu :

 

read_image (Image, 'C:/Users/Mustafa/Desktop/RenPics/142856.bmp')
*Region bulalım
var_threshold(Image, Region, 460, 240, 0.2, 2, 'light')
closing_circle(Region, RegionClosing, 15)
opening_circle(RegionClosing, RegionOpening, 45)
fill_up(RegionOpening, RegionFillUp)
connection(RegionFillUp, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, ['area','inner_radius'], 'and', [700000, 200], [2000000, 280])
*
shape_trans(SelectedRegions, RegionTrans, 'convex')

*Resim ve Region birlikte Rotate Edelim
area_center(RegionTrans, Area, Row, Column)
text_line_orientation (RegionTrans, Image, 180, -0.523599, 0.523599, OrientationAngle)
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_rotate (HomMat2DIdentity, -OrientationAngle, Row, Column, HomMat2DRotate)
affine_trans_image (Image, ImageRotate, HomMat2DRotate, 'constant', 'false')
affine_trans_region(RegionTrans, RegionAffineTrans, HomMat2DRotate, 'false')

Programın çalışmasını test etmek için kullanılabilecek 2 adet resmi buradan indirebilirsiniz

Nesne Adedi Bulan HALCON Kodu, erosion ve dilation kullanımı

 

Soldaki resimde (HALCON da pellets adı ile kaydedilmiştir) kaç adet pellet (topak) var. Bunu farklı yaklaşımlarla bulan HALCON kodu üzerinde kafa yoralım.  Ben ve Kağan tarafından geliştirilen farklı algoritmalar, burada alt alta verilecektir.

Buradaki tek zorluk, nesneler birbirine bitişik olduğu için, connection kullandığımızda bitişik olan nesneleri tek bir nesne olarak değerlendirecektir. opening_circle kullanıldığında ise yine istenen sonucu elde edebilmek her zaman mümkün olmamaktadır. Basit gibi görünen bu örnekte biraz daha farklı yaklaşımlar gerekebilir.

 

 

Kağan tarafından geliştirilen HALCON kodu

read_image (Image, 'pellets')
scale_image_range (Image, ImageScaled, 100, 200)
gray_erosion_shape (ImageScaled, ImageMin, 3, 3, 'octagon')
bin_threshold (ImageMin, Region)
difference (ImageMin, Region, RegionDifference)
opening_circle (RegionDifference, RegionOpening, 10)
connection (RegionOpening, ConnectedRegions)
count_obj (ConnectedRegions, Number)

 

 

 

 

 

 

 

 

 

Kağan tarafından yukarıda yazılan kod çalıştırıldığında yukarıdaki sonuç elde edilmiştir. Aradığımız da tam olarak buydu. Kodu tam 1000 defa çalıştırdığımda 3.175 sn. sürdü. Şimdi farklı mantıklar ile yeniden kodu geliştirmeyi düşünelim.
Benim geliştirdiğim HALCON kodu

read_image (Image, 'pellets')
bin_threshold(Image, RegionDark)
difference(Image, RegionDark, RegionLight)
connection(RegionLight, ConnectedRegions)
erosion_circle(RegionLight, RegionErosion, 8 )
connection(RegionErosion, ConnectedRegions)
dilation_circle(ConnectedRegions, RegionDilation, 8 )
count_obj(RegionDilation, Number)

Benim yazdığım kodu 1000 defa çalıştırdığımda 1.439 sn. sürdü 🙂  Buradaki püf noktası, önce erosion_circle kullanarak birbirine yapışık nesneleri sınırlarından erimeye tabi tutarak (erosion) ayırmak, sonra dilation_circle kullanarak eski boyutlarına geri ulaştırmak. (Hız her zaman ilk göz önüne alınması gereken parametre değildir.)

HALCON da bir çok farklı yaklaşım ile istenen sonuca ulaşmak mümkündür. Bir diğer yaklaşım,

distance_transform

HALCON fonksiyonunu kullanmak olabilir. Belritilen sınır mesafeye göre en uzak olanları en parlak, en yakın olanları en koyu olarak çizecek şekilde transform edilmiş yeni resim işleri çok kolaylaştırabilir.

distance_transform (ConnectedRegions, DistanceImage, ‘euclidean’, ‘true’, Width, Height)

fonksiyonu uygulandıktan sonraki orijinal resmimiz aşağıdaki gibi olacaktır. Bundan sonrasını, HALCON programcıları için yazmaya gerek bile görmüyorum.

 

 

Defne Yaprağı Ayrıştırmada Matematiksel Yaklaşım

Daha önceki blog kayıtlarımızda sıklıkla bahsettiğimiz Hatalı Defne Yaprağı Ayrıştırma Projemize tamamen matematiksel yöntemlerle çalışan, daha hızlı ve daha güvenilir sonuçlar veren yeni bir yaklaşım ekledik.

Matematikte Saddle Point (Semer Noktası) olarak bilinen fonksiyonun,  defne yapraklarına uyarlanması temelinde yapılan işlemler, daha kısa sürede ve daha hızlı sonuçlar vermektedir. Görüntü işleme fonksiyonları ile matematiksel fonksiyonların eş zamanlı olarak kullanıldığı bu yeni yaklaşımda, işlemci (cpu) hızı artırıldıkça, doğru orantılı olarak işlemin sonlanma hızı da artmaktadır. (Salt görüntü işleme fonksiyonları kullanılsaydı, işlemci hızının artışı yine olumlu sonuçlar verecekti fakat işlemcide geçmeyen süreler – kameralardan görüntünün alınması, veriyolunda kaybedilen zamanlar, hafızaya okuma/yazma süreleri vb. – yüzünden beklenen hız artışı daha sınırlı kalacaktı.)

 

 

 

 

 

 

 

Yukarıdaki resimde, sağlam ve hatalı yaprağın, üst yarısının kenar çizgileri gösterilmiştir. İdeal bir yaprakta (hatasız) semer noktası (saddle point) hiç olmamalıdır.

Analiz Yöntemi :

  1. Yaprak yatay düzlem ile sıfır derece açı yapacak şekilde döndürülür
  2. Yaprağın alt ve üst bölgelerinin konturları (contours) çıkartılır
  3. Çıkartılan konturlara ait, satır-sütun değerleri fonksiyonel olarak çıkartılır
  4. Oluşturulan 2 boyutlu fonksiyonda semer noktaları (saddle points) aranır
  5. Semer noktaları derinliği belirlenen değerlerden fazla ise yaprak hatalıdır
  6. Yaprak yatay eksenle 90 derece açı yapacak şekilde döndürülür (Sol ve Sağ tarafı baş aşağı gelecek şekilde)
  7. Tüm kontroller yeniden yapılır.

Tüm bu işlemlerde kullanılan belli başlı HALCON operatörleri :

  • Contour processing (edge-detection, smooth contours, union contours…)
  • 1d fonksiyonel işlemleri (create_funct_1d_pairs, derivate_funct_1d  …)
  • Semer Noktası işlemleri (saddle_points_sub_pix …)

Bu kez çalışan HALCON kodu örneği yerine kullanılan fonksiyonları ve yöntemi açıkladım. Konuyla ilgilenenlerin olması ve ulaşması durumunda çalışan gerçek kodlar ile daha detaylı paylaşımlarda bulunabiliriz.