Mustafa Sarı

Mustafa Sarı hakkında

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

uEye SDK kullanarak görüntünün Bitmap olarak alınması

iDS uEye Kameraları, güçlü bir SDK ile gelmektedir. Bu SDK, görüntünün kameradan düzgün bir şekilde alınabilmesi içindir. uEye Cockpit programında elle yapılan tüm işlemlerin kod ile (program) yapılabilmesi içindir. (Pozlama, kazanç, pixel clock, frame rate vs…)

Eğer uEye SDK düzgün olarak yüklenmişse, makinanızda IDS klasörü altında resimdeki gibi, tüm gerekli dosyalar klasörler olacaktır. Buradaki örneklere ve yardım dosyalarına göz atmakta fayda vardır. Unutulmamalıdır ki, uEye SDK, bir görüntü işleme kütüphanesi değildir. (bir HALCON değil mesela)

Bize .NET, Directshow, ActiveX ve yaygın görüntü işleme kütüphaneleri için interface ler sunar. Yani ben sana görüntüyü veririm, sen al ne yaparsan yap der.

Bazı iDS uEye kullanan müşterilerimiz, görüntüyü bitmap olarak almak ve bu bitmap olarak alınmış görüntüde pixel-pixel kendi algoritmalarını geliştirmek istemektedirler. Her ne kadar iç içe for döngüleri ile pixel-pixel çalışmak hayli zahmetli ve ilkel bir yöntem olsa da, çok basit ve zaman sorunu olmayan görüntü işleme uygulamalarında iş görüyor olabilir. Dolayısıyla, tüm bu yazının özeti, bize sık sorulan, iDS uEye kameralar kullanarak görüntüyü bitmap olarak nasıl alırım sorusuna bir cevap yazalım.

1 .NET interface kullanmak

Object Oriented mantığına göre geliştirilmiş .NET interface kullanmak en doğru yöntemdir.

Başlangıç olarak, uEye_DotNet_Simple_Live isimli C# uygulamasını açın. En temel fonksiyonları ve kullanımını basitçe göstermektedir.  Bunu çalıştırın. Herşey yolunda ise, çok küçük bir ekleme yapalım.

Bir PictureBox komponeti koyalım. (Bitmap nesnesini bunun üzerine atayacağız)

Şimdi Freeze butonuna aşağıdaki kodları ekleyelim.

            uEye.Defines.Status statusRet = 0;

            // Get last image memory
            Int32 s32LastMemId;
            Int32 s32Width;
            Int32 s32Height;
            statusRet = Camera.Memory.GetLast(out s32LastMemId);
            statusRet = Camera.Memory.Lock(s32LastMemId);
            statusRet = Camera.Memory.GetSize(s32LastMemId, out s32Width, out s32Height);

            Bitmap MyBitmap;
            statusRet = Camera.Memory.ToBitmap(s32LastMemId, out MyBitmap);

            // unlock image buffer
            statusRet = Camera.Memory.Unlock(s32LastMemId);

            pictureBox_bmp.SizeMode = PictureBoxSizeMode.StretchImage;
            pictureBox_bmp.Image = MyBitmap;

Görüldüğü gibi, Freeze() ile kamerayı video modundan çıkartıp stil image (sabit görüntü alma) moduna getirdim, ve kamera üzerindeki aktif görüntüyü bir bitmap değişkenine aldım. Sonra da onu pictureBox1 nesnesine atadım (siz dilediğiniz gibi kullanabilirsiniz)

Freeze() ile görüntüyü durdurabilir, Freeze(100) gibi bir komutla, 100 ms bekletebilirsiniz.

Ethernet kamera kullanıyorsanız, GetActive() , GetLast() vs deneyebilirsiniz. (Aktif olan görüntüyü değil de en sonuncusunu ver vs.)

ya da, henüz yeni görüntü oluşmamışsa (frame_rate 10 ise, 100 ms. de 1 yeni görüntü oluşacaktır gibi) bu durumda

Camera.Acquisition.Freeze(100)

gibi bir komutla, 100 ms beklemesini isteyebilirim. Uygulamaya göre değişir. sonuçta elimde Bitmap türünden görüntü mevcuttur artık.

