Mustafa Sarı

Mustafa Sarı hakkında

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

Mavis Targovishte’de

Mavis Yapay Görme Ekibi, Bulgaristan Targovishte deki bir tesiste, kameralı kontrol kurulumu için yerinde çalışmalar yaptı. 1 gün boyunca süren çalışmalarda, üretim esnasında ve laboratuvar ortamında birçok farklı tip ürün üzerinde çalışılarak sonuca varıldı. Yapılan çalışmalar, proje sahibine rapor olarak sunulacaktır. Proje gerçeklenme aşamasında, daha detaylı bilgi verilecektir.

Mavis, Bugün Bulgaristanda kurulumunu yaptığı bir diğer proje olan robot kontrollü kameralı kontrol sisteminin kontrol ve iyileştirme çalışmalarına devam etmektedir.

Mavis İzmir’de

Mavis, Kameralı Yaprak Kontrolü makinasının montaj ve ilk testleri için İzmirde.

14 Haziran itibariyle, İzmirde sıcaklık : 34 derece.  Öğle saatlerinde 40 a yaklaşacağı söyleniyor.

(Müşteri Bilgi Gizliliği politikamız gereği, yapılan çalışma ve teknolojisi hakkında daha fazla bilgi verilmemiştir)

VYP ye Yeni Bir Standart Kontrol

Mavis VYP Kameralı Kontrol Yazılımı standart kontrollerine yeni bir tane daha eklendi : Parça Yönelimi.

Mavis VYP de, kameralı kontroller 3 gruba ayrılır.

  • Standart Kontroller
  • Projeye Özgü Kontroller
  • Gelişmiş Kontroller

Bir projenin sadece standart kontroller kullanılarak gerçeklenmesi en ideal durumdur. Projeye özgü kontroller bazı durumlarda kaçınılmaz olabilir. VYP, standart kontrol setini zenginleştirerek Projeye özgü kontrolleri olabildiğince minimuma indirgemiştir.

Standart kontrol kullanmanın avantajları

  • Kod yazımına gerek kalmaz
  • Defalarca test edilmiş olduğundan hatalara açık değildir
  • İyi Dökümante edilmiş ve eğitimlerde anlatılmış olduğundan kullanıcılar kolay uyum sağlar
  • Modüler / parametrik  olduğundan zahmetsizce uyarlanabilir
  • Güncelleştirmeler veya arayüz iyileştirmelerinden var olan tüm kurulumlar ek işlem yapılmaksızın yükseltilmiş olur

Parça Yönelimi :

Bu kontrol, sıkça karşılaştığımız “ters yönde takılmış” parçaları yakalamaya yarar. Kullanıcı arayüzü oldukça basittir.

Zorunlu kullanıcı seçimleri

  • bağlantı noktası (_juncPoint)
  • parçanın doğrultusu (_partDirection) Yatay / Dikey
  • parçanın beklenilen yönelimi (_expectingOrientation) Sol / Sağ / Üst / Alt

Opsiyonel kullanıcı seçimleri

  • Yaklaşma dörtgeninin kenar uzunluğu (_juncHeight) Varsayılan Değer : 10

Böylece sadece 3 seçimle birlikte kullanıcı parçanın olması gereken yönü sisteme kolayca bildirmiş olur.

(VYP Parça Yönelimi İçeren Kontrolleri Çalıştırıyor)

VYP Ekranında %800 zoom edildiğinde, parçanın yönelimi görülüyor.

Yönelim kullanıcının beklediği doğrultuda ise yeşil ok, aksi halde kırmızı ok (ters istikamete) ekranda belirecektir.


