Mustafa Sarı

Mustafa Sarı hakkında

(Samsun, 26.03.1973, ,İTÜ, Elektronik ve Haberleşme Mühendisliği, Yazılım)

HALCON12 Hobj Viewer

One of the HALCON 12’s new feature is HObj file support.

HOBJ is a binary file format, which provides the functionality to write and read all kinds of iconic HALCON objects (images, regions, and XLDs). Since data is written with neither compression nor conversion, writing this file format is faster than other supported file formats in most circumstances. Hence, if an application needs to read and write all kinds of HALCON objects as fast as possible and no compression is required, this format should be used. The default file extension for this file format is ‘.hobj’. For images, all HALCON pixel types can be written. Multi-channel images are supported. The channels can have mixed pixel types but must have the same width and height. The domain of an image and it’s creation date are stored in the file as well. An object tuple is written into a single file.

I wrote a opensource simple .NET HObjViewer to display hobj files. (Requires HALCON 12 Runtime license)

 

Download Visual Studio Express Edition Source codes of HObjViewer

 

HObj, HALCON 12 ile birlikte gelen yeni bir özelliktir. İkonik nesnelerin (Resim, region, xld) okunmasında ve yazılmasında çok daha hızlı çalışmaktadır. (Sıkıştırma algoritmaları kullanmadığı için)

Mavis olarak, HALCON Runtime yüklü makinalarda hobj dosyalarını görüntüleyebilmek için geliştirdiğimiz, açık kaynak kodlu HObjViewer uygulamasını indirebilirsiniz.

Download Visual Studio Express Edition Source codes of HObjViewer

 

Paralel Programlama

PC tabanlı görüntü işleme uygulamalarında, paralel programlama teknikleri kullanmak çok radikal hız artışları sağlayabilir. Yazılımımız, gerçekten sahip olduğumuz donanımın hakkın veriyor mu? Günden güne hızlanan bilgisayarlar, çok çekirdekli işlemciler, devasa hafızalar… Bu kaynakları gerçekten etkin olarak kullanabiliyor muyuz?

Düzgün yönetilmememiş paralel programlama (Multi threaded programming) uygulamalarında çoğu kez olan yukarıdaki gibidir 🙂 Bilmem kaç çekirdekli cep telefonlarının neden bu kadar yavaş olduğu sorusunun da cevabı? Tamam çekirdek çok da, uygulama onları nasıl kullanıyor?

Paralel programlama derken tam olarak neyi kastediyoruz?

Paralel programlama, bilgisayar işlemcisinde gerçekleşen işlemlerin, birinin diğerini beklemediği, aynı anda bir çok işlemin çalıştığı uygulamalardır. Visual Studio .NET dilinden konuşursak, çok kanallı programlar (Multiple threads), parallel tasks, background worker v.b. yapılar ile çoğu programcının bir şekilde aşina olduğu yapılardır. Bu yapılar ile uğraşanlar iyi bilir, duruma göre tam bir başağrısıdırlar. Geliştirmesi zor, debug etmesi zor, sonuçların ekranda gösterilmesi bile ayrı bir teknik gerektirir. Lock objects ler, autoreset, manual reset eventler, mutexler, semaphore lar v.b. .NET yapıları, durduk yere hiç bir programcının severek bulaşacağı yapılar değildir, kabul edelim.


Eğer öyle ise, görüntü işleme uygulamam gerçekten paralel çalışmalı mı?
Bu  sorunun cevabı, eğer zaman sorunum varsa, ya da birim sürede çok daha fazla kontrol etmem gerekiyorsa EVET, aksi halde HAYIR dır.

Gerçek hayattan örnek vermek gerekirse, Derby traş bıçakları fabrikasında bir makinada kurulu olan sistemimiz, her 600 milisaniyede bir, üretilen traş bıçağını kontrol etmektedir. Böyle bir sistemde,

  • Kameradan Görüntünün Alınması (80 ms.)
  • Alınan Görüntünün İşlenmesi (60 ms)

sürmektedir. Özetle, tetik sinyali geldikten sonra, en geç 150 ms. sonra, OK ya da NOK cevabını sisteme bildirmekteyiz. Geri kalan 450 ms. içinde de sistem diğer ürünün gelmesini beklemektedir. Dolayısıyla, bir zaman sorunu yoktur, işlemleri paralel yapmak kimseye bir şey kazandırmayacaktır. Bu durumda, eski tip, ardışıl programlama (görüntü al, işle, dijital çıkış ver, bekle, başa dön..) en doğru seçenek olacaktır.

Peki ya sürekli ve çok hızlı kontrol etmem gerekirse, mesela araçlardaki şerit takip sistemi örneği gibi. Sistem sürekli ve olabildiğince hızlı görüntü almalı, işlemeli ve hiç beklemeden yeniden görüntü almalı, yeniden işlemeli. bu alma-işleme süreci ne kadar kısa olursa, sistem o kadar sağlıklı / gerçeğe yakın çalışacaktır.

Yine gerçek bir örnek verelim;

Halı Kesme makinası olarak kurulumunu yaptığımız sistemde 13 adet kamera vardır. 50 m/dk hızıyla üretilen halıları dikey olarak tam kesim çizgisinden kesmek istiyoruz. Bunun için 13 bıçağın, kameralar yardımıyla anlık olarak sağa-sola yönlendirilmesi ve tam çizgi üzerinden kesim yapılması sağlanmalıdır.