2. dll kullanarak Bitmap olarak alma

(.NET çıkmadan önce yazdığım eski bir makaleydi bu. Orijinal haliyle bırakıyorum, .NET varken kullanılmasını çok da tavsiye etmem ama hala iş görür)

SDK ve uEye_api dll kullanımı için, Program Files altındaki IDS klasöründeki yer alan uEye_CSharp_Demo güzel bir örnek oluşturmaktadır. Burada, kameradan alınan görüntü (canlı ya da tek bir kare) .NET PictureBox bileşeni üzerinde gösterilmektedir. görüntüyü direk olarak PictureBox bileşeninin Handle ına atamak yerine Bitmap nesnesi olarak almak (ve işlemek) için, aşağıdaki kod kullanılabilir.

        private void button1_Click(object sender, EventArgs e)
        {
            Bitmap MyBitmap;

            // get geometry of uEye image buffer
            int width = 0, height = 0, bitspp = 0, pitch = 0, bytespp = 0;
            long imagesize = 0;
            m_uEye.InquireImageMem(m_pCurMem, GetImageID(m_pCurMem), ref width, ref height, ref bitspp, ref pitch);
            bytespp = (bitspp + 1) / 8;
            imagesize = width * height * bytespp; // image size in bytes

            // bulit a system bitmap
            MyBitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);

            // fill the system bitmap with the image data from the uEye SDK buffer
            BitmapData bd = MyBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            m_uEye.CopyImageMem(m_pCurMem, GetImageID(m_pCurMem), bd.Scan0);
            MyBitmap.UnlockBits(bd);

            //picShow.Image = MyBitmap;
            pictureBox2.Image = MyBitmap;

            //Bitmap may be saved to file if necessary
            MyBitmap.Save("uEyeImage.bmp");
        }

3. ActiveX kullanmak

ActiveX, VB6 ya da Delphi kullanıcısı iseniz mantıklı olabilir .Her ne kadar 2014 sonundan itibaren desteklenmese de (yeni versiyon ve bug fix vs gelmeyecektir),  iDS tarafından hala yürürlüktedir. En iyisi görüntüyü Save etmek, sonra Bitmap olarak load etmektir.

4. Görüntü İşleme Kütüphanesi kullanmak

Eğer HALCON kullanıyorsanız, kamerayı direk tanıyacak ve grab_image() komutu kameradan görüntüyü alıp size verecektir.

Hareketli Bir Nesnenin Yerinin, Hızının ve Doğrultusunun Belirlenmesi

Hareketli bir nesnenin (insan, araba vb. olabilir) nereye, hangi hız ve açıda hareket ettiğinin belirlenmesi, görüntü işleme teknikleri hızlı ve tutarlı olarak yapılabilmektedir. Bu konuya örnek olabilmesi açısından, masamda bir oyuncak robotu hareket ettirerek, kamera ile üstten bakıp fotoğraflarını aldım. 5 farklı pozisyonda aldığım bu fotoğrafları işleyerek her bir pozisyon için, bir öncekine göre hız ve açı değişimini hesapladım. (Normalde, bu işlem kameradan alınan görüntülerle canlı olarak yapılmalıdır.  İşlem mantığı tamamen aynı olacağı için, off-line yani dosyadan yüklenen resimler ile çalışıldı. HALCON kullanan herhangi biri, kamerası olmasa bile örneği çalıştırabilsin diye)

Aldığım 5 adet fotoğrafın yanyana görüntüsü aşağıdaki gibi. Kullandığım fotoğrafları buraya tıklayıp bilgisayarınıza indirebilirsiniz.

 

Gerçek hayattaki olabilecek uygulamalara benzemesi açısından, takip edeceğimiz robotun yanına, benzer renklerde engeller koydum. (Program bu engelleri eleyebilmeli) engellerin yerlerini her bir resimde değiştirdim. (Değişen arka zemin, farklı nesnelerin de görüntüye girmesi vb. durumlarda program doğru nesneyi takip edebilmeli)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Hareketli oyuncak robot ve ona tepeden bakan kameranın yerleşim görüntüsü. Robotun çevresine aynı renkteparçalar koydum (sistemin kafasını karıştırabilmek için). Robot engellere takılmadan yürüyecek ve biz de kamera ile robotun hareketini izleyeceğiz.