Yeni kontrolün C# kodlaması :

 

		private bool CheckDirection(JobDefs job)
		{

			if (masterFailed)
			{
				DrawCurrentRoi(job, false);
				return false;
			}

			HObject ho_ImageReduced;
			HObject ho_Region, ho_SelectedRegions, ho_Open, ho_Rect;
			HTuple hv_R1, hv_C1, hv_R2, hv_C2;

			bool retval = false;

			// Initialize local and output iconic variables 
			HOperatorSet.GenEmptyObj(out ho_ImageReduced);
			HOperatorSet.GenEmptyObj(out ho_Region);
			HOperatorSet.GenEmptyObj(out ho_SelectedRegions);
			HOperatorSet.GenEmptyObj(out ho_Open);
			HOperatorSet.GenEmptyObj(out ho_Rect);

			ho_ImageReduced.Dispose();
			if (imagesource.ReduceJobDomain(job, out ho_ImageReduced))
			{
				ho_Region.Dispose();
				imagesource.ApplyThreshold(job, ho_ImageReduced, out ho_Region);

				if (job.ValDouble("area") > 0)
				{

					ho_SelectedRegions.Dispose();
					imagesource.ApplySelection(job, ho_Region, out ho_SelectedRegions);

					int openR = job.VarInt32("OpeningRadius", 1);
					ho_Open.Dispose();
					HOperatorSet.OpeningCircle(ho_SelectedRegions, out ho_Open, openR);

					imagesource.DisplayObj(ho_Open, "blue");

					// Yaklaşma Bölgesini oluşturalım
					HOperatorSet.SmallestRectangle1(ho_Open, out hv_R1, out hv_C1, out hv_R2, out hv_C2);
					int tutamac = job.VarInt32("_juncPoint", 3); //L R U D
					int rHeight = job.VarInt32("_juncHeight", 10); // Yaklaşma Dörtgeninin Yüksekliği
					int yonelim = job.VarInt32("_partDirection", 0); // Horizontal, Vertical
					int beklenenYon = job.VarInt32("_expectingOrientation", 0); // L R U D

					if (tutamac == 0) // Soldan tutturulmuş				
						HOperatorSet.GenRectangle1(out ho_Rect, hv_R1, hv_C1-rHeight, hv_R2, hv_C1);
					else if (tutamac == 1) // Sağdan tutturulmuş				
						HOperatorSet.GenRectangle1(out ho_Rect, hv_R1, hv_C2, hv_R2, hv_C2 + rHeight);
					else if (tutamac == 2) // Üstten tutturulmuş				
						HOperatorSet.GenRectangle1(out ho_Rect, hv_R1 - rHeight, hv_C1, hv_R1, hv_C2);
					else if (tutamac == 3) // Alttan tutturulmuş				
						HOperatorSet.GenRectangle1(out ho_Rect, hv_R2, hv_C1, hv_R2 + rHeight, hv_C2);

					imagesource.SetColor("yellow");

					ho_ImageReduced.Dispose();
					HOperatorSet.ReduceDomain(imagesource.Image, ho_Rect, out ho_ImageReduced);

					ho_Region.Dispose();
					if (imagesource.ApplyThreshold(job, ho_ImageReduced, out ho_Region))
					{
						double yRow = job.ValDouble("row"); // yaklaşma Row
						double yCol = job.ValDouble("column"); // yaklaşma col

						HOperatorSet.DispCross(imagesource.DisplayHandle, yRow, yCol, 12, 0);

						if (yonelim == 0) // Yatay bir parça ise
						{
							double pC1 = TupleToDbl(hv_C1);
							double pC2 = TupleToDbl(hv_C2);

							double lFark = Math.Abs(pC1 - yCol); // merkez ile sol noktanın farkı
							double rFark = Math.Abs(pC2 - yCol); // merkez ile sağ noktanın farkı

							//imagesource.SetColor("blue");
							if (beklenenYon == 0) // Soldan bekleniyor
							{
								retval = lFark > rFark; // Solda bekleniyordu, geldi.
								imagesource.SetColor(retval ? "green" : "red");
								if (retval)
									HOperatorSet.DispArrow(imagesource.DisplayHandle, yRow, yCol, yRow, hv_C1, 1);
								else
									HOperatorSet.DispArrow(imagesource.DisplayHandle, yRow, yCol, yRow, hv_C2, 1);

							}
							else if (beklenenYon == 1) // Sağdan bekleniyor
							{
								retval = rFark > lFark;
								imagesource.SetColor(retval ? "green" : "red");								
								if (retval)
									HOperatorSet.DispArrow(imagesource.DisplayHandle, yRow, yCol, yRow, hv_C2, 1);
								else
									HOperatorSet.DispArrow(imagesource.DisplayHandle, yRow, yCol, yRow, hv_C1, 1);
							}
						} 
						else  // Dikey Parça
						{
							double pR1 = TupleToDbl(hv_R1);
							double pR2 = TupleToDbl(hv_R2);

							double uFark = Math.Abs(pR1 - yRow); // merkez ile üst noktanın farkı
							double dFark = Math.Abs(pR2 - yRow); // merkez ile alt noktanın farkı

							if (beklenenYon == 2) // Üstte bekleniyor
							{
								retval = uFark > dFark;
								imagesource.SetColor(retval ? "green" : "red");
								if (retval)
									HOperatorSet.DispArrow(imagesource.DisplayHandle, yRow, yCol, hv_R1, yCol, 1);
								else
									HOperatorSet.DispArrow(imagesource.DisplayHandle, yRow, yCol, hv_R2, yCol, 1);
							}
							else if (beklenenYon == 3) // Altta bekleniyor
							{
								retval = dFark > uFark;
								imagesource.SetColor(retval ? "green" : "red");
								if (retval)
									HOperatorSet.DispArrow(imagesource.DisplayHandle, yRow, yCol, hv_R2, yCol, 1);
								else
									HOperatorSet.DispArrow(imagesource.DisplayHandle, yRow, yCol, hv_R1, yCol, 1);
							}

						}
						PutLog(job, retval, "Parça Beklenen Yönde " + (retval ? "Geldi" : "Gelmedi"));
					}

				}
				else RedLog(job, "Seçili Bölg Bulunmamadı!");
			}
			else RedLog(job, "ROI indirgenemedi!");

			ho_ImageReduced.Dispose();
			ho_Region.Dispose();
			ho_SelectedRegions.Dispose();

			int compela = job.VarInt32("Complement", 0);
			if (compela == 1) retval = !retval;

			if (!retval)
			{
				DrawCurrentRoi(job, retval);
				int masterJob = job.VarInt32("MasterJob", 0);
				if (masterJob == 1)
					masterFailed = true;
			}

			return retval;
		}