Halı, esnek olduğundan, kesim çizgisi sağa sola kayabilmekte ve ancak kamera yardımıyla çizgiyi görüp takip etmesi sağlanabilmektedir. Sorun şu ki, 50 m/dk. hızında üretim yapılırken, 120 ms. içinde halı 10 cm kaymaktadır. Dolayısıyla, bu projede, tipik olarak 1. kameradan görüntü al, işle, 2. ye geç al işle, sonra 3. ye… şeklinde bir yaklaşım izlenmiş olsa, algoritmalar ne kadar düzgün çalışırsa çalışsın, sonuç tam bir felaket olacaktır. Tek bir kameradan görüntü alınıp yine aynı kameraya sıra gelene kadar, halı 1 m. den fazla ilerleyecektir ve böyle bir sistem elbette kabul edilemez.

HALCON 12 ile Paralel Programlama

Visual Studio kullanarak geliştireceğimiz, çok kameralı tipik bir paralel programlama algoritması genel hatları ile şu şekildedir.

3 adet genel thread vardır.

  1. Grabbing Threads : Var olan kamera sayısı kadar thread açılır. Her bir thread sonsuz bir döngüde görüntü alır. Diyelim ki 4 kamera var. 4 ü de eş zamanlı olarak görüntü alır. Biri diğerini beklemez, her biri bağımsız olarak kendi görüntüsünü alır.
  2. Processing Thread : Yine kamera sayısı kadar thread açılır. Her bir thread, sonsuz bir döngü içinde, kendi kamerasından görüntü alınmışsa, bunu işler yine başa döner (yeni görüntü alınmasını bekler) görüntüyü işlemeye başladığı anda, grabbing thread yeniden resim alma işi ile meşgul olur. Diyelim ki, resim alma (grabbing) 60 ms, işleme ise 20 ms sürsün. bu durumda, tek bir kamera 60 ms içinde sonucu verecektir (80 değil) çünkü 20 ms. işleme sürerken, grabbing thread görüntü almaya başlamıştı ve işleme bittikten 40 ms. sonra (60 değil) yeni görüntü gelecektir.
  3. User Interface Thread : Benim kullanmadığım ama genel amacı, bulunan sonuçların ekranda gösterilmesi, label buton panel v.b. form kontrollerinin çizilmesi amacıyla kullanılır. Ben, HALCON fonksiyonlarına, DisplayHandle gibi bir değişken gönderiyorum ve ekran işlemlerini de HALCON içinden yaptırıyorum. Böylece, sonuçların toparlanması ekranlarda gösterilmesi gibi işleri C# tarafında değil, HALCON tarafında hallediyorum.

Bu yapı, kendi içinde gayet hızlı çalışacak ve CPU kullanımı tüm çekirdeklerde %100 e vuracaktır. bu iyiye işarettir, tek bir cpu birimini boşa harcamaya gerek yoktur ve uygulamamız resmen donanımın hakkını veriyor demektir.

Ayrıca, bellek kullanımına dikkat edin, sonsuz döngüde çalışan thread (kanal) yapıları, nesneleri hafızadan atamıyorsa, çok çabuk hafıza dolabilir. İdealde hafızanın sabit kalması gerekmektedir.

HALCON 12 ile Paralel Programlama

Visual Studio ile, paralel programlama tekniklerini etkin bir şekilde kullanarak, çok kameralı sistemde, tüm görüntü alma ve işleme kanallarını paralel çalıştırarak, çok büyük bir hız avantajı sağladık. Şimdi HALCON ile bu yapıyı daha da geliştirmek mümkün.