Şimdi işin HALCON kodlamasına geçelim.

Sistemin temel mantığı ardışıl olarak alınan 2 resmi karşılaştırmak ve aradaki farkları bulmak üzerinedir. HALCON daki sub_image fonksiyonu, 2 görüntüyü birbirinden çıkarır ve fark görüntüsünü geri döndürür. Kullanılan dual_threshold fonksiyonu sayesinde, hem eski pozisyonu hem de yeni pozisyonu ayrı iki bölge olarak elde ederiz. Bundan sonrası, engellerin ve görüntüye giren beklenmeyen nesnelerin elenmesi (select_shape) ve son olarak ta bulunan sonuçların ekranda listelenmesidir. Her bir hareket için, robotun eski konumu, yeni konumu, gidilen mesafe, dönülen açı hesaplanacaktır.

Önce tam HALCON kodunu verelim.

dev_set_line_width(1)
set_display_font (3600, 12, 'mono', 'true', 'false')
gen_empty_obj(Robots)
for Index := 1 to 4 by 1
    read_image (Image1, 'C:/Users/Mustafa/Desktop/' + Index + '.bmp')
    S := Index + 1
    read_image (Image2, 'C:/Users/Mustafa/Desktop/' + S + '.bmp')
    convert_image_type (Image1, ImageConverted1, 'int2')
    convert_image_type (Image2, ImageConverted2, 'int2')

    sub_image (ImageConverted1, ImageConverted2, ImageSub, 1, 0)
    dual_threshold (ImageSub, RegionDiff, 500, 20, 10)

    closing_circle(RegionDiff, RegionClosing, 3.5)
    select_shape (RegionClosing, SelectedRegions, ['area','height'], 'and', [40000, 250], [80000, 450])
    count_obj(SelectedRegions, Number)
    if (Number = 2)
        select_obj(SelectedRegions, FirstObject, 1)
        select_obj(SelectedRegions, NextObject, 2)
        if (Index = 1)
            concat_obj(Robots, FirstObject, Robots)
        endif
        concat_obj(Robots, NextObject, Robots)
    endif
endfor
* Display islemleri
* Katedilen mesafe (pixel cinsinden) ve doğrultu (açı) yazalım
dev_display(Image2)
dev_display(Robots)
dev_set_color('yellow')
area_center(Robots, Area, Row, Column)
count_obj(Robots, Number)
for Index := 1 to Number - 1 by 1
    disp_arrow(3600, Row[Index - 1], Column[Index-1], Row[Index], Column[Index], 5)
    distance_pp(Row[Index - 1], Column[Index-1], Row[Index], Column[Index], Distance)
    angle_lx(Row[Index - 1], Column[Index-1], Row[Index], Column[Index], Angle)
    tuple_deg(Angle, Deg)
    disp_message (3600, Distance$'.3' + ' px.', 'image', Row[Index-1], Column[Index-1], 'white', 'false')
    disp_message (3600, Deg$'.2' + ' derece', 'image', Row[Index-1] + 40, Column[Index-1], 'white', 'false')
endfor

Bu kod çalıştırıldığında elde edilen ekran görüntüsü ise aşağıdaki gibi olacaktır. Robotun son 5 hareketinde, nereden nereye gittiğini ve kaç derece dönerek hareket ettiğini gözlemlemek mümkündür. Otoyollarda kullanılan Radar sistemi doppler frekansı mantığına göre çalışmakla birlikte, kamera ile yapılan hız kontrollerinde bu ve benzeri yöntemler kullanılmaktadır.

Çoklu Karekod Okumada Gelişmiş Yöntemler – 1

Geliştirdiğimiz çoklu karekod okuma cihazı, gerçek zamanlı üretim ortamında (5 farklı ürün, 2 farklı hatta) test edilmiş ve %100 okuma başarısı sağlamıştır. Çoklu karekod okuma işlemi, kamera önündeki tüm karekodları okumayı gerektirdiğinden, gelişmiş okuma teknikleri kullanmak gerekmektedir. Üretim anında her bir karekod yazıldıktan sonra doğrulamasaı (verification) yapılmasına rağmen, shrink, koli, bandaj vb. yöntemlerle birleştirildiğinde, ışık açısı, kutunun dönmesi vb. sebeplerle bazı karekodlar okunamayacak ya da zor okunacak şekle gelebilir. Bu gibi durumlarda, “ileri” teknikler kullanarak, çoklu okuma işlemini %100 başarılı hale getirmek mümkündür.