Tek Lokasyonda 10 Farklı Kameralı Kontrol İstasyonu


Mavis, Volkswagen yan sanayilerinden Kros Otomotiv Kütahya fabrikasında, 10. kameralı kontrol istasyonunu kurmaya hazırlanıyor.

Fabrika genelindeki kameralı kontrol istasyonlarımıza ilişkin ortalama rakamlar…

  • Çalışan 7, Yapım aşamasında 3 istasyon mevcuttur
  • Her bir istasyonda ortalama 4 kamera bulunmaktadır
  • En az kamera sayısı olan istasyonda 2 kamera bulunmaktadır
  • En çok kameralı istasyon ise 7 kameralıdır
  • Her bir istasyonda ortalama 4 farklı çeşit (tip) ürün kontrol edilmektedir.
  • Her istasyon 3 vardiya çalışmaktadır

Böylece Kros Otomotiv 10 farklı istasyon ile en çok kurulum yaptığımız yer olmuştur. Kros Otomotiv’i, B/S/H/ ve Renault ve Derby izlemektedir.

Kros Otomotiv’de kurulu istasyonlarımızdan görüntüler…

Bir görevi belirli bir zaman sonra çalıştırma

Bir görevi belirli ve kesin bir süre sonra çalıştırmak gerekirse ne yapılır?

En basit yöntem, bir Timer kurmak ve bu Timer ın interval değerini belirli değere set ederek TimerTick olayında görevin çalışmasını tetiklemektir.  Daha komplex uygulamalarda bu yöntemi kullanmak zahmetli ya da sorunlu olabilir (Genelde de olur).

Böyle durumlarda thread kullanmak ve thread çalışması için belirli bir zaman atamak daha profesyonel bir yaklaşımdır. .NET halihazırda thread tetiklenmesi, bekletilmesi, sonlandırılması vb. işlemler için güçlü API desteği sunar.

Kameralı Kontrol uygulamamız, yakaladığı hatalı parçayı bir t süre sonra üflemek suretiyle konveyörden atacak olsun.

		public void UfleP(int t)
		{
			System.Threading.Thread.Sleep(t);
			SetDigitalOutput(1);
		}