Öncelikle HALCON, tecrübeli olmayan programcılar ya da .NET çok kanallı yapılarını sevmeyen tercih etmeyen kullanıcılar için bir çok yenilik barındırmaktadır. Artık tüm paralel programlama işlemlerini HALCON kendisi yerine getirebilmektedir. HALCON12, yazdığınız kod parçalarını (HDevelop procedure) tek bir tıklama ile paralel olarak çalıştırabilmektedir. (Bizim C# ile tabir yerinde ise, o kadar kastırarak yaptığımız dümenlerin hepsi boşa mı gitti şimdi 🙁 )

Ve hala daha da fazlasını sunmaktadır. O da şu :

diyelim ki, her bir kameradan alınan görüntüde, tek bir işlem değil de, birden fazla işlem yapmak durumundayım. Mesela alınan görüntüde hem barkod, hem karekod, hem de OCR yapmak durumundayım diyelim.

Barkod bulma 40 ms, OCR 90 ms, karekod okuma ise 70 ms. civarı sürsün.

HDevelop içinde bu işi yapan 3 güzel procedure yazdığımı varsayalım. HALCON 12, bu 3 procedure ü paralel olarak başlatabilmekte (par_start komutu ile) Buraya kadar olan, zaten tecrübeli C# kullanıcılarının daha önceden yaptığına denk gelen kısım. HALCON, par_join komutu ile, bu 3 procedure ü de aynı anda çalıştırmakta, en son hangisi biterse, diğerleri onu beklemekte, ve tek bir yapı çalıştırmışım gibi sonlanmakta. Dolayısıyla, bu yapıları paralel çalıştır diyorum, sanki hepsi tam da aynı anda çalışıp aynı anda bitmiş gibi, bir alt satırda da hepsinin sonuçlarını toplayabiliyorum. Bizim örneğimizde, 90 ms. sonunda barkod, karekod ve OCR işlemim bitmiş, elimde hazır sonuçlar olmuş oluyor.

Bu güçlü yapıyı, C# daki özgün multi thread yapım ile birleştirdim. Ortaya, C# tarafında, tüm kameralardan görüntü alma ve işleme işlemlerinin paralel koşturulduğu, HALCON tarafında da bir çok procedure (alt programı) aynı anda çalıştırıldığı, hibrit bir yapı çıktı. Sistemi 13 kamera için çalıştırdığımda, cpu fanı hemen devreye girmekte CPU maksimum performansa zorlanmakta. (Bu aşamada i7 gibi işlemcilerin gerçek farkını ve hızını hissedebilmek de bir programcı olarak ayrı bir mutluluk kaynağı oluyor.)

Peki, neden aynı anda bir çok procedure start edilir. Ya da ne gibi uygulamalar buna ihtiyaç duyar.

Açıkçası bu çok sık karşılaşılan bir yapı veya ihtiyaç değildir.

Bizim halı kesme makinasında, siztem kesim çizgisini aramaktadır. Yazdığım algoritmalarda bazen var_threshold ile sonuca gitmiş, bazen de binary_threshold işe yaramıştı. Bazı durumlarda median_rect filtresi güzel sonuçlar vermiş, bazen ise label_to_region işe yaramıştı. Bazen GMM classification imdada yetişmiş, bazen resmi decompose edip hsv kanallarına bakmam gerekmişti?

İyi ama, bunların hangisini kullanmam en doğrusuydu? Apaçık ki, hiç biri tek başına yeterli değil. Hepsini tek tek denesem, bu sefer çok uzun sürebilir. İşte tam da bu anda, yazdığım tüm alt programları (ki aslında hepsinin derdi aynı, hepsi de çizgi arıyor) aynı anda start ediyorum. Resmi grab etmem (kameradan almam) ortalama 60 ms. kadar sürüyor (bendeki pixel clock, exposure değerleri ile inebildiğim minimum değer) ve bir sonraki resim gelene kadar, tüm yapıları HALCON aynı anda start ediyor. bunlardan bir veya daha fazlası sonucu zaten buluyor ve bulduğum sonucu işliyorum.

Sonuç?

Eğer bu kadar fazla multitasking sonucu yazdığınız kodlar halıya çıkmadıysa, iyi yoldasınız demektir.

Yazının Özeti :

HALCON 12 güçlü bir multithreading (paralel programlama) desteği sunmaktadır. par_start, par_join, mutex, message queue yapılarını inceleyin, örneklere bakın, dokümanları okuyun, çok yardımcı olacaktır. Buna rağmen danışmanız gereken bir yer olursa, buradan ya da info@mavis.com.tr ile bana istediğiniz zaman ulaşabilirsiniz.

kolay Gelsin 😉

Kameralı Otomatik Dikey Halı Kesme Makinası

Mavis, dikey halı kesme makinası (5 mt, 13 kafa, 60 mt/dk.) kullanıma alındı.

 

 

 

 

 

 

 

Sistemin çalışan bir videosu şu adreste izlenebilir.

https://www.youtube.com/watch?v=hHQT50P9wk8

Daha fazla bilgi için bizimle iletişime geçebilirsiniz.

3D Görüntü İşleme Teknikleri – 2

Stereovision Prensibi

Bir önceki makalede, 3D görüntü işleme teknolojilerine ana başlık olarak değinmiştik. Bu makalede biraz daha teknik ayrıntıya girebiliriz.

Önce işin biraz matematiğine değinelim. Stereovision nasıl çalışır?

Nesne farklı açılardan gözlemlenir.

Eğer α ve β açıları ile b mesafesi biliniyorsa, basit bir geometrik hesaplama ile P nin pozisyonunu bulabiliriz.

Buna, triangulation (üçgenleme) prensibi denir.

P noktası her iki kamerada bir miktar kaymış olarak görünür (sırasıyla tek gözümüzü kapattığınızda gördüğümüz nesnelerin bir miktar kayması gibi)

Sonuç olarak, her iki kamera arasındaki mesafe, açı, focal mesafe biliniyorsa, kaymanın kaç pixel olduğu da hesaplanabilir. Buna Disparity denir. Uzaktaki nesneler için kayma az olacaktır, yakındaki nesneler için ise kayma daha fazla olacaktır. Bu durumda, stereovision da temel prensip, her bir pixel için Disparity değerini hesaplayabilmektir.

Nemrutun her iki (sol ve sağ kamera) tarafından alınmış görüntüsü soldaki gibidir. Şapkasının hemen üst noktası, sağ kameraya daha yakın olduğundan 156. pixelde iken, sol kamerada 160. pixeldedir. Kameralar kalibre edilmiş olduğundan aynı Y değerlerini vermektedirler. Yine kalibrasyon sonucu, bu 4 pixel kaymanın, ne kadar mesafeye dek düştüğü bulunabilir. Burada, sistemin hızlı çalışması için, sol resimdeki P(160,120) noktasının, sağ resimde nerelerde aranacağını sistem kestirebilmek zorundadır. Kalibrasyon sonucu, sol kameradaki her bir satır (row) sağ kamerada da aynı satıra denk düşecek şekilde resim dönüştürülür (rectification). Son olarak, stereo kamera, hangi mesafeden çalışıyor ise, (10 cm, 30 cm, 1 mt., 2 mt. vs.) yaklaşık olarak, kaç pixel kayma olabileceği bellidir. Böylelikle, sol kameradaki her bir tekil pixel, sağ kamerada tek bir satır üzerinde, dar bir alanda aranır ve hızlıca bulunur.

Şimdi işin matematiğine daha ayrıntılı girelim.

Stereo Teori – Perspective Projection

3 boyutlu olarak algılanmak istenen nesne üzerindeki her bir nokta (p), biri sol kamerada (p’), diğeri sağ kamerada (p”) olmak üzere bir geometrik yüzey oluşturur. Buna epilolar yüzey denir.

Her bir kameranın, x-y eksenlerinden oluşan yüzey ile epipolar yüzeyin kesişim noktalarının kenara olan uzaklıkları, l1 ve l2 olsun. Sistem, sol kameradaki her bir tekil p’ noktasının sağ kamerada nerede bulunduğunu (p” noktaları) bulmak zorundadır. Normalde bu, uzun bir işlemdir. Örneğin 1.3M Pixellik kameralar kullanılıyorsa, soldaki her 1.3 milyon pixel, sağ tarafta tek tek aranacak ve Disparity değerleri hesaplanacak. Bu işlemi hızlandırmak için, Camera Rectification dediğimiz tekniği kullanırız.

Stereo Rectification

Rektifikasyondaki amaç, p noktasının her iki kameradaki izdüşümleri olan p’ ve p” noktalarını, yatay eksende aynı paralel doğru üzerine düşürmektir. Bunun için, her iki kamera görüntüsü de, bir miktar döndürülür ve pixeller transform edilir. Sonuçta, p’ ve p” noktaları aynı y (row – satır) değerine denk getirilir. Rectified (düzeltilmiş) görüntüler, şimdi aynı eksendedir (z=1) Epipolar doğrular, (l1 ve l2) aynı paralel düzlemdedir. Artık, sol kameradaki p'(x,y) noktasındaki bir pixel, sağ kamerada herhangi bir yerde değil, aynı y değerine sahip olan satırda aranacaktır. Üstelik, bütün bir satır boyunca aramaya gerek yoktur. Nesnenin kameraya olan uzaklığı aşağı yukarı belli ise, satır boyunca ne kadar ileride ya da geride olabileceği de belli demektir. Bu yaklaşım, hem çok daha hızlı olacak, hem de çok daha etkin PC ve CPU kullanımı anlamına da gelecektir.

Pasif Stereo Vision

Pasif Stereovision tekniğinde, 2 adet kamera vardır fakat projektör yoktur. Nesnelerin üzerindeki şekillerden ve desenlerden faydalanılarak, her bir pixelin ne kadar kaydığı hesaplanmaya çalışılır.

Üzerinde resim olan kupanın sol ve sağ kameralar ile alınmış görüntüsü yukarıdaki gibi olsun. Bu durumda, mesela resimdeki hayvanın gözünün sol ve sağ kamerada kaç pixel kaydığı, kupanın kulpunun ne kadar kaydığı, ayakkabısının alt köşesinin ne kadar kaydığı gibi bilgilere ulaşabilirim. (Disparity değerleri bulunabilir) Özetle, desen ya da resim (texture) içeren yerler için disparity değerlerine erişilebilir. Fakat, hiç resim ya da desen içermeyen, mesela masanın üzeri, arka plandaki duvar gibi yerlerde, disparty değerlerini hesaplamak mümkün değildir. Bu durumda, derinlik bilgisine de erişilemeyecektir.

 

 

 

 

Aktif Stereo Vision

Pasif stereo vision, nesne üzerinde yeterli texture (desen, resim) yoksa derinlik bilgisine ulaşamıyordu. Bu durumda ana fikir; bir projektör kullanarak nesnenin üzerine bilinen patterne sahip infrared görüntü göndermek ve stereovision kameraları ile, bu infrared desenleri yakalamaktır. Yukarıdaki şekilde de görüldüğü gibi, kupanın silindir geometrisinden dolayı, iyi görülemeyen yerleri dışında (gölgeleme/shadowing) hemen her noktada derinlik bilgisine ulaşılabilmektedir. (Silindirik yüzeylerin aşağı yukarı 2/3 kadarı stereovision ile yakalanabilmektedir. Tamamını görmek için, 3 veya daha fazla stereovision kameraya ihtiyaç olabilir)

3D Görüntü İşleme Teknikleri – 1

3D uygulamaları son zamanlarda hızla yaygınlaşmaktadır. Bu makalemizde, mevcut 3D modellerini ve uygulama alanlarını göreceğiz. Burada kastedilen 3D, görüntü işlemede kullanılan 3D dir. Standart kameralar (monocular) X-Y düzleminde görüntüler verir. Biz, aynı zamanda derinlik (Z) bilgisini de içeren, X-Y-Z bilgisi verebilen teknolojilere hızlıca değineceğiz.

Günümüzde yaygın olarak kullanılan 3D yapay görme teknolojileri şunlardır.

1. Laser Triangulation
Bu modelde, genellikle bir çizgi lazer kaynağı ve kalibre edilmiş bir kamera kullanılır. Genellikle çizgi lazer ve kamera, birlikte tek bir kutu içinde yer alır. Sistemin çalışabilmesi için, 3 boyutlu olarak algılanmak istenen nesnenin kontrollü bir şekilde hareket etmesi gerekmektedir. (Bir encoder yardımıyla nesnenin ne kadar gittiği hesaplanabilir) sistem sürekli fotoğraf çekerek lazer çizgisindeki profil değişikliğinden faydalanarak, 3 boyutlu nesnenin profilini çıkartır. Piyasada farklı alternatifler vardır, daha önceden LPS 36 isimli bir modeli incelemiş, HALCON ile çeşitli uygulamalar geliştirmiştim. Ülkemizde bu veya benzer ürünleri kolaylıkla temin etmek mümkündür.

2. Time Of Flight Kameralar

Kişisel olarak, geleceklerinin iyi olduğunu düşündüğüm 3D kamera teknolojisidir. Daha önce şu makalede detaylı olarak bu kameraları anlatmıştım. Çalışma prensipleri (özetle) 3D olarak belirlenmek istenen nesnenin fotoğrafı alınırken, aynı zamanda infrared (veya başka bir dalga) göndermek ve gelen dalganın ne kadar geciktiğini ölçerek (bir nevi radar), her noktada mesafeyi hesaplamak mantığına dayanır. Gerçekte zaman ölçümü Frekans Kaydırma (Frequency shift) modülasyonu ile gerçekleştirilir. Yine piyasada (nadir olmakla birlikte) TOF kameralar mevcuttur.

3. Stereovision

En yaygın olarak kullanılan 3D teknolojisidir. İnsan gözü modelinde olduğu gibi, 2 kamera kullanılır. Kameraların arasındaki mesafe ve merkez doğrultu açıları net olarak bilindiğinden, her bir noktanın, her iki kameradaki izdüşümü, basit geometrik hesaplamalar ile bulunabilmektedir. (İleride çalışma prensibi daha detaylı anlatılacaktır)

 

4. Fringe Projection

Bu teknolojide, algılanacak 3 boyutlu nesne üzerine bir projektör yardımıyla özel bir desen (genelde çizgiler vb) düşürülür. Kamera bu çizgileri algılar. Çizgilerdeki değişim, 3D profili verir. Laser Triangulation tekniğinde, nesne hareketli idi, bu teknikte nesne sabit olup, üzerine tek bir lazer çizgi yerine, pek çok çizgi aynı anda düşürülmektedir. Çalışma prensibi aynıdır.

 

5. Kinect (PrimeSense) Grubu

Oyun konsollarının (XBox, PS v.b.) yaygınlaşması ile birlikte genellikle PrimeSense firmasının sensörlerinin kullandığı, stereovision tekniğidir. Aslında farklı bir teknik olmamakla birlikte, çok yaygın bir grup olduğu için ayrı bir başlık olarak ele alınabilir. Burada, projektör, bilinen pattern’e sahip görüntüyü nesne üzerine yollar. Kamera bu patterni algılar. Orijinal pattern ile olan değişimden yola çıkarak, 3 boyut oluşturmaya çalışır.

6. Active Stereo Vision

Bu teknikte, stereovision modeli biraz geliştirilerek, araya bir projektör eklenmiştir. Projektör rastlantısal bir pattern oluşturup nesnenin üzerine gönderir. Stereo kameralar bu patterni yakalayıp, 3 boyut bilgisini çıkartır. Normal stereo Vision da, projektör yoktu. Kameralar, gerçek cismin görüntüsünden yola çıkarak 3 boyut bilgisini çıkartmaya çalışıyordu. Cismin üzerinde texture (şekil, yazı, desen vb.) yoksa, böyle bir durumda stereo vision başarılı olamıyordu. Çünkü her pixel kendi komşu pixelleri ile aynı bilgiyi taşıyor farklılık yaratmıyordu. Bu modelde, projektör cisim üzerine yeterli karmaşıklıkta desen varmış gibi pattern yollar. Kendi gönderdiği patterni arar ve 3 boyut bilgisini çıkartır. En sağlıklı 3D yöntemi de, günümüzde budur. (Firmamız, Active Stereo Vision ürünü olan Ensenso cihazlarının Türkiye distribütörüdür.)

Tüm teknikleri artı ve eksileri ile karşılaştıran aşağıdaki gibi bir tablo yaptım.

 

 

Buradaki Multi-View stereo, aynı nesneye birden fazla yerden (ön, arka, sağ, sol v.b.) bakmak gerektiği durumları ifade eder. Örneğin 3-4 Kinect cihazını farklı açılardan birbirine bağlayıp daha iyi bir görüntü elde edemezsiniz. (Kinect böyle bir teknolojiyi sunmamaktadır, tek ve bağımsız çalışmaktadır gibi.)

Bu konuya kaldığımız yerden devam edeceğiz. Önce Stereo Vision teknolojisine daha detaylı giriş yapıp, işin tekniğini kavrayacak, sonra HALCON ile stereo vision uygulaması nasıl geliştiririz buna bakacağız.

Bir sonraki bölüm için tıklayınız…

 

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

Yazı dizisinin ilk IV bölümünü takip edenler HALCON hakkında bilgi sahibi olup HDevelop ile uygulama geliştirmeye başlamışlardı. Şimdi merak edilen, yazılan HDevelop kodlarının Visual Studio içine aktarılıp, uygulamaya dönüştürülmesi işlemidir. Bu makalede bunu anlatacağım. Yaygın kullanıldığı için Visual Studio 2008 versiyonu üzerinden gideceğim fakat daha yeni versiyonlarda da mantık tamamen aynı.

Metodolojik olarak 2 farklı yöntem ile kendi uygulamalarımıza HALCON desteği verebiliriz.

  1. Klasik Yöntem : Bu yöntemde HDevelop içinde yazılan kodlar Export edilir, Visual Studio içinden bu export edilmiş kodlar yüklenir ve uygulama oluşturulur.
  2. Direk Yöntem : Bu yöntemde, HDevelop içinde yazılmış kodlar hiç bir yere export edilmez, Visual Studio ile geliştirdiğimiz program, gidip direk HDevelop program ya da programcığını çalıştırır.

Bu sayfada her 2 yöntem de resmedilmiş.

Biz, öncelikle Klasik Yöntem ile başlayacağız. HALCON.NET nesne modeline hakim olabilmek, HDevelop değişkenlerini, Visual Studio içinden görebilmek, değiştirebilmek vb. amaçlar için daha doğru bir başlangıç noktası. Gerçekte (mesela bizim uygulamalarımız) 2. yöntemi kullanmaktadır. Yazı dizimizin ilerleyen bölümlerinde, bu yönteme de yeri gelirse değiniriz. Şimdilik 1. yöntem ile devam edelim.

Visual Studio 2008 konfigüre edilmesi

Visual Studio ile sıfırdan herhangi bir uygulamaya başladığınız gibi, yeni bir Windows uygulaması oluşturun. Ben projenin adını HALCONTest koydum. (.NET Framework 3.5 kullanıyorum)

Sol taraftaki Toolbox üzerine HDevelop görsel bileşeni olan HWindowControl isimli komponenti eklemeliyiz. Bu komponent, HDevelop içindeki Graphics Windows gibi, görsel çıktıları göstermemize yardımcı olacaktır. .NET içindeki PictureBox bileşenine benzer. Toolbox a yeni bir bileşen eklemek istediğimizde yaptığımız gibi, ToolBox üzerinde ike sağ tuşa tıklayıp, “Choose Items…” seçeneğini seçerek aşağıdaki ekranlardaki gibi yüklemeyi yapabiliriz.

.NET FrameWork componenleri arasında, Browse butonuna basarak, HALCON11 in yüklendiği klasörün, bin\dotnet35 alt klasöründeki halcondotnet.dll dosyasını seçmemiz gerekir.

OK leyip kaydettiğimizde HWindowControl bileşenini artık araç çubuğunda görebilmemiz lazım.

 

Şimdi bu bileşeni formumuza çekip, bir buton ekleyelim. Benim Formum şu şekilde oldu.

Bu form üzerindeki Çalıştır butonuna bastığımızda, 4. bölümde anlattığımız programın çalışmasını isteyeceğiz. Dolayısıyla, şimdi HDevelop’a dönüp, bu kısa programı yazıp export edelim.

HDevelop içindeki Araç çubuğunda, export butonuna bastığımda, yukarıdaki diyalog penceresi gelir. Buradan, dil olarak C# HALCON/.NET seçtim. Export dediğimde, Export File olarak belirtilmiş dosyayı oluşturacaktır.

Export edilmiş dosyayı (benim örneğimde unnamed.cs) Visual Studio ile açtığımda, HALCONun benim için, son derece profesyonel bir C# kodu oluşturduğunu gözlemleyeceğim.

Şimdi hem HALCON nesne modeline, hem de ortama biraz ısınmak için, adım adım bu kodu irdeleyeceğiz. Öncelikle, bu kodun en çok action() ile başlayan kısmı ile ilgileniyoruz. Bunun dışındaki tanımlamalar vs. şimdilik ilgimiz dışında. action() yapısı içindeki kod bloğunu alıp, bizim butonumuzun altına taşıyacağız.

Şimdi kendi formumuza (Form1) dönelim. Kod yazdığımız sayfada,

using HalconDotNet;

tanımlamasını yapalım. (Böylece, asıl formumuz çinden HALCON kütüphanesini kullanabilelim)

Projem basitçe yukarıdaki gibi oldu. Şimdi Form görünümüne geçip, Çalıştır butonuna basıldığında yapması gerekenleri, action() içinden kopyalayıp, buraya yapıştırabilirim.

 

 

        private void button1_Click(object sender, EventArgs e)
        {
            // Local iconic variables 

            HObject ho_Image, ho_Region, ho_ConnectedRegions;

            // Local control variables 

            HTuple hv_Number = null;

            // Initialize local and output iconic variables
            HOperatorSet.GenEmptyObj(out ho_Image);
            HOperatorSet.GenEmptyObj(out ho_Region);
            HOperatorSet.GenEmptyObj(out ho_ConnectedRegions);

            ho_Image.Dispose();
            HOperatorSet.ReadImage(out ho_Image, "rings_and_nuts");
            ho_Region.Dispose();
            HOperatorSet.Threshold(ho_Image, out ho_Region, 0, 128);
            ho_ConnectedRegions.Dispose();
            HOperatorSet.Connection(ho_Region, out ho_ConnectedRegions);
            HOperatorSet.CountObj(ho_ConnectedRegions, out hv_Number);
            HOperatorSet.SetTposition(3600, 220, 180);
            HOperatorSet.WriteString(3600, hv_Number);
            ho_Image.Dispose();
            ho_Region.Dispose();
            ho_ConnectedRegions.Dispose();

        }

Ve ilk programımız için hepsi bu kadar. F5 e bastığımzda programımızın derlenip, hiç hata vermeden çalışması lazım. İşte ilk programımızın ekran görüntüsü :

Siyah bir pencere ve ortada bir yerde 8 rakamı. Eğer gördüğünüz bundan ibaret ise, herşey yolunda demektir. Peki neden siyah ekran? Çünkü HALCON biz neyi ekranda göster dersek onu gösterir. Eğer, okuduğu resmi (ho_Image isimli bir değişkene atamış), bulduğu tüm bileşenleri (ho_ConnectedRegions isimli bir değişkene atamış) göstermesini istersek, ayrıca ekranda 12 farklı renk kullansın istersek, bir de, daha önceden bahsi geöen 3600 nolu grafik penceresi yerine, bizim koyduğumuz hWindowControl isimli bileşen üzerinde göstersin istersek,

aşağıdaki kodları araya eklememiz gerekecektir.

HOperatorSet.SetColored(hWindowControl1.HalconID, 12);            HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconID);            HOperatorSet.DispObj(ho_ConnectedRegions, hWindowControl1.HalconID);