Bu yazı  dizisinde, zaman buldukça Gelişmiş Yöntemler olarak adlandırdığım bu tekniklere ana başlıklar altında değinmeyi düşünüyorum. Özellikle ilaç üretimi yapılan yerlerde, okuma kalitesi kadar okuma hızı da çok önemlidir. (Karekod okuyacam diye üretimi durdurmanız/bekletmeniz düşünülemez) Dolayısıyla burada hem okuma kalitesini iyileştirecek hem de çok yüksek hızlarda okuma yapabilecek teknikler ele alınacaktır.

Mavis olarak, geliştirdiğimiz çoklu karekod okuma cihazı (konveyör, kameralar, sensörler, aydınlatma ekipmanı ve karekod basma makinasından meydana gelen cihaz) ile yaptığımız testlerde, 25 lik shrinkler için her bir shrink içindeki karekodları (her birinde 25 karekod olduğu durumda) okuma işlemi maksimum 1.5 sn. kadar sürmektedir. Okuma işlemi esnasında konveyör bu 1.5 sn. boyunca sabit olarak durdurulmakta, okuma işlemi bitince yeniden hareket ettirilmektedir. Konveyör çıkışında, okunan karekodlara ilişkin tek bir koli karekodu (master kod) üretilmekte ve kolinin / shrinkin üzerine basılmaktadır. Shrinkin konveyöre baştan girmesi ve en sondan çıkması arasındaki süre 4 sn. dir. (1.5 sn okuma, 2.5 sn. baştan sona yürüme)

Gelişmiş Yöntem – 1 : Okunamayan Karekodların tespiti ve sadece bu karekodları içerecek yeni bir resim alınarak yeniden denenmesi.

Karekodları içeren resim alındıktan sonra bazı durumlarda beklenen tüm karekodların okunamayabilir. Işık yansımaları, perspektif bozulmalar gibi etkenler, görüntünün tam orta noktasındaki karekod ile köşelerdeki karekodların farklı görünmelerine yol açabilir. Bu durumda, hemen pes etmeden önce çeşitli filtreler uygulayarak yeniden denemek gerekir. (Daha önceki bu makalede bahsedildiği gibi) Uygulanan filtrelere rağmen, hala bir ya da birkaç karekod okunamamış ise, şimdi yapılması gereken;

  1. Okunamayan Karekodların Yerlerinin Tespiti
  2. Tespit edilen yerlere göre AOI (Area of Interest) belirterek yeniden resim alınması
  3. Alınan resmin yeniden değerlendirilmesi

Burada püf noktası AOI belirtilmesidir. AOI, donanımsal olarak kameraya belirli koordinatların resmini al demektir. 10 Megapixel bir kamera ile çalışıldığını varsayalım. Tüm resmi almak 500 ms. kadar sürecekse, tek bir karekodun bulunduğu bölgenin resmini almak (değişebilir) 30-50 ms. kadar sürecektir. Böylece çok hızlı bir süre içinde sistem 2. 3. 4. denemelerini de yapar, gerçekten okunamayan bir kod var ise o zaman “NOK” olarak işaretler.

 

 

Yukarıdaki resimde sarı ile çerçevelenmiş tüm karekodların okunduğunu, kırmızı çerçeveli karekodun okunamadığını varsayalım. Okunamayan karekodun yeri HALCON find_barcode_2d fonksiyonu ile verilmekle birlikte, foundation fonksiyonları ile de belirlenebilir (Ben daha hızlı olması açısından, daha akıllı bir yapı kurarak, grid içinde okunamayan yerleri tespit eden bir yapı kurdum mesela) Şimdi yapılması gereken, bu karekodu içeren bir AOI kameraya bildirip yeniden fotoğraf almaktır.

AOI Bildirimi