gibi bir kod çalıştırıldığında, sistem t süresi kadar bekleyecek sonra dijital output set etmek suretiyle üfleme yapacaktır. Bu kod, bekleme süresinde (Sleep) sistemi uyutacağından, görüntü işleme uygulamalarında akla bile getirilmemelidir. Yapılması gereken, bu fonksiyonu çağıran yapıyı bir thread haline getirmek, thread i start edip unutmak, thread kendi içinde beklese bile ana programın bundan hiç etkilenmemesini sağlamaktır. Thread çalışırken bekleyecek, görevini yapacak ve en nihayetinde kendi halinde  sonlanacaktır (Terminate). Tüm bu olan bitenden ne ana programın, ne de programcını haberdar olması bile gerekmez. (Tam ideal durum. Yaz ve unut. Hiçbir Timer bu kadar kullanışlı olamazdı.)

Burada bir sorun, thread için parametre geçirmektir. Normal thread çağırırken parametre kullanımına izin vermez. Parametre kullanımı için ParameterizedThreadStart kullanmak gerekir.

Yapıyı yeniden kodlarsak;

		public void UfleP(object t)
		{
			int iSleep = (int)t;
			System.Threading.Thread.Sleep(iSleep);
			SetDigitalOutput(1);
		}

şekline dönüştürerek (parametrenin object türünden olduğuna dikkat edin. Dolayısıyla birden fazla parametre vermek, dizi geçmek vb. object türünün sağladığı sınırsız avantajlar burada kullanılabilir…)

		private void PickAfterMilliSecond(int msAfter)
		{
			System.Threading.ParameterizedThreadStart starter = new System.Threading.ParameterizedThreadStart(UfleP);
			new System.Threading.Thread(starter).Start(msAfter);
		}

gibi bir yapı ile, Parametrik Thread yapımızı programda istediğimiz yerden çağırabiliriz. Dertsiz tasasız çalışacaktır…

Delphi içinden uEye Kamera Kullanımı

iDS uEye kameralar, son derece güçlü bir SDK ile birlikte gelmektedirler.  Güçlü yanlarını genel başlıklar altında toplarsak

  • 32 bit ve 64 bit işletim sistemleri için %100 destek
  • Tüm platformlar için %100 destek (Native Windows, .NET, Linux, Web)
  • ActiveX, OCX bileşenleri olarak kullanabilme
  • Native .NET kütüphanesi
  • Tüm görüntü işleme arabirimleri (HALCON, neurocheck, cognex…)
  • Birçok derlenmiş ve çalışan örnek uygulamalar

vb. sayılabilir.

.NET ortamında uygulama geliştirmek için, C# ve onun güçlü IDE si VS yi kesinlikle tavsiye ederim. Buna rağmen, Delphi ile uygulama geliştirmenin cazibesi de hala devam etmektedir. Bunları da kendime göre kısaca sıralarsam;

  • En hızlı Native Win32 uygulama
  • Delphi 1 den itibaren standartlaşmış güçlü ve oturmuş IDE
  • ObjectPascal dilinin getirdiği güç artı kolaylık
  • Birçok VCL, hazır kod, library vb. vb.
  • Açıklanamayan Delphi bağlılığı/sevgisi

Delphi 1 den Delphi 2010 versiyonuna kadar Delphi kullanmış biri olarak, laf açılmışken susmam son derece zor olduğundan, lafı burada keserek, Delphi içinden uEye kameralarının kullanımına geçiyorum.

1. Öncelikle uEye Driverları ve programları Full olarak kurulur. (www.ueyesetup.com)

2. uEye Demo programı ile kameranın düzgün olarak çalıştığı test edilir.

3. Şimdi Delphi Çalıştırılır (Resimler Delphi2009 programından alınmıştır. Delphi5 ten itibaren aynı mantık geçerli olduğundan tüm versiyonlar için burada anlatılanlar geçerli olacaktır)

ilk iş olarak, diğer tüm ActiveX bileşenlerinde olduğu gibi, uEye ActiveX bileşeni Delphi içinden yeni bir component olarak install edilir.