bu son durumda, bütün kod bloğu :

 

        private void button1_Click(object sender, EventArgs e)
        {
            // Local iconic variables 

            HObject ho_Image, ho_Region, ho_ConnectedRegions;

            // Local control variables 

            HTuple hv_Number = null;

            // Initialize local and output iconic variables
            HOperatorSet.GenEmptyObj(out ho_Image);
            HOperatorSet.GenEmptyObj(out ho_Region);
            HOperatorSet.GenEmptyObj(out ho_ConnectedRegions);

            ho_Image.Dispose();
            HOperatorSet.ReadImage(out ho_Image, "rings_and_nuts");
            ho_Region.Dispose();
            HOperatorSet.Threshold(ho_Image, out ho_Region, 0, 128);
            ho_ConnectedRegions.Dispose();
            HOperatorSet.Connection(ho_Region, out ho_ConnectedRegions);
            HOperatorSet.CountObj(ho_ConnectedRegions, out hv_Number);
            HOperatorSet.SetColored(hWindowControl1.HalconID, 12);
            HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconID);
            HOperatorSet.DispObj(ho_ConnectedRegions, hWindowControl1.HalconID);
            HOperatorSet.SetTposition(3600, 220, 180);
            HOperatorSet.WriteString(3600, hv_Number);
            ho_Image.Dispose();
            ho_Region.Dispose();
            ho_ConnectedRegions.Dispose();

        }

