Aug132010

tarayıcıdan taranmış bir resimde arka planı temizlemek - Image filte

Published by admin at 7:13 PM under

Diyelimki beyaz bir A4 kağıdına yazı yazdınız ve tarayıcıdan taradınız. Kağıdın beyaz olmasına rağmen tarayıcı da taranmış resimde

grimsi renkler belirir. Kağıttaki kırışıklıklar bile farklı bir renkte karşınıza gelir.

Eğer bir OCR programı veya benzeri bir işlemle o resmi işliyecekseniz, resmin arka planının komple bembeyaz olması istenir.

Aski takdirde resmi işlerken sorun çıkabilir. Arka planda gürültü yada noise diye tabir edilen bu renkler işlemi biraz zorlaştırabilir.

Bu sorundan kurtulmak için resmi bir filtreleme yaparak noise lardan arındırmak gerekmektedir.

Resmin bütün piksellerini tarayarak belli bir eşik değerinden küçük olan değerleri direk beyaza çevirirsek işlemimiz gerçekleşmiş olur.

Burda önemli olan bu eşik değerini tespit etmek. Resmin sahip olduğu renk paletine göre bu eşik değerini tespit edebilirsiniz.

böylece elinize noise lardan arındırılmış bir resim geçecektir ve bu resimle yapacağınız işlemler daha güvenilir olacaktır.

ben bu işlem için microsoftun yapmış olduğu aşağıdaki örnek C# kodundan faydalandım. Sizden bu şekilde yapıl isterseniz kaydetmeyi farklı bir formatta da yapabilirsiniz.

Aşağıdaki örnek gif üzerinden gitmiştir ama siz istediğiniz bir formatla da bu işlemi yapabilirsiniz.

 

System.Drawing ve GDI + yazılan, .gif dosyaları anlama

.Gif görüntü dosyası en fazla 256 renk ifade edebilirsiniz. Renk kıt kaynağın .gif dosyası olduğundan, bu renkleri en iyi duruma getirme sık istenen bir görevdir. Bir en iyi duruma getirilmiş renk tablosu uygulamak için herhangi bir rasgele bir özel renk tablo .gif dosya olmalıdır.

Öncelikle geçici GDI + bir sarmalayıcı System.Drawing ad ise, System.Drawing ad alanına özgü bir davranış, bu durumda, açıklanan sürece bu nedenle bu makalede ad alanına GDI + başvuruyor System.Drawing kullanılan bir terimdir.

GDI + Resim değiştirir ve GIF Kodlayıcısı'nı kullanarak görüntü bir dosyaya yazar sonra GDI + dosya görüntü nesnenin bit renk sınırlı olan bir yarı ton paleti kullanarak yazar. GDI + 32 bit / piksel (32 BPP) bir renk dönüşümü mu GDI + 32 BPP grafik altyapısıyla yapılan tüm değişiklikler görüntü için onu resmi dosyaya yazar.

GDI + görüntüler ve bit eşlemler olarak piksel oluşturulmasını destekler ve bu nedenle bir .gif resmini yükleyebilirsiniz, ancak, GDI + tarafından değiştirildiğinde, 32-BPP grafik altyapısı kullanımını 32 BPP dönüştürme necessitates. Ancak, bir resmi veya bit eşlem olan tarafından değişiklik GDI + piksel özgün biçimi korur ve uygun kodlayıcı ile kayıt yöntemini kullanarak bir dosyaya yazılır. Bu özellik bir Resim için bir <a0>özel renk</a0> tablosuyla .gif dosya kaydedebileceğiniz bir teknik temelini oluşturur.


Bir .gif sahip özel bir renk tablosu yazılıyor

Değiştirilmemiş bir bit eşlem GIF kodlayıcı ile yazma ve bit eşlem renk tablosu korumanız; bu nedenle, yeni bir renk tablo .gif dosya kaydetmek için bu yöntemi kullanabilirsiniz.

Özgün Resim nesneden resim verisi için geçici bir bit eşlem nesnesi kopyalamak yöntemdir. Bu geçici bir bit eşlem, 8 BPP, bit eşlem, .gif dosya kaydetmek için kullanılan piksel biçimi olan dizin olarak oluşturulur. Bit eşlem renk tablosu SetPalette yöntemini kullanarak ayarlayın ve sonra resim tanımı için bit eşlem geçici olarak kopyalanır. Bit eşlem geçici yinelenen bir tanımlama oluşturduktan sonra 8-BPP renk tablosunu koruyan GIF kodlayıcı ile kaydetmeyi Save() yöntemini kullanabilirsiniz.

