Rss Feed

C# ile Görüntü İşleme – 1

Tarih: November 23rd, 2008 | Yazan: Ahmet Kakıcı | Kategori: Programlama | Etiketler: , , | 12 Yorum »

Blogda bu kadar kod dolu yazılar yazmak konusunda kararszıdım ama yine de bir kez denemek istedim bakalım ilgi olacak mı.

Görüntü işleme ile ilgili temel bilgileri biliyorsunuz farzederek bu yazıyı yazıyorum. Zira işin hikaye kısmını yazması biraz zor oluyor diyerekten konuya geçelim.

Görüntü işleme sırasında image veya bitmap nesneleri üzerinde işlem yapmak yerine dizileri kullanıyorum ondan dolayı aşağıdaki kodlarda da bütün işlemler diziler üzerinde olacak. Kullandığım birçok fonksiyon pointer kullanarak çalışıyor. C# ile nasıl pointer kullanacağınızı bilmiyorsanız şurada bulunan yazımı okuyabilirsiniz.

Öncelikle picturebox nesnesinden diziye dönüşüm işlemini yapan fonksiyonu verelim:


int[,] pixelArray = new int[pictureBox1.Image.Height, pictureBox1.Image.Width];
int[,] greyPixelArray = new int[pictureBox1.Image.Height, pictureBox1.Image.Width];

private void BuildPixelArray(Image myImage)
{
Rectangle rect = new Rectangle(0, 0, myImage.Width, myImage.Height);
Bitmap temp = new Bitmap(myImage);
BitmapData bmpData = temp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int remain = bmpData.Stride - bmpData.Width * 3;
unsafe
{
byte* ptr = (byte*)bmpData.Scan0;
for (int i = 0; i < bmpData.Height; i++)
{
for (int j = 0; j < bmpData.Width; j++)
{
pixelArray[i, j] = ptr[0] + ptr[1] * 255 + ptr[2] * 255 * 255;
greyPixelArray[i, j] = (int)((double)ptr[0] * 0.11 + (double)ptr[1] * 0.59 + (double)ptr[2] * 0.3);
ptr += 3;
}
ptr += remain;
}
}
temp.UnlockBits(bmpData);
}

Bu fonksiyon sayesinde picturebox nesnesindeki görüntüyü pixelArray dizisine taşıyoruz. Aynı fonksiyonda greyPixelArray dizisi ile tutulan griseviye görüntü de oluşturuluyor.

Dizideki görüntüyü form üzerinde bulunan bir picturebox nesnesine aktarmak için aşağıdaki fonksiyonu kullanabilirsiniz.


private void SetImage(int[,] sourceArray, ref PictureBox myPictureBox)
{
Rectangle rect = new Rectangle(0, 0, myPictureBox.Image.Width, myPictureBox.Image.Height);
Bitmap temp = new Bitmap(myPictureBox.Image);
BitmapData bmpData = temp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int remain = bmpData.Stride - bmpData.Width * 3;
unsafe
{
byte* ptr = (byte*)bmpData.Scan0;
for (int i = 0; i < bmpData.Height; i++)
{
for (int j = 0; j < bmpData.Width; j++)
{
ptr[0] = ptr[1] = ptr[2] = (byte)sourceArray[i, j];
ptr += 3;
}
ptr += remain;
}
}
temp.UnlockBits(bmpData);
myPictureBox.Image = temp;
}

Üstteki fonksiyon aldığı diziyi gri seviye olarak değerlendiriyor. Eğer renkli bir görüntünüz varsa bir aşağıdaki fonksiyonu kullanabilirsiniz


public void SetColorImage(ref int[,] sourceArray)
{
Rectangle rect = new Rectangle(0, 0, sourceArray.GetLength(0), sourceArray.GetLength(1));
Bitmap temp = new Bitmap(sourceArray.GetLength(0), sourceArray.GetLength(1));
BitmapData bmpData = temp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int remain = bmpData.Stride - bmpData.Width * 3;
unsafe
{
byte* ptr = (byte*)bmpData.Scan0;
for (int i = 0; i < bmpData.Width; i++)
{
for (int j = 0; j < bmpData.Height; j++)
{
ptr[0] = (byte)(sourceArray[i, j]%256);
ptr[1] = (byte)((sourceArray[i, j]/256)%256);
ptr[2] = (byte)((sourceArray[i, j]/65536)%256);
ptr += 3;
}
ptr += remain;
}
}
temp.UnlockBits(bmpData);
destPictBox.Image = temp;
}