şeklinde olacaktır. Ve haliyle ekran çıktısı da, HDevelop ta gördüğümüz şekle iyice yaklaşmış olacaktır. (Yeniden F5)

Artık, kendi başına çalışabilen, güçlü ve son derece hızlı bir C# uygulaması edindik. Üstelik form üzerine istediğiniz bileşenleri ekleyerek zenginleştirebilir, tamamen kendi tsarımlarınızı yapabilirsiniz. Artık hiçbir sınırınız yok. Bu uygulamayı herhangi bir bilgisayarda çalıştırabilmek için, o bilgisayarda HALCON Runtime kurulu olmalıdır unutmayın. Kendi bilgisayarınızda zaten HALCON development kurlu olduğundan, sorunsuz çalışacaktır.

(Not : Eğer derleyici hata verirse, Project menüsü, App Properties seçerek, gelen dialog penceresinde Platform Target olarak Any CPU seçiniz. Kullandığınız .NET Framework versiyonuna uygun Halcondotnel.dll dosyasını yükleyip yeniden deneyiniz)

Programın tamamını buradan indirebilirsiniz.

Konuya daha detaylı olarak devam edeceğiz. İlgilenenlere bir sonraki makalede tekrar görüşmek dileğiyle kolay gelsin diyorum. Görüşmek üzere.

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…

