Mustafa Sarı

Mustafa Sarı hakkında

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

uEye için yeni HALCON arabirimi

HALCON uEye SDK nın 3.5 ve sonraki versiyonlarına uygun yeni bir arabirim (interface) çıkardı. Bilindiği gibi uEye gerek yenmi çıkardığı kameralar, gerek SDK sında yaptığı yeniliklerle 3.5 ve sonrası versiyonlarda (halihazırdaki son versiyon 3.70) büyük yenilikler getirmişti.

Bu yeni fonksiyonlar ve modellere HALCON içinden erişebilmek adına, yeni bir arabirim (interface) yayımlanması gerekiyordu ve 30 Ağustos itibariyle bu arabirim yayımlandı.

Mavis olarak, uEye kameralarına erişmek amacıyla, direk uEye ayar dosyası (ini) file ile çalıştığımızdan, bizim uygulamalarımız zaten uEye SDK nın yeni özelliklerini kullanabiliyordu. Bu yeni arabirim, uEye kameralarına HALCON un get_framegrabber_param ve set_frame_grabber_param fonksiyonlarını kullanarak erişen kullanıcılar için anlamlı olacak.

Yeni arabirim, kayıtlı (registered) kullanıcılar için MVTec web sayfasından ücretsiz indirilebilir.

Delphi XE yeni bir şans olabilir mi?

Delphinin en son versiyonu olan Delphi XE (RAD Studio XE) raflarda yerini aldı. Programın 30 günlük deneme sürümünü kurup, yeni (ya da daha da geliştirilmiş) özelliklerine göz attığımda Delphi XE nin gerçekten son derece gözalıcı özelliklerle donatıldığını gördüm. 64 bit derleyiciler hariç, hemen hemen her başlıkta eksiksiz bir ürün çıkartılmış.

Bunlara başlıklara kısaca değinirsek

Derleyici : En büyük değişim, delphi derleyicisinin ANSI C++ derleyicisi ile çok daha uyumlu hale getirilmiş olmasında görülmektedir. Yeni nesil işlemciler (SSE4.x, AMD 3DNow vs.) için uyumluluk ve artırılmış performanstan bahsedebiliriz. Derleme işlemi artık arkaplanda bir thread tarafından yapılabiliyor. (Çok büyük projelerde, saatler süren derlemeleriniz varsa, işe yarar bir özellik şüphesiz)

Geliştime Ortamı : Artık Delphi geliştiricileri Visual Studio 2008 / 2010 veya MonoDevelop içinden geliştirme yapabilecekler. (Radikal bir değişiklik olmakla birlikte kimin bu şekilde kullanacağını da merak ediyorum. Çok değil, birkaç sene önce IDE savaşlarından bahsedenler şimdi en güçlü silahlarını almadan savaş meydanına mı çıkıyor?) Birde beklendiği üzere, Win32 SDK, Windows 7 API ve .NET 4.0 da tam desteklenmektedir.