Bir .gif resmini bir özel renk tablosu içeren bir dosyayı yazmak için şu adımları izleyin:

  1. Kaynak resmi aynı boyutta olan yinelenen bir bit eşlem nesnesi oluşturun.
  2. Özel renk tablosu <a0>bit eşlem</a0> nesnesinin, istediğiniz renk tabloya ayarlayın.
  3. Görüntü bitlerini kopyanın yazma erişim kazanmak için LockBits yöntemini kullanın.
  4. Bir resmi tanımı, kopya ile özgün Resim pikselleri yinelenen LockBits elde edilen bellek renk dizinleri yazarak oluşturun.
  5. Görüntü bitlerini yayımlamayı UnLockBits kullanın.
  6. Bit eşlem kopya ile özel bir renk tablosu kaydedip GIF Kodlayıcısı'nı kullanarak, görüntü bir dosyaya kaydetmek için kullanın.
  7. Resimbit eşlem kopyasını bırakın.

Örnek kodu kullanma

Bu makaledeki örnek kod Bitmap.Save rasgele bir boyuttaki bir özel renk tabloyla bir .gif dosyası yazmak için nasıl kullanılacağını gösterir. Amacı yalnızca gösteri olduğundan, kodu için performans getirilmemiştir. En iyi duruma getirme için en iyi fırsatlar döngü işleme piksel ' dir. GetPixel uygun bir Özet piksel biçimi olan ancak çok yavaş olacaktır. Örnek kod, LockBits piksel biçimi doğrudan erişmek için kullanılan, daha hızlı olacaktır. Hızını artırmak için <a0></a0>, GetPixel yöntemi ve renk sınıfı Özet kullanmayın. Performansı artırmak için <a0></a0>, gri tonlamalı dönüştürme tamsayı matematik kullanarak yerine kayan nokta yeniden yazın.

Örnek işlevi, aşağıdaki dört parametreleri alır:

  • Tüm GDI + Resim nesnesi.
  • Hedef dosya için dosya adı.
  • .Gif dosyası için renk sayısı.
  • Saydam bir renk gerekli olup olmadığını gösteren bayrak.

Işlevi ilk olarak, nColors ile .gif dosyası oluşturmak için kayıtlı olan bir nesne olduğundan PixelFormat.Format8BPPIndexed piksel biçimi olan bir bit eşlem nesnesi oluşturur. Sonra bir renk paleti özel renk ile oluşturulur. .Gif dosyasını, bit eşlem nesnenin ColorPalette boyutunu ve belirli kendi renk tablosu girdileri alır. Bu algoritma çeşitli renk tablo boyutunu genişletmek kolay olduğundan, gri ölçek gösteri amaçlı örnek kodu oluşturur.

.Gif dosyası oluşturmak için <a0></a0>, dosyaya yazılacak olan görüntü tanımıyla birlikte 8 BPP bitmap nesnesini yeniden başlatmalısınız. Örnek kodda, bir merkez döngü için kullanılan kümesidir renk aslında siyah ve beyaz TV renk uzayına gelen görüntü dönüştürme.

Gösteri amaçlı kaynak resim pikselleri kaynak resme bir kopyası bir bit eşlem nesnesi GetPixel() yöntemi yoluyla erişilir. Resim sınıfı GetPixel() yöntemi uygulamadığından, bit eşlem kopyasını yapılır.

Piksel piksel, Windows GDI DIB bölümleri ' ni kullanarak yerel yönetilmeyen kod ile birlikte çalışma ve LockBits() yöntemi kullanarak doğrudan erişim gibi erişmek için diğer teknikleri kullanabilirsiniz. Gdi + HDC GDI DIB bölüm için bir bit eşlem kopyalamak BitBlt işlevini kullandığınızda bellek etki alanı denetleyicisi, GDI yeteneklerini eşleştirme rengi kullanır GBitBlt çalışır.

Bit eşlem kopya oluşturduktan sonra kayıt yöntemi ImageFormat.gif nesnesiyle bit eşlem, hedef dosyaya yazmak için kullanın.


GIF dosyaları ile az 256 renk

GDI + sürümü 1.0 GIF codec bileşeni, 8 BPP yalnızca GDI + görüntüleri kodlar. Tüm Resim biçimleri, önce kodlama dönüştürülür. Bu kod, GIF codec Palette.Count özelliği tarafından daha az 256 renk içeren 8 BPP bit eşlem nesneleri tanıdığı için renk sayısı 256'dan az olan .gif dosyaları yazmak için 8-BPP bit eşlem biçimi kullanın.