Bunun için Component ana menüsünden, “Import Component” menü öğesi seçilir. Gelen ekranda “Import ActiveX Control” radio button işaretlenir ve aşağıdaki ekran gelir.

Bu ekranda uEyeCam ActiveX Control bulunur ve istenilen Delphi component paletine yüklenir. (Ben Additional sekmesini seçtim. ActiveX ya da System gibi palet ler daha okunaklı görünebilir. İStediğinizi seçebilirsiniz zaten, dilerseniz yeni bir palet te oluşturabilirsiniz)

Sonraki ekranda Create New Unit” seçerek ilerledim ve nihayetinde Deplhi bana yeni ActiveX bileşenimin Additional paletine başarıyla yüklendiğini söyledi.

Artık delphi içinden kullanıma hazırım.

Normal form tasarlar gibi çalışıyorum artık. Additional paletinden uEye ActiveX bileşenini formun üzerine koydum ve istediğim gibi ölçeklendirdim.

sonrasında işime yarayacak bazı butonlar koydum. Kamera Aç, Kapat, Resmi Farklı Kaydet vb. gibi.

“Yükle” butonuna

uEyeCam1.InitCamera(0);

kodunu ekliyorum. Ve daha fazla kod yazmadan hemen F9 a basıyorum ve ta taaa… Yine Delphi hızı ve mucizesi ekranda beliriyor…

Dilersem, fotoğrafı farklı kaydetmek için;

uEyeCam1.SaveImage(”);

kodunu kullanabilirim. Parametee olarak ” kullanırsam, kaydedeceğim yeri seçmem için Save Dialog görüntülenecektir. Belirli bir yere kaydetmek istiyorsam, bunu parantez içinde belirtmem yeterlidir.

Kamera ile işim bittiğinde (Formu kapatırken vs.)

uEyeCam1.ExitCamera;

kodunu çağırmam yeterli olacaktır.

Hepsi bu kadar kolay…

uEye ActiveX bileşeninin yüzlerce fonksiyonu mevcuttur ve bunlar Help kısmında son derece detaylı açıklanmıştır. İhtiyaç duyulabilecek hemen her fonksiyon gerçek bir Alman mühendisliği inceliğiyle kodlanmıştır. Programcıya son derece kolay bir kodlama işi kalmış, geliştirilen uygulama diğer Delphi uygulamalarında olduğu gibi, “En Hızlı” ve “En Şık” olarak harddisk te yerini almıştır.

Bir tüyo : Ekranda karşınıza çıkan default iDS uEye görüntüsünden hoşlanmıyorsanız, kendi marka ve logonuzu içeren bitmap dosyayı C:\Windows\System32 klasörüne uEyeCamOcx.bmp ismiyle kaydedin 😉

Uygulama başlar başlamaz sizi bu ekran karşılayacaktır.

Mavis Kütahya’da

Yeni kameralı kontrol masaları kurulumları ve eski kurulu sistemlere bakım amacıyla Mavis teknik personeli bugün Kütahya Kros Otomotivde bulunmaktadır.

Yapılacak Çalışmalar

  • Barkod yazıcıların yeni etiket formlarının uyarlanması
  • Yeni 2 kameralı kontrol masasının montajı ve devreye alınması
  • Eski hatlarda bakım ve kontrol yapılması

Arçelik Çamaşır Makinesi Soket Kontrolü

Mavis, Arçelik Çayırova kampüsündeki çamaşır makinası üretim tesislerinde kameralı kontrol uygulamalarını devreye aldı.

Yapılan Kontroller

  • Soket Varlık Kontrolü
  • Soket Pozisyon Kontrolü

Program, üretim hattında %100 kontrol esasına göre çalışmaktadır. Hatalı üretim görüldüğünde sesli ve görsel ikaz ile operatörü bilgilendirmektedir.

Soket hatalı takılmış (Tam yerine oturmamış)

Soketler düzgün olarak takılmış

Projenin Zorlukları :

  • Takılan soketlerin ve zeminin beyaz renkte olması
  • Soketin yerine tam oturmaması durumunda aradaki farkı algılamanın zor olması

Lazerli Kameralı Derinlik Ölçüm Sistemi