open_framegrabber ('uEye', 1, 1, 0, 0, 0, 0, 'default', 8, 'default', -1, 'false', 'default', '1', 0, -1, AcqHandle)
count_seconds(T1)
grab_image(Image, AcqHandle)
count_seconds(T2)
set_framegrabber_param (AcqHandle, 'roi', [80,80,240,240])
count_seconds(T3)
grab_image(Image, AcqHandle)
count_seconds(T4)
FullGrabTime := (T2-T1)*1000
AOISetTime := (T3-T2)*1000
AOIGrabTime := (T4-T3) * 1000
close_framegrabber (AcqHandle)

Burada da kolayca görülebileceği gibi asıl işlem
set_framegrabber_param (AcqHandle, ‘roi’, [80,80,240,240]) fonksiyonu tarafından yapılmaktadır. Kendi makinamda bu kodu çalıştırdığımda; 1.3 MP kamera ile Full Grab (AOI verilmeden alınan resim) süresi : 118 ms.
set_frame_grabber için harcanan süre : 30 ms.
80-80-240-240 koordinatlarından resim almak için geçen süre : 20 ms.

olarak ölçüldü. Eğer 5 ya da 10 MP kamera kullanacak olsaydım, çok daha radikal zaman kazancım olacaktı.

Eş zamanlı olarak, her bir denemeden önce, kamera pozlama süresi bir miktar değiştirilebilir. Böylece ardışıl alınan her iki resmin birbirinden farklı olması sağlanır, varsa ışık parlamalarının önüne geçilmiş olunur.

Eğer işin içine bir miktar da bulanık mantık katılmak istenirse, pozlama miktarının değişimi sabit bir sayı ile değil, rastgele bir değer ile yapılabilir. Hala yeterli vaktimiz varsa, okuma metodolojisi “enhanced_recognition” ile zorlanır, pattern tolerance olarak “low” değeri denenir ve kod içinde yumuşatma fonksiyonu varsa mean_image yerine mean_curvature_flow ile değiştirilir. Threshold parametreleri yine bir miktar rastlantısal değerler ile ötelenir. İşlem tekrar denenir. (Bu şekilde sistem tarafından parametrelerin belirsiz bir şekilde zorlanarak tekrar denenmesi ve sonuçta başarıya ulaşılması, çoğu kez beni de heyecanlandıran bir durumdur. Mekanik bir sistem gibi OK/NOK vermek yerine, yapay zeka algoritması gibi çalışması, NOK durumunun üstüne gidilmesi ve beklenen süre içinde kalmak kaydıyla belirsiz zamanlarda OK diyebilmesi, test ya da demo esnasında gerçekten heyecanlı durumlara yol açabilmektedir.) Tam da bu arada, karekod okumaişlemi için timeout belirtmeyi de unutmamak gerekir. Yoksa HALCON hiç olmaması gerektiği kadar uzun oyalanabilir. Ben tüm proses için de timeout kullanıyorum. Şu alt programcığı 300 ms. içinde sonlandır gibi. (Birşeyler belirsiz olsun ama yine de sınırlar içinde kalsın)

Vakit buldukça burada karekod üzerine gelişmiş algoritmalardan bahsetmeye devam edeceğim. Bugünlük bu kadar. İletişime geçmek isteyenler için, info@mavis.com.tr mail adresini yeniden hatırlatayım…

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.

 

ARM Cortex A9 üzerinde çalışan HALCON

Gömülü HALCON dağıtımlarının ARM Cortex A9 işlemcileri üzerinde çalışabildiğinin açıklanması, yakın gelecekte çok tanıdık mobil cihazlarda HALCON görebileceğimiz anlamına geliyor.

ARM Cortex A9 kullanan mobil cihazlar listesi çok uzun olmakla birlikte (en yaygın kullanımı neredeyse her modemde yer alan Conexant işlemcileri) günlük hayatta bilinen bazı markaları listelemek istiyorum.

Apple iPhone 3GS, Palm Pre, Samsung i8910, Sony Ericsson Satio, Touch Book, Nokia N900 …