Ne yazık ki, .NET Framework System.Drawing ad ColorPalette sınıfını bağımsız bir <a0>bit eşlem</a0> nesnesinin örneği oluşturulamıyor. .NET Framework'de System.Drawing.Bitmap sınıfı uygular bir kısıtlama budur; ancak, bu makaledeki yaklaşım kullanmak için <a0></a0>, bit eşlem nesnesi varsayılan değerinden daha az renk içeren yeni bir ColorPalette nesnesi olmalıdır 256 ColorPalette.

Bunu başarmak için <a0></a0>, örnek kod, GetColorPalette adlı bir işlevi tanımlar. Bu işlev, yakın bir istenen sayıda renk için renk derinliği olan geçici bir bit eşlem nesnesi oluşturur. Işlev paleti özelliği başvurur ve çağrıyı geri döndürür. Bu yeni bir ColorPalette birkaç olası renk sayımları biriyle oluşturur: 256 renk, 16 renk veya iki renk (tek renkli). 256 Renkten küçük olan .gif dosyaları renk tablo oluşturabilirsiniz, ancak renkli ikinin üssü boyutları için sınırlı tablolarıdır.

Renk tablosu ölçüde ikinin üssü sınırlamak, harcanan alanı en aza indirin. Bu örnek, elde edilen renk tablosu 8 renk (2 x 2 x 2) ' dir. Bir bit eşlem o accomodates altı küçük PixelFormat, çünkü ile örnek kod, .gif dosyası 16 renk renk tablosu oluşturulması renkleri.

Kod bir pikselin dizin değeri hesaplar, görüntünün piksel tanımları için bit eşlem 8 BPP kopyaladığı işleme döngü kodu, palet boyutu dikkate alınır. GIF codec palet boyutunu sınırlar ve görüntü tanımı için palet boyutu (diğer bir deyişle, olası GIF renk tablo) ile uyumlu değildir ve bu nedenle, .gif dosyaları daha az 256 renk oluşturabilirsiniz dizin değerlerini kısıtlar.

GIF saydamlık

Örnek kodda, ColorPalette oluşturma yordamının ilk girdiden saydamlık özelliği kullanımını gösteren GIF saydam renk olarak ayarlar. Kod SıFıR için <a0>renk</a0> girdisinin Alpha bileşeni'ni ayarlayarak bunu yapar. Bu makaledeki örnek kod, yalnızca gösterim amacıyla kullanılır, bu nedenle, saydam renk bir rasgele seçim ve olabilir tamamen kaynak üzerinde Resim bağımlı beklenmeyen sonuçlar.

GIF kodlayıcı ilk rengi saydam renk olarak SıFıR değeri bir alfa ColorPalette tanımlar. Bu, ColorPalette dosyasındaki ilk girdi saydam renk yok anlamına gelir. Alpha bileşenleri sıfır dışında değerler içeren tüm önceki girişleri içeren koşuluyla, herhangi biri palette, olası 256 renkte olabilir. Bileşen değerlerini SıFıR Alpha ile sonraki tüm girişleri dikkate alınmaz. Sıfır olmayan alfa bileşenleri yüklü olan tüm girdileri opak olarak düşünülür.

 

Örnek kod

protected ColorPalette GetColorPalette( uint nColors )
{
// Assume monochrome image.
PixelFormat bitscolordepth = PixelFormat.Format1bppIndexed;
ColorPalette palette; // The Palette we are stealing
Bitmap bitmap; // The source of the stolen palette

// Determine number of colors.
if (nColors > 2)
bitscolordepth = PixelFormat.Format4bppIndexed;
if (nColors > 16)
bitscolordepth = PixelFormat.Format8bppIndexed;

// Make a new Bitmap object to get its Palette.
bitmap = new Bitmap( 1, 1, bitscolordepth );

palette = bitmap.Palette; // Grab the palette

bitmap.Dispose(); // cleanup the source Bitmap

return palette; // Send the palette back
}