Görüntüyü yeniden boyutlandırmak için aşağıdaki fonksiyonu kullanabilirsiniz. ConstWidth değişkenine istediğiniz değeri vererek işlem sonucundaki görüntünün enini ayarlayabilirsiniz. Ben tüm görüntüleri standart boyuta getirmek için böyle bir yol kullanmıştım. Fonksiyonun çalışmasını kolaylıkla anlayabilir ve istediğiniz en-boy değiştirme işlemini kolayca yapabilirsiniz.


private void ResizeImage(ref Image myImage)
{
float nPercent = ((float)constWidth / myImage.Width);
int sourceWidth = myImage.Width;
int sourceHeight = myImage.Height;
int sourceX = 0;
int sourceY = 0;

int destX = 0;
int destY = 0;
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);

Bitmap bmPhoto = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(myImage.HorizontalResolution, myImage.VerticalResolution);

Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.DrawImage(myImage,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
myImage = bmPhoto;
grPhoto.Dispose();
}

Kenar algılama, gürültü yok etme ve yapısal (morfolojik) filtreleri de bir sonraki yazımda paylaşmak üzere. İyi işlemeler diliyorum :)

Benzer yazılar:

  1. Programlama İpuçları


12 Comments on “C# ile Görüntü İşleme – 1”

  1. 1 C# ile Görüntü İşleme - 2 | Ahmet Kakıcı said at 16:31 on January 2nd, 2009:

    [...] önce görüntü okuma, gösterme ve kaydetme gibi başlıca fonksiyonları vermiştim. Aşağıda ise asıl görüntüyü işeyecek fonksiyonlar bulunmaktadır. Tabii buradaki [...]

  2. 2 Anonymous said at 11:31 on March 23rd, 2009:

    çok teşekkürler hocam…

  3. 3 C# ile Görüntü İşleme - 3 | Ahmet Kakıcı said at 11:27 on June 4th, 2009:

    [...] iki yazının ardından ( 1 – 2 ) sonunda üçüncü yazıyı da yazabildim. Bu yazıya sadece morfolojik filtreler kaldı. [...]

  4. 4 taemmyheas said at 00:11 on May 11th, 2010:

    meraba bi sorum olacaktı. c#ta grafiği resıme nasıl donusturebiliriz. yardımcı olursanız sevınırım.

  5. 5 Ahmet Kakıcı said at 12:48 on May 14th, 2010:

    Soruyu biraz daha açabilir misiniz ?

  6. 6 Emrah Hançer said at 17:25 on June 1st, 2010:

    Ahmet Kardeş,
    greyPixelArray[i, j] = (int)((double)ptr[0] * 0.3 + (double)ptr[1] * 0.59 + (double)ptr[2] * 0.11);

    0.3 ile 0.11 i yerdeğiştirerek yazmak gerekli. Bu hata tam 3 saatime mal oldu. Kolay gelsin…

  7. 7 Ahmet Kakıcı said at 21:32 on June 1st, 2010:

    Emrah katsayıların seçimi tamamen sana kalmış. İstersen toplayıp üçe de bölebilirdin.

  8. 8 feridun said at 18:18 on June 25th, 2010:

    hocam slm.
    C# ile H.263 ve H.264 ya da open source ya da webM ile msn yapılabilirse performansı sizce ne olur? bide tasarım kalıpları türkçe kaynak elinizde varmı ?

  9. 9 Ahmet Kakıcı said at 19:50 on June 25th, 2010:

    Performansı anlamanın en iyi yolu denemek olacaktır :)
    Tasarım kalıpları için yan tarafta da bağlantısı bulunan Emre Çevik’in sitesine göz atabilirsin:
    http://code.internet.com.tr/kategori/php/designpatterns/

  10. 10 feridun said at 23:14 on June 25th, 2010:

    hocam teşekkürler…

  11. 11 selami said at 04:21 on August 27th, 2010:

    eline sağlık verdiğin bilgiler için…

    resim için seçilen bir bölgenin kes kopyala yapıştır işlemlerinin yapılması hakkında bir çalışman oldu mu acaba ?
    olduysa eğer, bunu paylaşman çok faydalı olacaktır.

  12. 12 Ahmet Kakıcı said at 12:15 on August 28th, 2010:

    Kesme işlemi için çalışacağınız pikselleri uç noktalardan değil arada alacağınız noktalardan seçerseniz yapabilirsiniz.


Leave a Reply