Kameralı Hız Belirleme

Kamera ile hız belirlemek (bir tür radar) konusunda öğrenciler ya da meraklılar için basit bir HALCON kodu ile yardımcı olmak istedim. Kameralı hız belirleme konusunda bir çok yaklaşım olabilir. En sık kullanılan yaklaşım, ardışıl olarak alınan 2 görüntü arasında, farklılıkları belirlemek, (bu farklılıklar genellikle yer değiştiren nesneler, yani araçlardır) ve bu farklılıktan kaynaklanan yer değiştirme mesafesini bulup, arada geçen zamana bölmek suretiyle hızın elde edilmesidir.

Örnek olması açısından, şirketimizin balkonundan cep telefonumla sokaktan geçen araçlarn resimlerini çektim. (Normalde, kullanılan endüstriye kameralar, resim ile birlikte resmin alındığı hassas zaman bilgisini de verirler. Konuyla ciddi ilgilenenler o tür kameralar bulmalıdır. örneğin iDS imaging ürünleri)  Ben cep telefonumla çektiğim için, ortalama 2 sn bekledim. (Yani, umarım) Tabii elim sabit olmadığı için kamera biraz titredi 🙂 Yine de tüm bunlar, yoldan geçen güzelim twingonun hızını iyi kötü belirlemem için engel teşkil etmedi.