Mavis, kendi bünyesinde geliştirdiği yeni bir cihaz olan “Lazerli Kameralı Derinlik Ölçüm Sistemi” ismini verdiği cihazı kullanıma almıştır. Yaklaşık 1 ay önce geliştirilen sistem, 2 – 3 haftalık test ve kalibrasyon sürecinden sonra devreye alındı.

Cihazın Amacı

Cihaz, kesilerek açılan derinliğin hassas olarak ölçülmesine yarar. Bir endüstriyel bıçak tarafından yarıklık şeklinde açılan kesik, kumpas cetvel ya da bilindik yöntemlerle ölçülemeyeceği için, Mavis tarafından geliştirilen bu aparat ile hassas olarak ölçülebilmektedir.

Cihazın Çalışma Şekli

Cihaz, kesiklik derinliği ölçülecek olan parçanın (çalışılan uygulama mukavva konilerdir) cihaza yerleştirilmesiyle başlar. Yerleştirme esnasında, parçanın en üst düzeyinin sabitleneceği bir nokta vardır. Yüksekliği ayarlanabilen zemine yerleştirilen parça, en üst noktada bu sabit yüzeye getirilir. Böylece kamera tek bir noktaya focus (netlik) olabilir. Kesikliğin bulunduğu yere düşürülen çizgi lazer, yüzey boyunca düz bir çizgi halinde görünürken, kesikliğin olduğu yerde içe doğru V şeklinde girer. Yüksek çözünürlüklü, megapixel lense sahip kamera ile alınan dijital görüntü, Mavis VYP yazılımı tarafından işlenir. Online olarak yapılan işleme sonucu, derinliğin boyu, 0.8 mm ve 1 mm aşağıdaki yarık kalınlığı vb. parametreler otomatik olarak bulunur. Bunların dışında kullanıcı dilerse manual olarak istediği noktalar arasında ölçüm yapabilir.

Laser düşürülmüş kesikliğin kamera görüntüsü ve kesiğin otomatik olarak ölçümü

Projenin Zorlukları

Kalibrasyon : Elle ya da muadil bir cihazla ölçüm yapılamadığından sistemi kalibre etmek için bir yöntem geliştirildi. Matematikse modellere ve tekrarlanabilir değerlere dayanan bu modele göre sistem kalibre edildi.

Kamera ve Lazer Pozisyonu : Lazer ışığının tam kesiklik yarığına düşürülmesi, kameranın belirli bir açıdan bu kesikliğe bakması ve hem lazer hem de kameranın olması gereken kesin açı pozisyonlarının hassas olarak belirlenebilmesi.

Otomatik Ölçüm : Program kalibre edildikten sonra, isterler doğrultusunda tüm ölçümlerin otomatik olarak yapılabilmesi istenmektedir.

Manual Ölçüm : Kullanıcı dilerse kendi belirleyeceği noktalar arasında hassas ölçüm yapabilmeyi istemektedir. Programın buna izin verecek şekilde kalibre edilmesi sağlanmıştır.

Sonuçların Değerlendirilmesi : Tüm ölçüm sonuçları istatistiksel olarak değerlendirilebilir, raporlanabilir, veritabanına kaydedilebilir özelliktedir. Mavis VYP de zaten var olan altyapı kullanıldığından tüm bu istekleri yerine getirmek Mavis için zor olmamıştır.

Programın otomatik hesaplama işlevinin yanısıra, kullanıcı tarafından 2 farklı şekilde manual ölçüm yapılabilir.

  • Çok tıklayarak ölçüm
  • Doğru çizerek ölçüm

Her iki yöntemde de kullanıcı, ekranda dilediği noktalar arasında ölçüm yapabilir. Sistem kolay ölçüm yapılabilmesi amacıyla, lazer çizgisinin başlangıç ve bitiş klavuzlarının sınır yerlerini çizer.

Program, kullanıcıya yardımcı olması açısından görüntü filtreleme seçeneğini kullanır. Bu seçenek, alınan görüntünün filtrelenerek, bir nevi temizlenerek sunulması işlemine yarar. Kullanıcı dilerse bu özelliği devre dışı bırakır ve salt görüntü üzerinden çalışabilir.