protected void SaveGIFWithNewColorTable(
Image image,
string filename,
uint nColors,
bool fTransparent
)
{

// GIF codec supports 256 colors maximum, monochrome minimum.
if (nColors > 256)
nColors = 256;
if (nColors < 2)
nColors = 2;

// Make a new 8-BPP indexed bitmap that is the same size as the source image.
int Width = image.Width;
int Height = image.Height;

// Always use PixelFormat8bppIndexed because that is the color
// table-based interface to the GIF codec.
Bitmap bitmap = new Bitmap(Width,
Height,
PixelFormat.Format8bppIndexed);

// Create a color palette big enough to hold the colors you want.
ColorPalette pal = GetColorPalette(nColors);

// Initialize a new color table with entries that are determined
// by some optimal palette-finding algorithm; for demonstration
// purposes, use a grayscale.
for (uint i = 0; i < nColors; i++)
{
uint Alpha = 0xFF; // Colors are opaque.
uint Intensity = i*0xFF/(nColors-1); // Even distribution.

// The GIF encoder makes the first entry in the palette
// that has a ZERO alpha the transparent color in the GIF.
// Pick the first one arbitrarily, for demonstration purposes.

if ( i == 0 && fTransparent) // Make this color index...
Alpha = 0; // Transparent

// Create a gray scale for demonstration purposes.
// Otherwise, use your favorite color reduction algorithm
// and an optimum palette for that algorithm generated here.
// For example, a color histogram, or a median cut palette.
pal.Entries[i] = Color.FromArgb( (int)Alpha,
(int)Intensity,
(int)Intensity,
(int)Intensity );
}

// Set the palette into the new Bitmap object.
bitmap.Palette = pal;


// Use GetPixel below to pull out the color data of Image.
// Because GetPixel isn't defined on an Image, make a copy
// in a Bitmap instead. Make a new Bitmap that is the same size as the
// image that you want to export. Or, try to
// interpret the native pixel format of the image by using a LockBits
// call. Use PixelFormat32BppARGB so you can wrap a Graphics
// around it.
Bitmap BmpCopy = new Bitmap(Width,
Height,
PixelFormat.Format32bppArgb);
{
Graphics g = Graphics.FromImage(BmpCopy);

g.PageUnit = GraphicsUnit.Pixel;

// Transfer the Image to the Bitmap
g.DrawImage(image, 0, 0, Width, Height);

// g goes out of scope and is marked for garbage collection.
// Force it, just to keep things clean.
g.Dispose();
}

// Lock a rectangular portion of the bitmap for writing.
BitmapData bitmapData;
Rectangle rect = new Rectangle(0, 0, Width, Height);

bitmapData = bitmap.LockBits(
rect,
ImageLockMode.WriteOnly,
PixelFormat.Format8bppIndexed);

// Write to the temporary buffer that is provided by LockBits.
// Copy the pixels from the source image in this loop.
// Because you want an index, convert RGB to the appropriate
// palette index here.
IntPtr pixels = bitmapData.Scan0;

unsafe
{
// Get the pointer to the image bits.
// This is the unsafe operation.
byte * pBits;
if (bitmapData.Stride > 0)
pBits = (byte *)pixels.ToPointer();
else
// If the Stide is negative, Scan0 points to the last
// scanline in the buffer. To normalize the loop, obtain
// a pointer to the front of the buffer that is located
// (Height-1) scanlines previous.
pBits = (byte *)pixels.ToPointer() + bitmapData.Stride*(Height-1);
uint stride = (uint)Math.Abs(bitmapData.Stride);

for ( uint row = 0; row < Height; ++row )
{
for ( uint col = 0; col < Width; ++col )
{
// Map palette indexes for a gray scale.
// If you use some other technique to color convert,
// put your favorite color reduction algorithm here.
Color pixel; // The source pixel.

// The destination pixel.
// The pointer to the color index byte of the
// destination; this real pointer causes this
// code to be considered unsafe.
byte * p8bppPixel = pBits + row*stride + col;

pixel = BmpCopy.GetPixel((int)col, (int)row);

// Use luminance/chrominance conversion to get grayscale.
// Basically, turn the image into black and white TV.
// Do not calculate Cr or Cb because you
// discard the color anyway.
// Y = Red * 0.299 + Green * 0.587 + Blue * 0.114

// This expression is best as integer math for performance,
// however, because GetPixel listed earlier is the slowest
// part of this loop, the expression is left as
// floating point for clarity.

double luminance = (pixel.R *0.299) +
(pixel.G *0.587) +
(pixel.B *0.114);

// Gray scale is an intensity map from black to white.
// Compute the index to the grayscale entry that
// approximates the luminance, and then round the index.
// Also, constrain the index choices by the number of
// colors to do, and then set that pixel's index to the
// byte value.
*p8bppPixel = (byte)(luminance * (nColors-1)/255 +0.5);

} /* end loop for col */
} /* end loop for row */
} /* end unsafe */

// To commit the changes, unlock the portion of the bitmap.
bitmap.UnlockBits(bitmapData);

bitmap.Save(filename, ImageFormat.Gif);

// Bitmap goes out of scope here and is also marked for
// garbage collection.
// Pal is referenced by bitmap and goes away.
// BmpCopy goes out of scope here and is marked for garbage
// collection. Force it, because it is probably quite large.
// The same applies to bitmap.
BmpCopy.Dispose();
bitmap.Dispose();

}




[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Responses