mobil cihazlarda gittikçe artan kamera ve ekran çözünürlüğü, geri planda çok hızlı ve hassas sonuçlar verebilecek bir engine kullanımını zorunlu hale getirmektedir. Bir önceki makalede de bahsettiğim gibi, teknoloji devi firmalar, tam da bu alana inanılmaz kaynaklar ayırmaktadır. Burada kişisel görüşüme göre; ARM gibi mobil işlemci piyasasının %75 ine hakim bir işlemciyi hedefleyen HALCON, bu sektöre taze bir kan getirecek ya da bazı ciddi kararların değişmesine sebep olabilecek gibi görünüyor.

HALCON Kinect Desteği

HALCON 10, test aşamasında olsa da MS Kinect ile 3D alanında başarılı çalışmalar yapmaktadır. Bilindiği gibi Kinect, Microsoft XBox oyun konsolları için geliştirilmiş, oyuncunun üzerinde herhangi bir kontrolör, kumanda ya da sensör olmaksızın tüm hareketlerini algılayabilen 3D kamera sistemidir.

HALCON un Kinect desteği sunması, oldukça ucuz ve yaygınlaşacağı neredeyse kesin olan 3D kamera seçeneği ile çalışabilmesi dışında daha derin anlamlar da içeriyor olmalı. Kişisel görüşüm, inanılmaz bir hızla yükselen oyun endüstrisinin MVTec yetkililerinin zaten uzunca bir süredir dikkatini çektiği yönünde. Nintendo Wii konsollarıyla başlayan etkileşimli oyun teknolojilerinin, Kinect ve benzeri ürünler ile iyice yaygınlaşması, bu cihaz üreticileri için HALCON kullanılabilmesi anlamına geleceği gibi, HALCON kullanıcılarının bu tür ucuz donanımlar ile profesyonel uygulamalar geliştirebileceği anlamına da gelir.

Üstelik, Microsoft un kendisi bile, Kinect görüntülerini algılayan akıllı yazılımlar için inanılmaz kaynaklar tüketirken, MVTec elindeki mevcut HALCON 3D görüntü işleme kütüphanesini Kinect uyumlu hale getirmek için hiç te sıradışı bir çabaya ihtiyaç duymayacak. Mevcut yapı zaten yeni framegrabber ve kamera arabirimleri için genişletilebilir durumda.

Başlangıçta Linux ve Windows işletim sistemlerini destekleyerek çoklu platformu hedefleyen HALCON, son zamanlarda ARM işlemcilerine verdiği güçlü destek ile ön plana çıkmaktadır. Nokia (belirli seri) desteğinden sonra bu atılımlar, yakın gelecekte HALCON u mobil cihazlar, oyun sektörü, ve günlük hayatın içinde çok daha fazla görebileceğimiz anlamına geliyor.

NASA gibi bir kurumun kendi görüntü işleme yazılımını bir kenara itip HALCON kullanmaya karar vermesi örneğini diğer teknoloji devi firmalar da izleyecektir. (Apple ın OpenGL için açık iş pozisyonlarını google dan aratın, gözlerinize inanamayacaksınız.)

Akıllı Şekil Tamamlama

Görüntü işleme uygulamaları, olabildiğince net ve düzgün görüntülerle çalışmayı sever. Bizim gibi, görüntü işleme ile endüstriyel ortamlarda çalışanlar, kaliteli ve bir görüntüyü garanti etmek için sistemin kurulumuna aşırı önem gösterirler. Gece/gündüz, yaz-kış, 24 saat çalışacak uygulamalar da alınan her görüntünün yeterli kalitede olması için aydınlatma ve çevre şartlarından izolasyon işlemleri özenle yerine getirilir. Her şeye rağmen, alınan tüm görüntüler beklenen kaliteyi sağlamayabilir.

İşte bu noktada, iyi bir görüntü işleme yazılımından beklentiler yükselir. Yazılım, değişen fotoğraf kalitesinde bile en iyi sonucu verebilmeli. “Akıllı şekil tamamlama”, kenar çizgileri eksik olarak alınmış fotoğrafların, kenar çizgilerini olması gerektiği gibi tamamlayan bir algoritmadır. Bol miktarda uygulama alanı mevcuttur. Örneğin bir önceki makalede, Defne Yapraklarının kalite kontrolünü incelemiştik. Bir yaprağın kenar çizgilerinin düzgün olup olmadığını anlamak için bu algoritma uygulanabilir.

