private static Bitmap ConvolutionFilter(Bitmap sourceImage,
double[,] xkernel,
double[,] ykernel, double factor = 1, int bias = 0, bool grayscale = false)
{
//Image dimensions stored in variables for convenience
int width = sourceImage.Width;
int height = sourceImage.Height;
//Lock source image bits into system memory
BitmapData srcData = sourceImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
//Get the total number of bytes in your image - 32 bytes per pixel x image width x image height -> for 32bpp images
int bytes = srcData.Stride * srcData.Height;
//Create byte arrays to hold pixel information of your image
byte[] pixelBuffer = new byte[bytes];
byte[] resultBuffer = new byte[bytes];
//Get the address of the first pixel data
IntPtr srcScan0 = srcData.Scan0;
//Copy image data to one of the byte arrays
Marshal.Copy(srcScan0, pixelBuffer, 0, bytes);
//Unlock bits from system memory -> we have all our needed info in the array
sourceImage.UnlockBits(srcData);
//Convert your image to grayscale if necessary
if (grayscale == true)
{
float rgb = 0;
for (int i = 0; i < pixelBuffer.Length; i += 4)
{
rgb = pixelBuffer[i] * .21f;
rgb += pixelBuffer[i + 1] * .71f;
rgb += pixelBuffer[i + 2] * .071f;
pixelBuffer[i] = (byte)rgb;
pixelBuffer[i + 1] = pixelBuffer[i];
pixelBuffer[i + 2] = pixelBuffer[i];
pixelBuffer[i + 3] = 255;
}
}
//Create variable for pixel data for each kernel
double xr = 0.0;
double xg = 0.0;
double xb = 0.0;
double yr = 0.0;
double yg = 0.0;
double yb = 0.0;
double rt = 0.0;
double gt = 0.0;
double bt = 0.0;
//This is how much your center pixel is offset from the border of your kernel
//Sobel is 3x3, so center is 1 pixel from the kernel border
int filterOffset = 1;
int calcOffset = 0;
int byteOffset = 0;
//Start with the pixel that is offset 1 from top and 1 from the left side
//this is so entire kernel is on your image
for (int OffsetY = filterOffset; OffsetY < height - filterOffset; OffsetY++)
{
for (int OffsetX = filterOffset; OffsetX < width - filterOffset; OffsetX++)
{
//reset rgb values to 0
xr = xg = xb = yr = yg = yb = 0;
rt = gt = bt = 0.0;
//position of the kernel center pixel
byteOffset = OffsetY * srcData.Stride + OffsetX * 4;
//Create new bitmap which will hold the processed data
Bitmap resultImage = new Bitmap(width, height);
//Lock bits into system memory
BitmapData resultData = resultImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
//Copy from byte array that holds processed data to bitmap
Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length);
//Unlock bits from system memory
resultImage.UnlockBits(resultData);
//Return processed image
return resultImage;
}
//Sobel operator kernel for horizontal pixel changes
private static double[,] xSobel
{
get
{
return new double[,]
{
{ -1, 0, 1 },
{ -2, 0, 2 },
{ -1, 0, 1 }
};
}
}
//Sobel operator kernel for vertical pixel changes
private static double[,] ySobel
{
get
{
return new double[,]
{
{ 1, 2, 1 },
{ 0, 0, 0 },
{ -1, -2, -1 }
};
}
}
double[,] xkernel,
double[,] ykernel, double factor = 1, int bias = 0, bool grayscale = false)
{
//Image dimensions stored in variables for convenience
int width = sourceImage.Width;
int height = sourceImage.Height;
//Lock source image bits into system memory
BitmapData srcData = sourceImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
//Get the total number of bytes in your image - 32 bytes per pixel x image width x image height -> for 32bpp images
int bytes = srcData.Stride * srcData.Height;
//Create byte arrays to hold pixel information of your image
byte[] pixelBuffer = new byte[bytes];
byte[] resultBuffer = new byte[bytes];
//Get the address of the first pixel data
IntPtr srcScan0 = srcData.Scan0;
//Copy image data to one of the byte arrays
Marshal.Copy(srcScan0, pixelBuffer, 0, bytes);
//Unlock bits from system memory -> we have all our needed info in the array
sourceImage.UnlockBits(srcData);
//Convert your image to grayscale if necessary
if (grayscale == true)
{
float rgb = 0;
for (int i = 0; i < pixelBuffer.Length; i += 4)
{
rgb = pixelBuffer[i] * .21f;
rgb += pixelBuffer[i + 1] * .71f;
rgb += pixelBuffer[i + 2] * .071f;
pixelBuffer[i] = (byte)rgb;
pixelBuffer[i + 1] = pixelBuffer[i];
pixelBuffer[i + 2] = pixelBuffer[i];
pixelBuffer[i + 3] = 255;
}
}
//Create variable for pixel data for each kernel
double xr = 0.0;
double xg = 0.0;
double xb = 0.0;
double yr = 0.0;
double yg = 0.0;
double yb = 0.0;
double rt = 0.0;
double gt = 0.0;
double bt = 0.0;
//This is how much your center pixel is offset from the border of your kernel
//Sobel is 3x3, so center is 1 pixel from the kernel border
int filterOffset = 1;
int calcOffset = 0;
int byteOffset = 0;
//Start with the pixel that is offset 1 from top and 1 from the left side
//this is so entire kernel is on your image
for (int OffsetY = filterOffset; OffsetY < height - filterOffset; OffsetY++)
{
for (int OffsetX = filterOffset; OffsetX < width - filterOffset; OffsetX++)
{
//reset rgb values to 0
xr = xg = xb = yr = yg = yb = 0;
rt = gt = bt = 0.0;
//position of the kernel center pixel
byteOffset = OffsetY * srcData.Stride + OffsetX * 4;
//Create new bitmap which will hold the processed data
Bitmap resultImage = new Bitmap(width, height);
//Lock bits into system memory
BitmapData resultData = resultImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
//Copy from byte array that holds processed data to bitmap
Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length);
//Unlock bits from system memory
resultImage.UnlockBits(resultData);
//Return processed image
return resultImage;
}
//Sobel operator kernel for horizontal pixel changes
private static double[,] xSobel
{
get
{
return new double[,]
{
{ -1, 0, 1 },
{ -2, 0, 2 },
{ -1, 0, 1 }
};
}
}
//Sobel operator kernel for vertical pixel changes
private static double[,] ySobel
{
get
{
return new double[,]
{
{ 1, 2, 1 },
{ 0, 0, 0 },
{ -1, -2, -1 }
};
}
}
No comments:
Post a Comment