Okuldan Sonrası Ölüm (okul-ölüm)

Nisan 22, 2009 03:37 tarihinde dandelo tarafndan eklenmistir.

    Bir arkadaşımın "okuldan sonra ölüm gelir" şeklinde ifadesine önce şaşırarak sonra işin içinde bir bit yeniği arıyarak aklıma bazı fikirler geldi. İşin aslı; okul kelimesinin harflerinin her birinden bir sonra gelen harflerin oluşturduğu kelime "ölüm". Ne büyük tesadüf değilmi? Yaptığım ufak çaplı bir araştırma ile, 12703 kelime içinde sadece 8 kelime bu şekilde eşleşti. Bunların içinde 4 harfli eşleşme sadece 2 adet. "Nötr" be "Okul" kelimeleri.

 

   "Nötr" kelimesini Türkçe saymassak 12703 kelime içinde sadece bir adet eşleşme var; (okul-ölüm) eşleşmesi. Bunun oranı 0,000157 den daha az. Bu değerde okuldan sonra ölüm gelir tezinin tesadüf olma ihtimalini gösterir. Okulumun bitmesine son 2-3 ay kala(!) yaptığım ufak bir çalışmayı paylaşmak istiyorum. (okul_olum.rar)

   "İngilizce-Türkçe" sözlük veritabanından (sozluk.rar) sadece Türkçe kelimeleri alarak ufak bir veritabanı (kelimeler.mdb) oluşturdum.Dil olarak C#kullandığım programı bölüm bölüm açıklayalım. 

        List<string> kelimeler = new List<string>();
List<string> eşleşmeler = new List<string>();
string harfler = "abcçdefgğhıijklmnoöprsştuüvyz-";

