lunes, 21 de junio de 2010

Imagenes

Codigo para binarizar una imagen y pasarla a escala de grises utilizando la clase Marshall, para esto, importamos el siguiente Namespace:

using System.Runtime.InteropServices;

codigo Marshall para escala de grises:

private void grayMarshall()
{

Bitmap n = (new Bitmap(pctbxImagPrincipal.Image));
Rectangle rec = new Rectangle(0, 0, n.Width, n.Height);
BitmapData bmpD = n.LockBits(rec, ImageLockMode.ReadWrite, n.PixelFormat);
IntPtr ptr = bmpD.Scan0;
int bytes = bmpD.Stride * n.Height;
byte[] rgbValues = new byte[bytes];
Marshal.Copy(ptr, rgbValues, 0, bytes);
for (int i = 3; i < rgbValues.Length; i += 4)
{
byte NewValue = (byte)((int)((rgbValues[i - 3]) * .11) + (int)((rgbValues[i - 2]) * .59) + (int)((rgbValues[i - 1]) * .3));
rgbValues[i - 1] = rgbValues[i - 2] = rgbValues[i - 3] = NewValue;
}
Marshal.Copy(rgbValues, 0, ptr, bytes);
n.UnlockBits(bmpD);
pctbxImagResult.Image = n;
}

codigo Marshall para binarizar imagen:
private void binmarshall()
{
Bitmap n = (new Bitmap(pctbxImagPrincipal.Image));
Rectangle rec = new Rectangle(0, 0, n.Width, n.Height);
BitmapData bmpD = n.LockBits(rec, ImageLockMode.ReadWrite, n.PixelFormat);
IntPtr ptr = bmpD.Scan0;
int bytes = bmpD.Stride * n.Height;
byte[] rgbValues = new byte[bytes];
Marshal.Copy(ptr, rgbValues, 0, bytes);
//DateTime start = DateTime.Now;
for (int i = 3; i < rgbValues.Length; i += 4)
{
byte NewValue = (byte)((int)((rgbValues[i - 3]) * .11) + (int)((rgbValues[i - 2]) * .59) + (int)((rgbValues[i - 1]) * .3) / 3);
if (NewValue <= 100)
{
rgbValues[i - 1] = rgbValues[i - 2] = rgbValues[i - 3] = 0;
}
else
{
rgbValues[i - 1] = rgbValues[i - 2] = rgbValues[i - 3] = 255;
}
}
Marshal.Copy(rgbValues, 0, ptr, bytes);
n.UnlockBits(bmpD);
pctbxImagResult.Image = n;
}

Ahora utilizando punteros para eficientar el proceso al pasar a escala de grises:
unsafe
{
Bitmap n = (new Bitmap(pctbxImagPrincipal.Image));
Rectangle rec = new Rectangle(0, 0, n.Width, n.Height);
BitmapData bmpD = n.LockBits(rec, ImageLockMode.ReadWrite, n.PixelFormat);
IntPtr ptr = bmpD.Scan0;
byte* RealPointer = (byte*)ptr.ToPointer();
int bytes = bmpD.Stride * n.Height;
for (int i = 3; i < bytes; i += 4)
{
byte NewValue = (byte)((int)((*(RealPointer + i - 3)) * .11) + (int)((*(RealPointer + i - 2)) * .59) + (int)((*(RealPointer + i - 1)) * .3));
RealPointer[i - 1] = RealPointer[i - 2] = RealPointer[i - 3] = NewValue;
}
n.UnlockBits(bmpD);
pctbxImagResult.Image = n;
}

otra forma muy conocida para tratar imagenes es utilizando los ciclos anidados:

escala de grises:

Bitmap n = (new Bitmap(pictureBox1.Image));
for (int i = 0; i < n.Width; i++)
{
for (int j = 0; j < n.Height; j++)
{
Color l = (n.GetPixel(i, j));
int k = l.ToArgb();
int rojo = (int)((k & 0x0000FF) * 0.3);
int Verde =(int)(((k & 0x00FF00) >> 8)*.59);
int blue = (int)(((k & 0xFF0000) >> 16)*.11);
int NColor = rojo + Verde + blue;
n.SetPixel(i, j, Color.FromArgb(NColor| NColor<<8| NColor<<16 | 255<<24 ));
}

}
pictureBox1.Image = n;

binarizacion :

Bitmap imagen = (new Bitmap(pictureBox1.Image));
for (int i = 0; i < n.Width; i++)
{
for (int j = 0; j < n.Height; j++)
{
Color l = (imagen.GetPixel(j, i));
int gris = (int)((l.R + l.B + l.G) / 3);
if (gris <= 100)
{
imagen.SetPixel(j, i, Color.Black);
}
else
{
imagen.SetPixel(j, i, Color.White);
}
}
}
pictureBox1.Image = n;

1 comentario:

CoMeNtArIoS y MaS...