Dilde Yapılan Yenilikler : Kişisel olarak en çok beğendiğim özellik, Exit derken artık opsiyonel olarak Result değerini de set edebiliyoruz. (C# taki return false, return 3 vb. kullanım gibi) Bunların dışında, RegEx (Regular Expression) library kullanımı artık – çok geç kalınmıl olsa da- mümkün. Dosyalama ve I/O işlemlerini yapmak için kullanılan eski tarz fonksiyon bazlı yapı artık OOP çatısına kavuşturulmuş. Yine C++ uyumlu object sınıfının ToString metodları, Unicode destekleri ve TStringBuilder gibi (yine C# tan aşina) sınıflar gelmiş (DateTime tipi ve DateUtils uniti geliştirilmiş mesela)

Kod Yönetimi : Tanıtımlarda ve ürün reklamlarında üstüne basa basa vurguladıkları Subversion Integration (versiyon, kodda yapılan değişiklikler ve geçmiş kontrolü) gelmiş. (Bir çok üründe ezelden beridir var olan bir özellik. Kaldı ki, 10 yıl önceki Delphi 7  Team Edition bile buna yakın özellikler sunuyordu zaten) Kod düzenleyici (Kod Formatlayıcı) , Refactoring (değişken rename vb. işlemler) gibi araçlar daha da desteklenmiş.

Modelleme : Son zamanlarda yazılım mühendisliğinin moda kavramlarından olan Modelling de unutulmamış. Nesne yapısı hiyerarşisinin gösteriminden, durum grafiklerine, komponent diyagramlarından, kod dökümanı oluşturmaya kadar aklınıza ne geliyorsa fazlası var, eksiği yok deyip geçeyim.

Test : Yine zorla her programa dayatılan Unit Testing den sonunda Delphi de nasibini almış. DUnit gibi süper bir unitimiz var artık.

Veritabanı : Sanırım her bir yeni versiyon için en çok ter döktükleri yer burası. BDE den ADO ya, dbExpress ten dbGO ya, önce tonla farklımetodoloji icat edersen sonunda geleceğin nokta budur. Özetle, adı geçen tüm veritabanı erişim ve sunum teknolojilerinin tamamı güncellenmiş. BDE (Borland Database Engine) hala güncel olduğunu görünce nostalji etkisinden gözlerim yaşardı desem yalan olmaz. Ürünle birlikte Interbase 20 kullanıcılı Developer Edition ücretsiz gelmekte (Yine ilgililere – varsa – duyurulur)

Yeni Teknolojiler : Cloud (Bulut) desteği de unutulmamış. Amazon EC2 ile patlayan, Microsoftun her zamanki gibi ışığı görüp çakmasını çıkartıp bende varım dediği (Azure) tam olarak desteklenmiş (Google Cloud neden desteklenmemiş acaba.)

Komponentler : Delphiyi delphi yapan VCL ler, 3rd party componentler… Burada önce hakkını verelim, son derece seçkin component setleri hazır olarak gelmekte. Indy, Raize, IP-Works, TeeChart, Nevrona Rave, Installaware gibi çok seçkin componentler hazır. DevExpress gibi UI alanında bestseller bir ürünün hala yüklü gelmemesi ise bence büyük hata. (Üstelik Delphi kökenli DevExpress cileri böylesine küstürmek te büyük başarı)

Web : Yine Delphi tarafından sayısız deneme yanılma yapılan bir diğer konu. Atozed firmasının Intraweb komponentleri XE ile birlikte de geliyor. VCL olarak kullanmak için ideal bir set.  Indy bileşenleri de eksiksiz, güçlü, open source  bir alternatif. WebSnap kullananlar için Server Side VBScript JavaScript desteği eklenmiş.

Yeni eklenen komponentlere (VCL) gelince;  etkileyici Gesture designer gelmiş. dokunmatik ya da etkileşimli uygulama yazanlar bunu çok sevecekler. TTouchKeyboard (Sanal Ekran Klavyesi) de yeterince başarılı. Görsel olarak çok futuristik olmasa da, kullanımı kolay ve fazlasıyla iş görüyor.

(Web geliştirme konusunda Delphi Prism / RadPHP XE ilgili (ve iddialı) olduğundan WEB tabanlı projeleri bu ürünlerle değerlendirmek daha sağlıklı bir yaklaşım olur)

Sonuç :

90 ların ortasında çıkan, kısa sürede efsaneleşen Delphi ne yazık ki, son 4-5 yıldır sürekli kan kaybetmektedir. Bu kötü gidişatın sebepleri ayrı bir makale konusu olacağından girmek istemiyorum. Delphi XE, ilk bakışta gözalıcı görünmekle birlikte, kaçan delphi geliştiricilerini geri getirebilecek mi? Ya da diğer dilleri (Mesela Visual Basic, C#, Java) kullanarak geliştirme yapan programcıları kazanabilecek mi? Her ikisine de evet diyebilmek çok zor. Eğer eldeki delphi geliştiricilerini kaçırmazsa bu bile büyük başarı olacaktır.

Delphi neredeyse her yıl yeni bir versiyon çıkartmaktadır. CodeGear RAD Studio 2009, Embarcadero Delphi 2010, Şimdi RAD Studio XE… Buradan da anlaşılacağı gibi, geçiş süreci hala devam etmektedir. Şimdilik görünen, Delphi nin var olan teknolojileri çok geçmeden yakaladığı ve kendi geliştiricilerini her zaman up to date tuttuğudur. Burada insanüstü bir gayret gösterildiğini anlamak zor değil. Microsoft cephesinde, işler çok daha yalın. Herşeyden önce işletim sistemi ve Framework gibi kendi tekelinde ürünler var. Piyasaya yeni bir versiyon çıkmadan önce, kendi içinde (inhouse) olarak tüm birimler eşzamanlı harekete geçebilir.  Her birim kendi uyumlu güncellemelerini yapabilir. Delphi geliştiricileri ise, oturup final release beklemek zorundalar. Tek beklenilen Microsoft olsa yine iyi, App Engine alanında gittikçe daha çok görülen Google, Java dünyası, Açık kaynak kodu geliştiriciler vs. vs. Hemen her cephede en önde yer alıp şaşkın şaşkın dolaşmaktan başka çareleri yok gibi…

Ben kişisel olarak Visual Studio ve C# kullanıyorum. Delphi kullanmayı bırakalı 3-4 yıl oluyor. Hala bazı projelerde Delphi ile çözüm geliştirdiğim de oluyor (100 lerce MB framework kurmayı gerektirmeyen, Native Win32 uygulamalarında mesela…)

Delphi geliştiricilerinin Delphi yi bırakmaları için hala ciddi bir neden yok. Benzer şekilde Delphi de ısrar etmeleri için de bir neden yok.

Delphi yıllar önce Anders Hejlsberg ile yaptığını bir daha yapabilir mi? Üzülerek te olsa pek ihtimal veremiyorum. Bana göre Borland firması, Hejlberg’in Microsofta 1 milyon $ ve hisse ortaklığı sonucu kaptırılmasıyla zaten bitmişti. Sonrasında firma  sayısız isim değiştirmiş ve son olarak 2 yıl önce tüm ürünleri ile birlikte komik ötesi bir rakamla Embarcadero’ya  satılmıştı. Tüm satış değeri sadece 23 milyon $ dı. (Borland’ın alıcı bulmak için kapı kapı gezdiği yıllarda, Türkiye’den bir alıcı çıksa Türk Bilişim sektörü için çağın hareketi olurdu diye iç geçirirdim. Emsal teşkil etmesi açısından bazı örnekler vermek istiyorum;

  • Neredeyse tedavülden kalkacak olan Sybase veritabanı, SAP ye, Borlandın tam 250 katına, 5.6 milyar dolara satıldı.
  • Ülkemizde Delphi kullanarak geliştirme yapan Logo Yazılımın Borsa bedeli 70 milyon $ civarında
  • Ülker, Belçikalı çikolata üreticisi Godiva’yı 600 milyon $a satın aldı
  • GS nin Aslantepe projesi : 300 milyon $ (bunun 4 katına çıkacağı söyleniyor)
  • BİM grubunun Mecidiyeköydeki eski likör fabrikasına verdiği teklif : 450 milyon $)

Sonuçta, yeni projeler için birincil uygulama olarak seçmemekle birlikte, eski gözağrımı, 1. versiyonundan 7. versiyonuna kadar kullandığım Delphi yi, arada bir göz hapsinde tutmakta fayda var 😉 )

Barkod Printer, Seri Port, USB, C# üzerine… – 3

Bundan önceki ilk 2 makalede sırasıyla Barkod yazıcılara ve C# içinden erişime değinmiştik. Ülkemizde yaygın olarak bulunan Zebra ve Argox yazıcılar için, barkod komut dili olan PPLA PPLB ZPL gibi diller ile tasarım yapmayı ve bu tasarımları barkod yazıcıya göndermeyi anlatmıştım.

Bu makalede ise  C# içinden  USB ile bağlı olan yazıcıya, data göndermek üzere gliştirilmiş kütüphaneyi ve C# içinden kullanımını göstereceğim.

aşağıdaki kodu DirectPrint.cs olarak kaydedip, var olan projenize item olarak eklemeniz yeterlidir.

// DirectPrint.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;

namespace VYP
{
	public class RawPrinterHelper
	{
		// Structure and API declarions:
		[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
		public class DOCINFOA
		{
			[MarshalAs(UnmanagedType.LPStr)]
			public string pDocName;
			[MarshalAs(UnmanagedType.LPStr)]
			public string pOutputFile;
			[MarshalAs(UnmanagedType.LPStr)]
			public string pDataType;
		}
		[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
		public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);

		[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
		public static extern bool ClosePrinter(IntPtr hPrinter);

		[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
		public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);

		[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
		public static extern bool EndDocPrinter(IntPtr hPrinter);

		[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
		public static extern bool StartPagePrinter(IntPtr hPrinter);

		[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
		public static extern bool EndPagePrinter(IntPtr hPrinter);

		[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
		public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);

		// SendBytesToPrinter()
		// When the function is given a printer name and an unmanaged array
		// of bytes, the function sends those bytes to the print queue.
		// Returns true on success, false on failure.
		public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
		{
			Int32 dwError = 0, dwWritten = 0;
			IntPtr hPrinter = new IntPtr(0);
			DOCINFOA di = new DOCINFOA();
			bool bSuccess = false; // Assume failure unless you specifically succeed.

			di.pDocName = "Mavis RAW Document (Barcode)";
			di.pDataType = "RAW";

			// Open the printer.
			if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
			{
				// Start a document.
				if (StartDocPrinter(hPrinter, 1, di))
				{
					// Start a page.
					if (StartPagePrinter(hPrinter))
					{
						// Write your bytes.
						bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
						EndPagePrinter(hPrinter);
					}
					EndDocPrinter(hPrinter);
				}
				ClosePrinter(hPrinter);
			}
			// If you did not succeed, GetLastError may give more information
			// about why not.
			if (bSuccess == false)
			{
				dwError = Marshal.GetLastWin32Error();
			}
			return bSuccess;
		}

		public static bool SendFileToPrinter(string szPrinterName, string szFileName)
		{
			// Open the file.
			FileStream fs = new FileStream(szFileName, FileMode.Open);
			// Create a BinaryReader on the file.
			BinaryReader br = new BinaryReader(fs);
			// Dim an array of bytes big enough to hold the file's contents.
			Byte[] bytes = new Byte[fs.Length];
			bool bSuccess = false;
			// Your unmanaged pointer.
			IntPtr pUnmanagedBytes = new IntPtr(0);
			int nLength;

			nLength = Convert.ToInt32(fs.Length);
			// Read the contents of the file into the array.
			bytes = br.ReadBytes(nLength);
			// Allocate some unmanaged memory for those bytes.
			pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
			// Copy the managed byte array into the unmanaged array.
			Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
			// Send the unmanaged bytes to the printer.
			bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
			// Free the unmanaged memory that you allocated earlier.
			Marshal.FreeCoTaskMem(pUnmanagedBytes);
			return bSuccess;
		}

		public static bool SendStringToPrinter(string szPrinterName, string szString)
		{
			IntPtr pBytes;
			Int32 dwCount;
			// How many characters are in the string?
			dwCount = szString.Length;
			// Assume that the printer is expecting ANSI text, and then convert
			// the string to ANSI text.
			pBytes = Marshal.StringToCoTaskMemAnsi(szString);
			// Send the converted ANSI string to the printer.
			SendBytesToPrinter(szPrinterName, pBytes, dwCount);
			Marshal.FreeCoTaskMem(pBytes);
			return true;
		}
	}

}

VS içindeki Projeniz şuna benzer bir şekilde görünür…

Artık, nereden isterseniz erişebileceğiniz çok düzgün bir sınıfımız oldu. SendBytesToPrinter içinde, yazdırma yöneticisine gönderilecek döküman adı bilgisini görebilirsiniz. Siz barkod bastır komutu verdiğinizde, Windows yazdırma yöneticinde bu isim görünecektir. Dolayısıyla projenize uygun şık bir isim girebilirsiniz.

Programınızdan kullanımı ise, bir önceki makalede gösterildiği gibidir. Yine de kısaca tekrar etmek gerekirse

RawPrinterHelper.SendStringToPrinter(printerName, barStrings);

şeklindeki bir yapı işinizi görür. Buradaki printerName, windows sürücüleri ile kurulu yazıcınızın adıdır. barstrings ise göndereceğiniz barkod komutlarıdır.

Benzer şekilde, paralel port kullanan nokta vuruşlu yazıcılara da direk USB üzerinden aynı sınıfı kullanarak erişebilirsiniz.

Arçelik Buzdolabı İşletmesinde Karakter Okuma (OCR)

Mavis, Eskişehirdeki Arçelik Buzdolabı İşletmesinde, Karakter Okuma (OCR) çözümünü devreye almak üzere çalışmalara başladı.

Mavis olarak OCR (Optik Karakter Tanıma) üzerine hayli gelişmiş bilgi birikimi ve tecrübemiz ile kısa sürede sistemi devreye alacağımızı düşünüyoruz. Proje, daha önce Oyak-Renault ta kurmuş olduğumuz dingil üzerindeki yazıyı okuma projemize benzemekte olup kendine özgü bazı zorluklar içermektedir. Bunlar;

  • Okunacak karakterler bombeli (konkav) bir yüzey üzerinde yer almaktadır
  • Okunacak karakterler nokta vuruşlu bir makina ile yazılmıştır
  • Farklı modeller için karakterlerin yeri değişebilmektedir

gibi sayılabilir.

Mavis olarak, alınan görüntüler ve geliştirilen algoritmanın ekran görüntüleri aşağıdaki gibidir

Kompresörün yüzeyinin uEye kamera ile alınmış orijinal resmi. Resim alınmadan önce demo amaçlı olarak gidildiğinden, aydınlatma kullanılmamıştır. Kırmızı 10 x 10 led array kullanılarak aydınlatılması düşünülen yüzeyde yazı kalitesinin daha iyi elde edileceği hesaplanmaktadır.

Görüntü işleme teknikleri kullanarak önce önce filtreleme (karakteri meydana getiren noktalar ile resimdeki lekelerin ayıklanması) yapılır, sonra noktalar birleştirilir daha sonra birleşmiş noktalar karakter meydana getirecek şekilde genişletilir  (karakterler ortaya çıkartılır) Resimde her bir karakter ayrı bir renk ile gösterilmiştir.

Son olarak, iyi bir OCR yapabilmek için normalde (insan gözünde de olduğu gibi)beyaz zemin üzerinde siyah karakterlere dönüşüm yapılması gerekir. Yapay olarak (artificial) siyah beyaz binary (binImage) resim oluşturulur. Oldukça temiz ve filtrelenmiş olarak görünen bu resim artık kolaylıkla okunabilir (OCR edilebilir) OCR edilmiş sonuç ekrana yeşil olarak yazılmıştır.

Proje uygulama aşamasında, sistemin tetiklenmesi, aydınlatmanın devreye girmesi, işlem sonucunun hatta bildirilmesi (PLC işlemleri), veritabanına kaydetme vb. aşamalar da olacaktır. Mavis olarak benzer sistemleri kurduğumuzdan gerek yazılım, gerek donanım olarak tüm bileşenler hazır olarak bulunmaktadır.

Projeye ilişkin en sadeleştirilmiş HALCON kodunu aşağıda veriyorum. Aradaki kontrol ifadelerini (if), gelişmiş seçim parametrelerini, OCR train kodlarını ve try-catch yapı bloklarını kaldırdım. Olabildiğince yalın hale getirdim ki herhangi bir geliştirici (Halconist) tarafından okunması durumunda en anlaşılır şekilde olsun 😉 (Programın yine de düzgün ve sağlıklı olarak çalışmaktadır)

Aşağıdaki kodun çalışması için gerekli olan özgün resmi sayfanın en altında OzgunResim olarak bulabilirsiniz.

read_image (Image, 'C:/Projects/Demos/Arcelik/1.bmp')
*draw_rectangle1 (3600, Row1, Column1, Row2, Column2)
gen_rectangle1 (Rectangle, 590, 400, 792, 705)
reduce_domain (Image, Rectangle, ImageReduced)
threshold (ImageReduced, Regions, 40, 255)
dilation_circle (Regions, RegionDilation, 3)
union1 (RegionDilation, RegionUnion)
smallest_rectangle1(RegionUnion, Row11, Column11, Row21, Column21)
connection (RegionUnion, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 90, 99999)
sort_region (SelectedRegions, SortedRegions, 'character', 'true', 'row')
copy_obj(SortedRegions, ObjectsSelected, 1, 6)
get_image_pointer1 (ImageReduced, _, _, Width, Height)
region_to_bin (SortedRegions, BinImage, 0, 255, Width, Height)
read_ocr_class_mlp ('Industrial.omc', OCRHandle)
do_ocr_multi_class_mlp (SortedRegions, BinImage, OCRHandle, Class, Confidence)
dev_set_color('green')
set_display_font (3600, 24, 'verdana', 'true', 'false')
set_tposition (3600, Row21+20, Column11)
write_string (3600, Class)

Özgün Resim (HALCON kodunda kullanılan)

Nereye Bakıyor Bu Adamlar

1976 yapımı, Zeki Alasya Metin Akpınar filmini burada saygıyla ve de takdirle anarak konuya girmek istiyorum.

Geçtiğimiz fuarlardan birinde, hala hatırladığım ısrarcı bir ziyaretçimiz vardı. İstediği şey “belirli bir yere bakan insanların sayısı” nı bulan bir uygulamaydı. Ziyaretçimiz, projesinin gizliliğinden ötürü olsa gerek, detaya girmekten kaçındığı için, eldeki isterlere göre bir çözüm önerememiştim. Mavis olarak elbette kameralı yapay görme sistemleri yapmaktayız ama bu tür ilginç bir alanda uygulamamız / çalışmamız yoktu.(Fuarlar en ilginç diyalogların yaşandığı yerlerdir zaten) Ve yine hatırladığım kadarıyla, yurtdışında böyle bir çözümün olduğundan bahsediyordu. Mavis olarak en çok sevdiğimiz cümle de işte budur. Eğer herhangi bir kameralı kontrol uygulaması, dünyanın herhangi bir yerinde gerçekleştirilmiş ise, Mavis bunu yapabilecek teknolojiye sahiptir. Bu durumda müşteri ne görmek istediğini bilir, ne araması gerektiğini bilir, hatta çoğu kez neyin mümkün olup, neyin mümkün olmadığını da bilir. Beklentileri de netleşmiştir. Kısaca bilinçlenmiştir ve bizim için çoğu kez bu tür müşteri bulmak kolay değildir.

Tekrar konumuza dönersek, fuarda o gün bu tür bir uygulama yapmadığımızı söylemiştim sanırım.

Şimdi sözümü geri alıyorum.

Veee distribütörü olduğumuz USB uEye XS kameralarının, yüz tanıma özelliklerinin tanıtımına başlıyorum.

Ortalama olarak yarım kibrit kutusu büyüklüğündeki bu muhteşem kamera, görüntü işleme (yapay görme) uygulamalarındaki süper performansının yanısıra yüz tanıma ile ilişkili etkileyici özellikler sunmaktadır.

Aşağıdaki resimde de göründüğü gibi, görüntüye kaç kişinin girdiği, her birinin hangi yöne baktığı, yüz merkezlerinin koordinat bilgisi ve yüzün dönme açısı (0/90/180/270) gibi bilgileri verebilmektedir. Üstelik tüm bu bilgileri kendi programlarınızdan da kullanabilirsiniz. Geliştiriciler (yazılımcılar) kamera ile birlikte ücretsiz olarak gelen gelişmiş API ile tüm kamera fonksiyonlarına kendi C++, C#, VB, Delphi vb. uygulamalarından API ya da ActiveX olarak erişebilirler.

konuyla ilgili detaylı video için bu videoyu izleyebilirsiniz.

IDS uEye kameralar için www.ids-imaging.com adresini ziyaret edebilirsiniz.

Not : Burada bahsedilen yüz tanıma, parmak izi tanıma sistemlerinde olduğu gibi yüz ile yüzün sahibini eşleştirme uygulaması değildir. Sadece fotoğraf içindeki yüzü tespit eden ve onun merkez koordinatları ile yönünü bulan bir özelliktir. Parmak izi gibi kullanılan yüz tanıma (ve kimlik bulma) sistemleri de vardır. Genelde hazır çözümlerdir ve Mavis olarak bu konuyla bir ilgimiz yoktur.

Renault’ta %100 Native Görüntüleme Sistemi ve uEye XS kamera

Mavis olarak Oyak – Renault Bursa fabrikasında yeni bir sistemi devreye aldık. Planlı duruş döneminde modernizasyon çalışması olarak adlandırılabilecek çalışmada, kameralı görüş sistemi devreye alındı.

Uygulama ile, Motor Montaj hattında, keçe varlığı kontrol edilmektedir. Bu uygulamayı diğerlerinden ayıran fark ise, Mavis tarafından Delphi ile geliştirilmiş tek ticari uygulama olmasıdır.  Mavis görüntü işleme uygulamalarını HALCON kütüphanesini kullanarak geliştirmektedir. HALCON şüphesiz en gelişmiş ve en hızlı görüntü işleme kütüphanesidir ve Mavis olarak HALCON kullanmanın avantajlarını yaşamaktayız. Buna rağmen, bu uygulama ciddi bir görüntü işleme arabirimine ihtiyaç duymuyordu. Dolayısıyla araya ilave bir katman (kütüphane, framework) sokmadan çok hızlı bir şekilde görüntü alıp genişçe bir monitörde (LCD TV) display etmek en mantıklı yöntemdi.

Projede IDS firmasının UI-1008XS marka kamerası kullanılmıştır.

son derece küçük bir tasarımı olan bu kamera mükemmel denecek kalitede sonuçlar vermektedir. Genel özellikleri :

– 8 Megapixel CMOS Sensör
– 3280×2464 çözünürlük (Snapshot Modundayken)
– 1280×720 çözünürlük (15 frame/sec realtime modunda)
– Entegre Otofokus lens
– Yüz Tanıma
– Elektronik resim stabilize etme
– EMC Regülasyonu: FCC Class B, CE Class B

gibi özelliklere sahiptir. Ortalama olarak yarım kibrit kutusu ebatlarında olduğundan, çok geniş uygulama alanlarına sahip olabilir.

Mavis olarak, Renault için ledli aydınlatma sistemi kullanmayı uygun gördük. Kameranın oto kontrast ayarını da etkinleştirip, 24 saat tüm ışık koşullarında hep aynı ışık şiddetinin ve dolayısıyla aynı görüntü kalitesinin yakalanmasını sağladık.

Delphi 2010 ile geliştirilen program, direk olarak IDS uEye API kullandığından, son derece hızlı Native bir windows uygulaması olmuştur. Kamera sürücüleri dışında hiçbir ilave program, kütüphane vb. kuruluma ihtiyaç duymayan yazılım, tüm windows uygulamalarında çalışabilecek yetenektedir ve sadece 600 KB büyüklüktedir.

C# ile başka uygulamayı yönetmek ve MATLAB ve Turist Ömer ve Tetris üzerine

C# içinden başka uygulamaları yönetmek bazı durumlarda gerekebilir. En yaygın olarak kullanılan yöntem, diğer uygulamaya mouse olayı ya da tuş (keystroke) göndermek. Aslında daha profesyonel yöntemler de mevcut, bu tür profesyonel yöntemlerin son zamanlarda kumar sitelerinde otomatik oyuncu olarak kullanılmakta olduğuna şahit oluyorum (BOT)

Yapay görme teknikleri ile birlikte çok güzel ve profesyonel  BOTlar yazılabilir. Mesela bende takıntı oldu, ne zaman bir CAPTCHA görsem, onun görüntü işleme teknikleri ile kolay kırılıp kırılamayacağına göz atarım ilkin.  (Sanırım bu yüzden captcha lar da gelişti. Etkileşimkli sorular türemeye başladı. Kutucuk içindeki yazıyı şuraya yazın vs. değil de, Türkiyenin başkenti neresidir? gibi sorulara cevap vermemizi istiyorlar. Karşıda insan olup olmadığını anlamanın güzel bir yolu. Bu tür sorulara da cevap verebilecek bir yapay zeka uygulaması geliştirilebilir mi mesela. Ya da Turist Ömerin bilgisayara sorduğu “Kompeter naber? (direk deadlock), 2 x 2 ? toto sonuçları? attırıbıttın mı? (zzzztt erenköy) ” gibi soruları geldi aklıma. ) Neyse konuyu çok dağıtmadan yapay görme kullanan bir BOT a kafa yoralım. Pek ala sanal bir okey oynayıcısı olabilir bu. Gerçi, o tür oyun sitelerinde, yapay görme ye girmeden, atılan taşın/kartın değeri zaten bir yerde listeleniyor.

“Ali Kırmızı 4 Attı” gibi.

Burada metin incelenerek (text parser) sanal kullanıcı kimin hangi taşı attığını bulabilir. Bizim işimiz yapay görme olduğuna göre, programımız atılan iskambil kağıdını tanıyabilir (mesela Kupa-7) gibi…

Boş bir anımda bu tür bir uygulama yazıp, Las Vegas sanal web casino’larına dadansam nasıl olur acaba…

Biz artık işin teknik kısmına gelelim. Şu, basit dediğimiz kısmına. Bir başka uygulamaya keystroke gönderme üzerine bir örnek yapalım. Web de bu konuda yerli yabancı tonla örnek var ama ben burada en kısa ve en basitini yazmak istiyorum.

Uygulamamız, windows hesap makinası ile bir hesaplama (8 faktöriyel) yaptırıp, işlem sonucunu alıp kendi başlığında gösteren bir uygulama olsun. Uygulama, hesap makinasını (calc.exe) çalıştırıyor, ardından 8! ve Ctrl + C gönderiyor. Windows hesap makinesi 8! sonucunu bulup ekranına yazıyor ve en son bu değeri clipboard a kopyalıyor. Uygulamamız Hafızada hazırlop hesaplanmış değeri alıyor ve kendi başlık alanında görüntülüyor. Artık ihtiyacı kalmadığından hesap makinasını da kapatıyor. (Böyle birşey ne işe yarar demeyin, bu mantık genişletilerek pek çok uygulama alanı bulunabilir. Üstelik pure multiprocess…)

İşin kod kısmını olabildiğince sadeleştirerek yaptım ki, kodu okuyan herkes anlasın, açıklamaya gerek bile kalmasın.

İşte bütün kod

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace WindowsApplication12
{
	public partial class Form1 : Form
	{

		[DllImport("user32.dll")]
		public static extern bool SetForegroundWindow(IntPtr hWnd);

		public Form1()
		{
			InitializeComponent();
		}

		private void button1_Click(object sender, EventArgs e)
		{
			// Burada hesap makinasını çalıştıralım
			// dilenirse parametrelerle oynanarak görünmez (invisible/hidden) olarak açılabilir
			Process p = Process.Start("calc.exe");

			// Şimdi calc.exe tam olarak yüklendi mi bekleyelim...
			while (p.MainWindowHandle == IntPtr.Zero)
			{
				System.Threading.Thread.Sleep(10);
				p.Refresh();
			}

			// Eğer yüklenmiş ise
			if (p.MainWindowHandle != IntPtr.Zero)
			{
				// Hafızayı temizleyelim. Birazdan hesap makinası dolduracak
				Clipboard.Clear();
				SetForegroundWindow(p.MainWindowHandle);
				System.Windows.Forms.SendKeys.Send("8!^C");	

				// Hafızada Text tipinde veri olana kadar bekleyelim
				while (!Clipboard.ContainsText())
				{
					System.Threading.Thread.Sleep(10);
					Application.DoEvents();
				}

				// Hafızadaki text tipi veriyi alalım ve pencerenin başlığına yazalım
				String clipText = Clipboard.GetData(DataFormats.Text).ToString();
				Text = clipText;

				// Hesap makinasını kapatabiliriz artık
				p.Kill();
			}
			else MessageBox.Show("Uygulama Bulunamadı!");
		}
	}
}

uygulamanın sorunsuz çalışması lazım. Ben Windows Vista da, VS 2005 kullanarak derledim bir sorun çıkmadı.

Burada asıl işi yapan
System.Windows.Forms.SendKeys.Send(“8!^C”);

fonksiyonu. Bunun SendWait versiyonu da var. gönderim bitene kadar uygulamayı bekler. Bazı durumlarda daha sağlıklı çalışabilir.

Ama asıl önemli olan, App.config dosyasında bir değişiklik yapmanız gerektiğidir. Normalde App.Config dosyası VS içinde default olarak oluşturulmaz. Manual oluşturmanız lazım ve içine

<appSettings>

<add key=”SendKeys” value=”SendInput”/>

</appSettings>

ifadelerini girmelisiniz. Bunu yapmak için VS içinden  Add New Item diyalog kutusuna tıklayıp Application Configuration File şablonunu seçip Add düğmesini tıklarsanız XML formatında ve herhangi bir seçenek içermeyen App.Config dosyası hazırlanır. Bunun içine yukarıda bahsettiğim 3 satırı girmeniz yeterlidir.

Bendeki App.Config şu şekilde

<?xml version=”1.0″ encoding=”utf-8″ ?>
<configuration>
<appSettings>
<add key=”SendKeys” value=”SendInput”/>
</appSettings>
</configuration>

<?xml version=”1.0″ encoding=”utf-8″ ?><configuration>  <appSettings>    <add key=”SendKeys” value=”SendInput”/>  </appSettings></configuration>

Gecenin yarısı bu makaleyi yazmama sebep olan olay, Hüseyin’in Matlab ile yaptığı o güzel ses-işlem (voice processing) uygulamalarına C# içinden erişmenin 1001 yolundan bir diğerine kafa yormaktı 😉  Proje, ses komutuyla tetris oynamaktı. Sol, Sağ, Dön, Aşağı komutları ile tetris oynamak gerçekten de eğlenceli olabilir. Gerçi bu yolla rekor yapılabilir mi bilmem. Sol sol sol soll…. derken, MATLAB o kadar hızlı process edebilecek mi acaba?

Yavaştır MATLAB yavaş… 😉 😉 😉

Hüseyin buradan sana sesleniyorum, direk MATLAB ile yazılmış Tetris uygulamaları var. Free. Downloadable. Bunlardan bi tane indir, yine Matlab içinden sesle yönet.

Ben de, kameraya el hareketleri ile yön bildirip tetris oynatayım. Bakalım hangisi daha kullanışlı olacak.

Ya da ortaya Hybrid bir versiyon çıkartalım. Sesli, görsel, dokunsal, duygusal Tetris. Hmmm…İyi Fikir. Budur.

Poliüretan Direksiyon’da Yüzey ve Varlık Kontrolü

Mavis, Pimsa tarafından Ford Transit için üretilen poliüretan direksiyonların kameralı kalite kontrollerini yapmak amacıyla kameralı kontrol istasyonu geliştirdi. Sistem Pimsa tarafında hat içine montaj ve direksiyon sabitleme mekanizmasının takılması gibi işlemler için devralındı. Önümüzdeki hafta içinde testlere başlanacak ve muhtemelen aynı hafta içinde eğitim verilip devreye alınacak.

Yapılan kontroller :

  • 4 adet elektrik iletim soketi kontrolü
  • 4 soketin saplama kontrolü
  • Soket boy ölçüm kontrolü
  • Yüzey Kontrolü
  • Çizik Kontrolü
  • Delik Kontrolü
  • Renk Kontrolü
  • Boy Kontrolü

şeklinde sıralanabilir.

Mavis tarafından geliştirilen istasyonda, direksiyon sabit bir yere takılmakta, üstten 4 kamera yüzey üzerindeki kontrolleri gerçekleştirip, yandan bakan 2 kamera ise, soketlere ilişkin kontrolleri yapmaktadır.

Kameralı Çoklu Karekod Okuma ve SAP Entegrasyonu

İTS (İlaç Takip Sistemi) nin devreye girmesiyle birlikte İlaç üretici firmalar ve ecza depoları, Karekod lu otomasyon sistemine ağırlık vermeye başladı. Mavis, genelde el terminali ile tek tek okutmak suretiyle yapılan karekod okutma işlemine, alternatif olarak  çoklu karekod okuyucu sistemi geliştirmiştir.

SAP ile entegre çalışabilen sistem, karekod okuyuculu bir el terminalinin yapabileceğinden çok daha fazlasını sunmaktadır. Bunlar;

  • Aynı anda ve yüksek hızda çoklu (çok sayıda) karekod okuyabilme
  • Farklı yüksekliklerdeki ilaçların karekodlarını okuyabilme
  • Açık zemin üzerine koyu (dark on light) ya da koyu zemin üzerine açık (light on dark) karekodları aynı anda okuyabilme
  • Farklı boylardaki (w x h) karekodları okuyabilme
  • farklı ışık koşullarındaki karekodları okuyabilme
  • Excel, veritabanı, istatistik, rapor çıktısı alabilme
  • SAP ile %100 Entegrasyon
  • Karekod değerlerini (eğim, okuma başarısı, baskı kalitesi vb.) gösterebilme
  • Shrink ya da bandajlı (overlap) bağlı ambalajları okuyabilme
  • Dijital çıkış sinyali verebilme (Okuma başarılı / başarısız)
  • Veritabanı ya da var olan sistemle haberleşebilme (Okuyacağı karekodları önceden bilme)
  • Koli Barkodu / Kutu Barkodu üretebilme
  • 1D barkodları da (Code 39, Ean8, Ean 13 vb.) okuyabilme

gibi özelliklerdir.

(Edit : Yazılım Eylül 2010 tarihinde daha da geliştirilerek, okuma yüzdesini daha da rtırmıştır. Konu hakkında detaylı bilgi için buraya tıklayınız)

Sistem Bileşenleri :

  • Karekodların görüntüsünü almaya yarayan kamera (lar)
  • Aydınlatma Sistemi (Fluoresan ya da led ışıklandırma)
  • Windows işletim sistemi yüklü PC (netbook)
  • Mavis VYP yazılımı

Mavis Akıllı Karekod Okuma Teknolojisinin anahtar özellikleri:

Sistem 2 veya daha çok sayıda kamera ile donatılmıştır. Kameralar farklı yükseklikler ve ışık şiddetlerine göre konfigüre edilmiştir. El tipi bir okuyucuya göre çok daha geniş bir alanı, farklı yükseklikleri ve farklı tipleri tarayarak, sonuçları birleştirir ve çok kısa bir süre içinde tüm karekodları başarıyla okur.

Sistem, okuma başarısını artırmak amacıyla, okuma kalitesini beğenmemiş ise, otomatik olarak kamera pozlama süresini değiştirerek çok sayıda resim alır ve en ideal resim sonucuna göre işlem yapar.

Sonuç olarak kameraların toplam görüş alanına giren karekodların tümü başarıyla okunmuş olur.

Örnek Proje Resimleri :

Örnek Proje, Bir ilaç deposunda, konveyör üzerinde ilaç kasası içinde giden ilaçların, kamera altına geldiğinde fotoğrafının çekilmesi ve karekodlarının okunması şeklinde çalışmaktadır. 2 kamera kullanılmıştır. Her bir kamera farklı yüksekliğe focus olmuştur ve farklı konfigüre edilmiştir. Aşağıda, her iki kameradan alınan görüntüler, bu görüntülerin içerdiği karekodların okunması ve yazılımın her iki görüntüyü ortak olarak değerlendirmesi gösterilmektedir.

Solda ve hemen altında sırasıyla 1. ve 2.  kameradan alınan resimler görünmektedir. Görüldüğü gibi, birçok farklı türden ilaç kullanılmıştır. Yazılım her bir kameraya giren karekodları değerlendirecektir.

1. kamera yüksek ya da yükseğe yakın karekodları, 2. kamera ise yüzeye yakın karekodları okuyacak şekilde ayarlanmıştır. Yazılım, karekod okuma başarısı çok yüksek olduğundan, her iki kamerada da aynı karekodları okuyabilir. Mavis tarafından geliştirilen algoritmalar, iki defa okunan barkodları tespit ederek, sonuç olarak tek bir defa okuma bilgisini iletecektir.

Gerçek bir ecza deposu koşullarında yapılmış olan bu çalışmada fluoresan aydınlatma ve 1.3 MegaPizel kameralar ile yapılmıştır. Mavis, Led tabanlı aydınlatma ve 5-10 Megapixel kameralar kullanarak sistemi ürün haline getirmektedir.

Yazılım Ekran Görüntüleri (Üzerine tıklayarak görüntüyü büyütebilirsiniz) :

Mavis Kütahya OSB de

Kütahya Organize Sanayi Bölgesi firmalarından, Kros Otomotivde, 10. kameralı kontrol istasyonunu devreye almak üzere Kütahya’dayız.

Sistem Bileşenleri (Donanım)

  • 7 Adet Kamera
  • 1 Tepe Aydınlatması
  • 1 USB Digital IO (Mavis)
  • 2 Led Aydınlatma Ünitesi
  • 1 Barkod Yazıcı

Sistemde, birbirinden farklı konumlara yerleştirilecek 6 adet ürün kontrol edilmektedir. Her bir ürün için aynı anda 1,2,3 veya 4 kamera devrede olacaktır.

Bu projede, aktif kamera ekran sistemi kullanılmıştır. Her bir ürün için kullanılacak olan kameralar kendi MDI Child pencerelerinde yüklenecek, kullanılmayacak kameralar için Frame Grabber (ve USB veri yolu kullanımı) devre dışı olacaktır.