İşte aldığım resimler ve işte bunları işleyen HALCON kodu.

Aslında buradan rar dosyasını da indirebilirsiniz.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Programın çalıştırılması ile oluşan ekran görüntüsü ise

 

 

 

 

 

 

 

 

Programın çalışma şekli.

Program aslında thresholding ile, lacivert renkli nesneleri arar. Görüntü renkli kamera ile alındığı için, önce RGB kanallarına ayırıyor resmi. Sonra HSV değerlerini buluyor. Threshold işlemlerini HSV kanallarında yapıyor.

Bir kere aracı bulduktan sonra, gerisi zaten 4 işlem. Anlatmaya gerek yok.

İdealde, bunun gibi sadece özel bir renge göre radar yapılmaz tabii 🙂

İdealde olması gereken, iki resmin karşılaştırılıp, aradaki farkı oluşturan noktalardan araçlar bulunup hız belirleme yapılmasıdır. check_difference isimli HALCON örneği incelemeye değer güzel bir çalışmadır mesela.

Konuyla ilgilenenlere kolay gelsin diyorum. İlgi alaka olursa, daha profesyonel olarak konuya yaklaşımları da irdeleyebiliriz.

Kirli İşler için Classifier Kullanın

Görüntü işleme uygulamalarında, bazen göze çok basit görünen işler, içinden çıkılmaz hale gelebilir. Threshold seçimi bunların başında gelir. Uygun bir threshold seçersiniz Diyelim ki var_threshold. 3-5 örnekte mükemmel çalışır, 1-2 örnekte teklemeye başlar, sonunda -öyle resimler çıkar ki- hiç çalışmaz 🙁 Neyse ki, HALCON var, moral bozmaya gerek yok. “Bir çok alternatif thresholding yöntemi sunuyor ne de olsa” özgüveniyle, hemen başka bir threshold seçilir. Mesela dynamic threshold. Sonuçlar baştan kontrol edilir. Eh, biraz daha iyi. Ama hala yakalanamayan örnekler var. İşin kötüsü, bazı resimlerde var_threshold iyi sonuç verirken, bazen de dyn_yhreshold iyi sonuç veriyor. Hangi durumda hangisini kullanalım? İkisinin sonucunu union yapıp denesek, bu kez de bazı istenmeyen durumlar çıkıyor. İstenmeyen durumları opening_circle vb. fonksiyonlarla elesek, sonra dilate etsek… derken bir bakmışsınız, yüzlerce satır HALCON kodu ile boğuşuyorsunuz.

Bu durum hemen hemen tüm görüntü işlemecilerin başına sık sık gelmektedir. Böyle bir durumla karşılaştıysanız, yanlış yoldasınız demektir, en iyisi önce bir mola verip şu klibi izleyin.

http://www.youtube.com/watch?v=y14_nLOi7YU

“Dirty deeds done dirt cheap”. Demek istediğimiz tam da bu. Kirli işler öyle kastırarak değil, (bizde) ucuz ve kolay yoldan halledilir.