Yaprak resmine benzer bu şekli Paint ile elle çizdim. Sonra kenarlarından bazı yerleri rastgele silerek, bozulma oluşturdum. Amacım bir algoritma ile bu boş yerleri tamamlayabilmek.

HALCON kodu aşağıdaki gibidir.

read_image (Image, 'C:/Users/Mustafa/Desktop/Yaprak.jpg')
edges_sub_pix (Image, Edges, 'canny', 1, 20, 40)
regress_contours_xld(Edges, RegressContours, 'no', 1)
union_collinear_contours_xld (RegressContours, UnionContours, 30, 10, 10, 0.2, 'attr_keep')

 

Bu 3 satırlık basit HALCON kodu çalıştırıldığında,  elde edilecek sonuç :

Soldaki gibidir. Bu çalışma da, contour processing yapılarak eksikliğin tamamlanması gösterilmiştir. close_edges, region_growing, sobel_amp gibi komutlar ve daha ciddi yapılanmalarla, oldukça karmaşık eksiklikler bile düzgün olarak tamamlanabilmektedir.

 

 

Defne Yaprağı Ayıklama Kontrolü

Ülkemizde bol miktarda yetişen defne yapraklarının, ayıklanıp sağlam olanlarının paketlenmesi ile birlikte, ekonomik değeri yüksek bir ürüne dönüşmesi mümkündür. Burada asıl maliyet, sağlam yaprakların bozuk (kırık, ezik, renksiz vb.) yapraklardan ayıklanmasını sağlamaktır. Üretici ya da toplayıcılardan çuvallarla getirilen yaprak, geliştirdiğimiz bir görüntü işleme uygulaması ile seri ve hızlı olarak ayıklanmaktadır.

Mavis olarak, defne yaprağı ayıklama projemizde, her tür yaprak hatalarına göre çalışan uygulamaya sahibiz. Binlerce yaprakla test edilmiş uygulamamız, en basit hatalardan en karmaşık hatalara kadar algılayabilmektedir. Bu yazı dizimizin devam eden sayfalarında, tüm sistemin çalışması detaylı olarak anlatılacaktır.

Sistem 2 bileşenden oluşmaktadır.

  1. Yaprakların konveyör üzerine tek tek dizilmesini sağlayan otomasyon sistemi
  2. Yaprakların sağlam olup olmadığını denetleyen kameralı kontrol sistemi.

Bu iki sistemden birincisi bir çok farklı şekillerde uyarlanabilir. Pnömatik döner borularla yaprakların hava ile emilmesi ve konveyör üzerine koyulması, aynı anda çok sayıda hava kanalcığının yaprakları emmesi ve ilerleyip konveyör üzerine bırakması vb. farklı alternatifler olabilir. Mavis olarak işin bu yanı ile fazla ilgilenmemekle birlikte, halihazırda çalışan otomasyon çözümlerine de sahibiz.

İşin yaprak ayrıştırma algoritması (sağlam ve bozuk yaprakların ayırt edilmesi) aşağıdaki şekilde çalışmaktadır.

1. Konveyör üzerinde giden yaprakların görüntüsünün alınması

Yapraklar hareket halinde olacağı için, olabildiğince kısa sürede fotoğraf almak gerekmektedir. Bu yüzden pozlama süresini en azda tutarak, güçlü bir aydınlatma kullanmak gerekmektedir. Yapraklar geniş bir yüzeye dağılmış ise fluoresan aydınlatma, dar bir kanaldan geliyor ise led aydınlatma kullanılabilir.

(Fluoresan aydınlatmanın daha uygun olacağı durum. Yüzey geniş ve tüm yüzeyi aydınlatmak fluoresan ile daha homojen olabilir)

(Yapraklar ardışıl bir kanalcıklardan gelmektedir ve tüm yüzey yerine belirli bir kanal aydınlatılabilir. Dolayısıyla power led kullanılabilir)

2. Alınan Görüntünün işlenmesi

Sistemin en hassas noktası burasıdır. Görüntü işleme uygulaması ile yaprakların sağlam ya da bozuk olup olmadığına karar vermek gerekmektedir.

2.1. Alınan Görüntüdeki Tüm Yaprakların Seçilmesi