private void Form1_Load(object sender, EventArgs e)
{
    baglan();

    //tüm kelimeleri yaz
    int k = 0;
    foreach (var kelime in kelimeler)
    {
        listBox1.Items.Add(kelimeler[k].ToString());
        k++;
    }

    //tüm kelimeleri kontrol et
    for (int i = 0; i < kelimeler.Count; i++)
    {
        string al = kelimeler[i].ToString();
        string ver = "";

        foreach (char harf in al)
        {
            int sayı = harfler.IndexOf(harf);
            ver += harfler[sayı + 1];

        }

        if (kelimeler.Contains(ver))
        {
            listBox2.Items.Add(al + " - " + ver);
            eşleşmeler.Add(ver);
        }
    }

    int kelime_adet = kelimeler.Count;
    int eşleşme_adet = listBox2.Items.Count;

    double ikiharfli = eşleşmeler.Where(kelime => kelime.Length == 2).Count();
    double üçharfli = eşleşmeler.Where(kelime => kelime.Length == 3).Count();
    double dörtharfli = eşleşmeler.Where(kelime => kelime.Length == 4).Count();

    string metin = string.Format("{0} adet kelime içinde sadece {1} adet kelime eşleşmiştir."
        +" {2} kelime içinde {3} adet iki harfli, {4} adet üç harfli,"
        + " {5} adet dört harfli eşleşme vardır.\n\nDört harfli eşleşme ihtimali : {6} dır.",
        kelime_adet, eşleşme_adet,kelime_adet,ikiharfli,üçharfli,dörtharfli,dörtharfli/kelime_adet);

    richTextBox1.Text = metin;

İlk olarak bağlantı kurulup tüm kelimeler "kelimeler" listesine eklenmektedir. Daha sonra "kelimeler" içindeki tüm kelimeler dolaşılıp harflerinin bir sonraki harflerden oluşan kelime elde edilmektedir.

public void baglan()
{
    OleDbConnection baglanti = new OleDbConnection();
    baglanti.ConnectionString = @"Provider= Microsoft.Jet.OleDB.4.0;Data Source = kelimeler.mdb";

    string sorgu = "SELECT kelime FROM TBLkelimeler";
    try
    {
        baglanti.Open();
        komut = new OleDbCommand(sorgu, baglanti);
        tablo = komut.ExecuteReader();
        
        while (tablo.Read())
        {
            kelimeler.Add(tablo[0].ToString());    
        }
    }
    catch
    {
        MessageBox.Show("Hata!");

    }
    finally
    {
        baglanti.Close();
    }
}

Yeni kelime oluşturulur.

for (int i = 0; i < kelimeler.Count; i++)
{
    string al = kelimeler[i].ToString();
    string ver = "";

    foreach (char harf in al)
    {
        int sayı = harfler.IndexOf(harf);
        ver += harfler[sayı + 1];
    }

Yeni oluşan kelime, "kelimeler" içindeyse listbox'a eklenir.

    if (kelimeler.Contains(ver))
    {
        listBox2.Items.Add(al + " - " + ver);
        eşleşmeler.Add(ver);
    }

}

Son olarakta eşleşmeler sayılıp oranlar hesaplanır.

int kelime_adet = kelimeler.Count;
int eşleşme_adet = listBox2.Items.Count;

double ikiharfli = eşleşmeler.Where(kelime => kelime.Length == 2).Count();
double üçharfli = eşleşmeler.Where(kelime => kelime.Length == 3).Count();
double dörtharfli = eşleşmeler.Where(kelime => kelime.Length == 4).Count();

string metin = string.Format("{0} adet kelime içinde sadece {1} adet kelime eşleşmiştir."
    +" {2} kelime içinde {3} adet iki harfli, {4} adet üç harfli,"
    + " {5} adet dört harfli eşleşme vardır.\n\nDört harfli eşleşme ihtimali : {6} dır.",
    kelime_adet, eşleşme_adet,kelime_adet,ikiharfli,üçharfli,dörtharfli,dörtharfli/kelime_adet);
 

 

Bu ufak ama önemli araştırma ile Doğal Dil İşleme üzerine ilk çalışmamı da yapmış oldum. Nice iyi çalışmalara...(Tabi okul bitmeden)

 


Görüntü İşleme (C#)

Mart 14, 2009 22:46 tarihinde dandelo tarafndan eklenmistir.

gi  Görüntü İşleme : Ölçülmüş veya kaydedilmiş olan elektronik (dijital) görüntü verilerini, elektronik ortamda (bilgisayar ve yazılımlar yardımı ile) amaca uygun şekilde değiştirmeye yönelik olarak yapılan bilgisayar çalışması. [wp]

 

 

      Bir görüntü gözek(pixel)lerden, gözeklerde kırmızı(R)-yeşil(G)-mavi(B) renk değerlerinden oluşur. Gözeklerin rengi RGB olarak üç ana rengin birleşimi şeklinde ifade edilir. R-G-B renk değerleri 0 ila 255 arasında değişir. 0 en koyu ton iken 255 e gittikçe açılır. Örneğin mavi rengin değeri :(0,0,255) kırmızın :(255,0,0) ve yeşilin de :(0,255,0) dir. Diğer renkler bu değerlerin değişmesi ile elde edilir. Artı olarak  32bitlik bir görüntünün gözekleri 4 kısından oluşur ve 4 kısımda görüntüye saydamlık derecesini veren 'Alpha' kanalıdır.

     Görüntünün bir satırda bulundurduğu gözeklerin sayısı o görüntünün genişliğini(width), satır sayısıda o resmin boyunu(height) verir.Boyutlarda (800x600), (1024x768) gibi iki değerli şeklinde yazılır. Bu değerlerden ilki görüntünün genişliğini, ikinci değer ise boyunu verir.

    C# ile görüntü işlemek için bir çok yöntem mevcut olmasına rağmen daha hızlı bir yöntem olduğu için pointer kullanacağım. Kullandığım yöntemin ana kalıbı aşağıdaki gibidir.

24bitlik format için ;



        public Bitmap griton(Bitmap resim)
        {
            unsafe
            {
                BitmapData bmpdata = resim.LockBits(new Rectangle(0, 0, resim.Width, resim.Height),
                        ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

                byte* p = (byte*)bmpdata.Scan0;
                int atıl = bmpdata.Width*3 - bmpdata.Stride;

                for (int i = 0; i < bmpdata.Height; i++)
                {
                    for (int h = 0; h < bmpdata.Width; h++)
                    {
                        byte ort = Convert.ToByte((p[0] + p[1] + p[2]) / 3);
                        p[0] = p[1] = p[2] = ort;
                        p += 3;
                    }
                    p += atıl;
                }

                resim.UnlockBits(bmpdata);

                return resim;
            }
        }

32bitlik format için ;


        public Bitmap griton(Bitmap resim)
        {
            unsafe
            {
                BitmapData bmpdata = resim.LockBits(new Rectangle(0, 0, resim.Width, resim.Height),
                        ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

                byte* p = (byte*)bmpdata.Scan0;

                for (int i = 0; i < bmpdata.Height; i++)
                {
                    for (int h = 0; h < bmpdata.Width; h++)
                    {
                        byte ort = Convert.ToByte((p[0] + p[1] + p[2]) / 3);
                        p[0] = p[1] = p[2] = ort;
                        p += 4;
                    }
                }

                resim.UnlockBits(bmpdata);

                return resim;
            }
        }


      Dikkat ettiyseniz 24bitlik formatın aksine burada atıl oluşmamaktadır.

      Kodları unsafe bloğunun içinde yazabileceğimiz gibi metodu aşağıdaki gibi de tanımlayabiliriz.



        public unsafe Bitmap griton(Bitmap resim)
        {
            BitmapData bmpdata ...
            ....
       }


      Yukarıdaki kodları satır satır açıklarsak;

      İlk olarak pointerlar olarak çalışacağımız için kodları "unsafe" bloğu içinde yazmalıyız veya metodu tanımlarken "unsafe" özlelliğini kullanmalıyız. Yalnız projemizde unsafe komutunu kullanabilmemiz için öncelikli olarak projenin ayarlarından unsafe kullanımına izin vermeliyiz. Bunun için, 'Project' menüsünden, '[Proje ismi] Properties', açılan pencerede 'Build' seçeneğine girip 'Allow unsafe code' seçeneğini aktif hale getiriyoruz. 

      Ayrıca çizim işlemlerini yapabilmemiz için projemize aşağıdaki isim uzaylarını eklemeliyiz.

using System.Drawing;
using System.Drawing.Imaging;

 



   BitmapData bmpdata = resim.LockBits(new Rectangle(0, 0, resim.Width, resim.Height),
           ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

       Resmin bitlerini ramde kitleyerek üzerinde işlem yapabilceğimiz hale getiriyor. Aldığı parametreler ;

"new Rectangle(0, 0, resim.Width, resim.Height) " , resmin üzerinde işlem yapılacak alanı belirtir. Yazıldığı şekilde, resmin (0,0) noktasında sonuna kadar tüm alanı kullanır.

"ImageLockMode.ReadWrite" , kilitli alan üzerinde işlem izni. ".ReadWrite" hem okumaya hem yazmaya, ".ReadOnly" adından da anlaşılacağı gibi sadece okurken, ".WriteOnly" sadece yazmaya izin verir.

"PixelFormat.Format24bppRgb" kilitli alanın kullanacağı formatı belirtir.Genel olarak ".Format32bppArgb" ve ".Format24bppRgb formatları kullanılmaktadır. 32 bit formatın 24 formata göre farkı, bir gözekin 3 (r-g-b) yerine 4 (r-g-b-a) parçası olması.


 byte* p = (byte*)bmpdata.Scan0;

 
Ram üzerinde bir gözek ilerlemek.

         Bu komut ile kilitli bellek alanının ilk noktasına ulaşılmaktadır. Resim verilerinin ram üzerinde yerleşimini, resmin gözek yerleşiminin(2 boyutlu) tersine tek satır olarak yerleşmiş olduğunu düşünebiliriz. Yani bir gözekin 3 renk değeri(b-g-r) bitince diğer gözeğin ilk renk değeri (b) gelmektedir. Yukarıdaki resimde de temsili olarak gösterildiği şekilde, p=p[0] ilk renk değerini(mavi) verirken p[1] bir sonraki(yeşil) vermektedir. Eğer p yi bir artırırsak p[0] artık 2. renk değerini(yeşil) verirken p[1] 3. renk değerini(kırmızı) verir. Gözeklerin renk değerlerine ulaşmak için; eğer p değeri gözeğin başındaysa p[0] o gözeğin mavi(b), p[1] yeşil(g) ve p[3] de kırmızı(r) bileşenini vermektedir. Dikkat ettiysenin dizilimler standart r-g-b diziliminin tersine bellekte b-g-r (mavi-yeşil-kırmızı) şeklinde dizilmiştir. Eğer 32bit formatını seçtiyseniz, p[3] değeri bize o gözekin saydamlık derecesini verir. Tam görünür bir gözek için bu değer255 , hiç görünmemesi içinde bu değer 0'a ayarlanır. 32bitlik formatta bir sonraki gözeğe ulaşmak için p, 4 artırılır.

for (int i = 0; i < bmpdata.Height; i++)
{
    for (int h = 0; h < bmpdata.Width; h++)
    {
        byte ort = Convert.ToByte((p[0] + p[1] + p[2]) / 3);
        p[0] = p[1] = p[2] = ort;
        p += 4;
    }
}

        Görüntü üzerinde gözek gözek yapılacak (noktasal) işlemler için (parlaklık, gri ton, negatif gibi) tüm gözekleri dolaşacak şekilde içiçe iki döngü yapıyoruz. İçteki döngü bir satırın tüm gözeklerini dolaşırken, dıştaki döngü hangi satırda olduğumuzu belirliyor. Satır içinde dolaştığımız için bir gözekle işimiz bittiğinde bir sonraki gözeke geçmek için iç döngüde p'yi 3 artırıyoruz(32bit te 4). Bir satır bittiğinde de dıştaki döngünün sonunda p'ye atılı ekliyoruz(sadece 24bit için). Yukarıda ki kodda 32bitlik kullanılarak, bir resmi gri tonlarına çevirme uygulanmıştır. Bir gözekin tüm renk değerlerinin ortalaması alınıp, tüm renk değerlerine bu ortalama değeri atanmaktadır. Bir gözekle işimiz bittiğine bir sonraki gözeğe "p+=4;" kodu ile geçebiliyoruz. Artık p[0] değeri bize diğer gözeğin mavi renk değerini verecektir.

resim.UnlockBits(bmpdata);

 

Burada ise daha önce ram üzerinde kilitleyip üzerinde işlemler yaptığımız bellek alanını resme geri atıyoruz.

Burada anlatılanları uygulamak için ufak bir uygulama ve çeşitli Gİ örnekleri Kod Kütüphanesinde yayınlanacaktır....

 

Yanlış olduğunu, tam açıklanmamış olduğunu düşündüğünüz veya eklenmesini istediğiniz bir yer varsa lütfen yorumlarınızla mesajı zenginleştiriniz...

Not: Fazla kod işlerine girmeden hazır Gİ kodları kullanmak isterseniz, C# ile hazırlanmış AForge kütüphanesini deneyebilirsiniz.

 

 


Augmented Reality (ArtırılmışGerçeklik)

Mart 11, 2009 22:08 tarihinde dandelo tarafndan eklenmistir.

   Pek de yeni olmayan ama pek de duyulmamış bir yazılım teknolojisini paylaşmak istedim. Türkçeye "Artırılmış Gerçeklik" olarak çevirebilceğimiz "Augmented Reality".

Kısaca bahsetmek gerekirse gerçek hayat ile bilgisayar grafiklerinin birleştirilip sunulduğu bir yapı diyebiliriz. Örneğin özel gözlüğünüzle bir reyona baktığınızda ürünler hakkında bilgilerinin gözünüzün önüne gelmesi, sadece siyah-beyaz referans resimlerin asılı olduğu bir salonda gezerek kendinizi piramitlerin içinde geziyormuş gibi hissetmek gibi desem pekte yalan olmaz.Bir örnek vermek istersek;

 

       Hakkında bir sürü kitaplar yazılan, üniversitelerde dersleri açılan, çeşitli firmalar tarafından frameworkleri çıkarılan sistem, gelecekte oyun sektörü, sinema sektörü, pazarlama ve reklam başta olmak üzere bir çok alanda kullanılacak gibi gözüküyor.Şehir planlama, oyun, müze, mobil sistemler, üretim ve mekan simulasyonu bunlardan sadece birkaçı...

 

      

 

       Flash ta dahil kullanabilceğiniz çeşitli kütüphaneler den biri de Artoolkit . Sitesinde sıfırdan başlayanlar için dökümanlardan, topluluklar ve çeşitli projelere kadar bir çok şey mevcuttur.

       İnsan-makine etkileşimini bir adım daha götüren teknoloji, bize gelecek hakkında bir fikir veriyor.

 


Dokunma-matik Etkileşim (Touchless Interactivity)

Ekim 14, 2008 14:26 tarihinde dandelo tarafndan eklenmistir.

    İnsan-bilgisayar etkileşimi konusunda son birkaç yıldır yaşadığımız gelişmeler özellikle yüzey teknolojilerinin gelişimi (örneğin Microsoft Surface) bize bilgisayar ile etkileşimde yeni bir bakış açısı kazandırmıştı, fikrin temelinde resim işleme sayesinde çoklu-dokunmatik ekranların farklı bir kullanıcı deneyimi sunması yatıyordu. Dokunmasız etkileşim ise bunu tamamiyle yüzeyi aradan kaldırarak yapıyor, artık bilgisayarınızı havada ellerinizle yönetmeniz gerçekten mümkün.

     Bu fikir Microsoft’ta yaz stajını yapan bir öğrenci olan Mike Wasserman’ın aklına gelmiş, yaptığı sunumu beğenen Office Labs ekibi projesini Microsoft açık kaynak kod paylaşım plaformu olan CodePlex’e koymasını önermiş ve artık proje online. Proje geçtiğimiz 6 günde 42 bin kişi tarafından incelenmiş, 13 bin kişi tarafından indirilmiş, işte paylaşımın gücüne güzel bir örnek.

Touchless nedir?

Touchless; basit bir webcam aracılığıyla bilgisayarınızı çoklu-dokunmatik özellikte kullanmanızı sağlayan açık kaynak kodlu yazılım geliştirme kitidir. Projenini .dll'leri kendi projenizde kullanarak bu yaratıcı fikri, hayalgücünüzün izin verdiği kadar farklı şekillerde kullanabilirsiniz.

"Nasıl Denerim?" 

Uygulamanın demo dosyalarını da içerek örneğini şu adresten indirip çalıştırdıktan sonra , web kamerasının karşısına geçip kontrol nesnesi olmasını istediğiniz iki nesneyi (tercihen ortamdan farklı renkli) elinize alıp, yeni bir marker ekle seçeneğini tıkladıktan sonra önce ilkini sonra da ikincisini işaretleyip demo butonuna tıklayarak demoları deneyebilirsiniz.
 
      İki açıdan bu geliştirme çok önemli duruyor, ilk olarak basit ve ucuz bir yöntem olması yaygınlaştırılabilmesini kolay kılıyor, basit bir web kamerasıyla inanılmaz sonuçlar almanız mümkün; ikinci olarak günümüzün gelişmiş işlemci yetenekleri sayesinde resim işleme yöntemi akademik bir çalışma olmaktan çıkarak artık bir öğrencinin yaz stajında geliştirdiği bir projenin parçası olabiliyor, iş bu kadar basite indirgenebiliyorsa bu alanda birçok innovasyon vakti geldi demektir. Önümüzdeki 3 yıl içerisinde çoklu-dokunma teknolojisi üzerine birçok projenin sektörün etkileşim bakış açısını sarsacağını kesin.

Önümüzdeki günlerde "Touchless InteractivitySDK" yı daha iyi inceleyip çeşitli örnekler vereceğim.
Detaylı Bilgi İçin

Projenin CodePlex Sayfası: http://www.codeplex.com/touchless
Touchless Demo Uygulaması İndirme Sayfası: http://www.codeplex.com/touchless/Release/ProjectReleases.aspx
Touchless Kaynak Kodu: http://www.codeplex.com/touchless/Release/ProjectReleases.aspx