Classifier Kullanımı :

Classifier belirgin 1 ya da 1 den fazla ortak özelliği bulunan nesneleri, bu ortak özelliklerine göre sınıflayarak seçmek için kullanılır. Örneğin bir resimdeki nesneleri, renklerine göre sınıflamak isteyebiliriz. HALCON a, bana bu resimdeki yeşilleri, mavileri, sarıları ver diyebilirim. Aksi halde, tek tek, farklı renklerin farklı threshold değerleri ile ilgilenmek zorunda kalacaktım. Ve bence işin en güzel yanı, bir örnek resim üzerinde, nesneleri tek tek göstrerek, mavi bu, yeşil bu, sarı bu, hadi bunları öğren, ve diğer resimleri verdiğimde, bana bu renkleri bu diyebilme kolaylığı.

Özetle, classifier yaygın olarak kullanılmalıdır. Çok düzgün ve güvenilir sonuçlar verir. Hızlı çalışır, iyi optimize edilmiştir. Sonuçlar kaydedilebilir / okunabilir vs.

 

Threshold seçimi ile uğraşıp 100 lerce satır HALCON kodunu silip, classifier kullanarak 3-5 satırla halledebileceğinizi görünce, ofisin içinde baştan sona Angus Young yürüyüşü yapacağınıza eminim. (yukarıdaki klibin ilk saniyelerinde. Angus Young yürüyüşü yapmayı bilmiyorsanız, buradan öğrenebilirsiniz. http://www.youtube.com/watch?v=MPBSKl9TpO8 (hayatımda böyle saçma video görmedim) )

Şimdi GMM classifier kullanan bir örnek verelim.

Bronz renkli metal plakanın üzerindeki kırmızı renkli çizgileri yakalayan bir görüntü işleme programı yazmamız isteniyor.
Klasik thresholding yöntemlerine göre elde ettiğimiz sonuçlar :

Yukarıdaki örnekte, yakalamak istediğimiz kırmızı çizgiler gayet başarıyla yakalanmış. (Etrafı yeşil ile çizilerek gösterilmiş). Fakat, kırmızı çizginin kalınlığı azaldıkça, kırmızı boyanın etkisi de azalmakta ve threshold kırmızıyı yakalamakta biraz zorlanmaktadır.

Yukarıdaki örnekte, uygulamamızın kırmızı çizgiyi kısmen yakaladığını ama tam istediğimiz gibi olmadığını görüyoruz.

Sonuçta, yukarıdaki gibi bazı örnekler için ise, kırmızı çizginin hiç yakalanamadığını görüyoruz. Kırmızı çizginin bazen yakalanıp, bazen yakalanamaması,

  • plaka yüzeyinde ışık şiddetinin değişken olması (sağ ve sol iyi aydınlanıyor, orta taraf iyi aydınlanmıyor)
  • Çizgi kalınlığının değişken olması (dolayısıyla ince çizgilerde kırmızı rengin belirsizleşmesi)
  • Zeminde lekeler açık koyu bölgeler olması
  • Bronz zeminin kendi içinde kırmızılık içermesi

gibi sebeplerden olabilir.

 

 

 

 

 

 

 

 

Yukarıdaki resim, yanlış threshold denemeleri ile boğuşurken, farketmeden hızlıca artmış HALCON kodlamasını gösteriyor.

GMM classifier kullanılarak yazılan aşağıdaki kod ise, tüm durumlarda %100 çalışarak istenen sonucu almamızı sağlamıştır.

 

set_display_font (3600, 16, 'mono', 'true', 'false')

list_files ('C:/Projects/Bronz/R', ['files','follow_links'], ImageFiles)
* list_files ('C:/Projects/SahinMotor/deneme 2/çapraz ışık/nok', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima)$','ignore_case'], ImageFiles)

* Red Region seçimi
read_image (Image, 'Reddic.jpg')
gen_rectangle1 (ROI_0, 198.172, 226.049, 485.801, 901.164)
reduce_domain(Image, ROI_0, ImageReduced)
decompose3(ImageReduced, R, G, B)
bin_threshold(G, RedRegion)
*

create_class_gmm (3, 1, 1, 'full', 'none', 3, 42, GMMHandle)
add_samples_image_class_gmm (Image, RedRegion, GMMHandle, 0)
train_class_gmm (GMMHandle, 100, 0.001, 'training', 0.001, Centers, Iter)
create_class_lut_gmm (GMMHandle, ['bit_depth','rejection_threshold'], [6,0.03], ClassLUTHandle)
clear_class_gmm (GMMHandle)

dev_set_color('blue')
for Index := 0 to |ImageFiles| - 1 by 1
    read_image (Image, ImageFiles[Index])
    reduce_domain(Image, ROI_0, ImageReduced)
    classify_image_class_lut (ImageReduced, ClassRegions, ClassLUTHandle)
    closing_circle(ClassRegions, RegionClosing, 3.5)
    area_center(RegionClosing, Area, Row, Column)
    if (Area > 500)
        disp_message(3600, 'KIRMIZI', 'image', 12, 12, 'red', 'true')
    endif
    stop()
endfor

Yazılımımız artık MODBUS uyumlu

Kameralı kontrol yazılımımız VYP, artık %100 Seri ve TCP modbus uyumlu.

Hem ModBus Slave, hem de ModBus TCP protokollerini tam destekleyen arabirimimiz ile, ModBUS protokolü üzerinden her tür çevre birim ile hızlı ve güvenli haberleşmek mümkün.

ModBus, Robot haberleşmesi, SCADA sistemleri, HMI, PLC, OPC vb. üniteler ile haberleşmek için geliştirilmiş bir endüstri standardıdır ve Mavis tarafından artık tam olarak desteklenmektedir.