Yeterince hızlı çalışan bir sistemde her bir fotoğraf karesine birden fazla yaprak girebilir. Bu durumda her bir yaprağın tek tek ayrıştırılması gerekmektedir. HALCON görüntü işleme kütüphanesi ile her bir yaprak ayrı bir nesne olarak ele alınır ve her bii için aşağıdaki kontroller tek tek sınanır

2.1.1 İçinde Delik bulunan yaprakların elenmesi

Burada kullanıcı yaprak içindeki deliği eleyebilmek için sabir bir rakam (3 mm2 gibi) ya da oran (%2) belirleyebilmektedir. Kullanıcı tarafından belirlenen değerden daha büyük bir delik belirlenmişse yaprak elenir.

2.1.2 Sağlam Yaprağa çok yakın hatalı yaprak varsa elenmesi

Bazı durumlarda sağlam yaprağı sistem ayrıştırırken, sağlam yaprağın çok yakınında bozuk yaprak varsa, o yaprak ta sağlam sepetine gidebilmektedir. Bunu önlemek için sağlam yaprağa çok yakın hatalı yaprak varsa her ikisinin de elenmesi istenebilir (Ne de olsa hatalı yaprakları sistemden 2. kez geçirmek mümkün)

2.1.3 Bir tarafı eksik yaprağın elenmesi

Mavis tarafından matematiksel modellemeye göre geliştirilen görüntü işleme kodu, yaprağın silüetini akıllı olarak tamamlayıp, herhangi bir yerde silüetten farklılık varsa (eksiklik, kopukluk, kırıklık, içe katlanma vb.) yaprağın bozuk olarak elenmesini sağlamaktadır.

Uzak Lokasyondan Alınan Görüntünün İşlenmesi

Bilgisayarlı görüntü işleme projeleri, kameradan alınan görüntünün bilgisayar tarafından işlenmesi ve değerlendirilmesiyle oluşmaktadır. Kamera bilgisayara ne kadar uzaklıkta olabilir? Eğer USB kamera kullanılıyorsa, max. 8m, Ethernet kamera kullanılıyor ise ağ altyapısının topolojisine göre ortalama olarak max bir kaç yüz metre olarak düşünülebilir. Peki bu mesafelerin yetersiz olduğu durumlarda, görüntü aktarımı nasıl yapılabilir? Örneğin, “Orman yangını erken uyarı sistemi”, “Fotokapan”, “tetiklemeli görüntü aktarımı” gibi bir görüntü işleme projemiz olsun. Ormanın ortasındaki kamera kilometrelerce ilerideki merkezi işlem birimine görüntüyü nasıl aktarabilir? Yoksa, ormanın ortasında bilgisayar,  besleme (elektrik bağlantısı) vb. bir istasyon mu kurmak gerekir? (Her zaman pek akıl karı değil)

Bu ve benzeri tüm durumlar için, “Uzak Lokasyondan Görüntü Aktarılması” kullandığımız Keymile modemleri tanıtmak istiyorum. Keymile modemler görüntü aktarma dışında bilgi (input/output) ta aktarabildiği için, uzak alan aktarım projelerinde anahtar rol oynamaktadır.

Uzaktan Alınan Görüntünün İşlenmesi Projesi :

Uzak Lokasyondan Alınan Görüntünün İşlenmesi

Bu projemizde internet üzerinden aldığımız görüntü verilerinin işlenmesini gerçekleştirdik. Projenin diğer projelere göre tek farkı görüntüyü işleyen bilgisayar ile kameranın farklı lokasyonlarda olmasıydı. Görüntü verileri internet üzerinden görüntüyü işleyecek olan bilgisayara aktarıldı. İnternet için Türk Telekom’dan 2 Mb/s band genişliğine sahip kiralık hat (Leased Line) aldık ve bu hattın çalışması için AVD Teknolojiden tedarik ettiğimiz Keymile marka SHDSL modemleri kullandık. Bu projede kiralık hat kullanmamızın sebebi kiralık hatların, ADSL veya G.SHDSL hatlarına göre göre daha stabil çalışmasıdır. Keymile marka SHDSL modemler ile PRI hat uygulaması da gerçekleştirebilirsiniz.