void Start_Contour_Detection()
{
// Copy original image to new bitmap
Bitmap bmp = (Bitmap)Original_image.Clone();
int Image_width = bmp.Width;
int Image_height = bmp.Height;
// Rectangle size
Rectangle Rectangle = new Rectangle(0, 0, Image_width, Image_height);
// Lock bitmap inside memory for faster processing and load bitmap data
BitmapData bmp_Data = bmp.LockBits(Rectangle, ImageLockMode.ReadWrite, bmp.PixelFormat);
// Load adress of the first byte of the bitmap,
// it is pointer to the adress
IntPtr bmp_First_byte_adress = bmp_Data.Scan0;
int Number_of_pixels = Image_width * Image_height;
int Number_of_bytes = Number_of_pixels * 3;
int Exact_number_of_bytes_in_row = bmp_Data.Stride;
int Necessary_number_of_bytes = Image_width*3;
//
int Number_of_alignment_bytes = Exact_number_of_bytes_in_row - Necessary_number_of_bytes;
//
// Total count of bytes necesary for all image pixels
Number_of_bytes += Image_height * Number_of_alignment_bytes;
//
// One dimensional matrix for memorizing bitmap
// values of RGB components of color of pixels
byte[] bmp_RGB_values = new byte[Number_of_bytes];
// Copy values of RGB components of pixel color from bitmap to matrix
Marshal.Copy(bmp_First_byte_adress, bmp_RGB_values, 0, Number_of_bytes);
// Two dimensional matrix for memorizing bitmap
// values of RGB components of color of pixels
byte [,,] RGB = new byte[Image_width,Image_height,3];
// Matrix for memorizing values of brightness of pixels
float [,] Brightness = new float[Image_width,Image_height];
// Byte counter inside one dimenzional matrix
int bmp_k = 0;
// Copy bitmap values of RGB components of color of pixels,
// from one dimenzional to two dimenzional matrix
// and fill matrix Brightness with values of brightness of pixels
//
// NOTICE :
// When loading bitmap data
// BitmapData bmp_Data = bmp.LockBits(Rectangle, ImageLockMode.ReadWrite, bmp.PixelFormat); ,
// values of RGB components of color of pixels are returned in opposite direction
// RGB -> BGR
//
for (int i=0;i<Image_height;i++)
{
for(int j=0;j<Image_width;j++)
{
// Value of R component of pixel color
RGB[j,i,0] = bmp_RGB_values[bmp_k+2];
// Value of G component of pixel color
RGB[j,i,1] = bmp_RGB_values[bmp_k+1];
// Value of B component of pixel color
RGB[j,i,2] = bmp_RGB_values[bmp_k+0];
// Value of pixel brightness
Brightness[j,i] = Color.FromArgb
(
bmp_RGB_values[bmp_k+2],
bmp_RGB_values[bmp_k+1],
bmp_RGB_values[bmp_k+0]
).GetBrightness();
bmp_k+=3;
}
bmp_k+= Number_of_alignment_bytes;
}
// Load lower and upper limit of the brightness
float lower_limit = (float) Lower_Brightness_Limit.Value;
float upper_limit = (float) Upper_Brightness_Limit.Value;
// Maximum found value for the difference in brightness
// between the opposing pixels
float mfd = 0;
for(int i=1;i<Image_height-1;i++)
{
for(int j=1;j<Image_width-1;j++)
{
//
mfd = Math.Abs(Brightness[j-1,i-1]-Brightness[j+1,i+1]);
//
if(mfd<Math.Abs(Brightness[j-1,i+1]-Brightness[j+1,i-1]))
mfd=Math.Abs(Brightness[j-1,i+1]-Brightness[j+1,i-1]);
//
if(mfd<Math.Abs(Brightness[j,i+1]-Brightness[j,i-1]))
mfd=Math.Abs(Brightness[j,i+1]-Brightness[j,i-1]);
//
if(mfd<Math.Abs(Brightness[j-1,i]-Brightness[j+1,i]))
mfd=Math.Abs(Brightness[j-1,i]-Brightness[j+1,i]);
//
if(Invert_Edge_Color.Checked)
{
if(mfd<lower_limit)
{
RGB[j,i,0] = (byte) 255;
RGB[j,i,1] = (byte) 255;
RGB[j,i,2] = (byte) 255;
}
else if(mfd>upper_limit)
{
RGB[j,i,0] = (byte) 0;
RGB[j,i,1] = (byte) 0;
RGB[j,i,2] = (byte) 0;
}
}
else
{
if(mfd<lower_limit)
{
RGB[j,i,0] = (byte) 0;
RGB[j,i,1] = (byte) 0;
RGB[j,i,2] = (byte) 0;
}
else if(mfd>upper_limit)
{
RGB[j,i,0] = (byte) 255;
RGB[j,i,1] = (byte) 255;
RGB[j,i,2] = (byte) 255;
}
}
}
}
if(Black_White.Checked)
{
for(int i=1;i<Image_height-1;i++)
{
for(int j=1;j<Image_width-1;j++)
{
if(Invert_Edge_Color.Checked)
{
if(RGB[j,i,0] < 255 || RGB[j,i,1] < 255 || RGB[j,i,2] < 255)
RGB[j,i,0] = RGB[j,i,1] = RGB[j,i,2] = (byte) 0;
}
else
{
if(RGB[j,i,0] > 0 || RGB[j,i,1] > 0 || RGB[j,i,2] > 0)
RGB[j,i,0] = RGB[j,i,1] = RGB[j,i,2] = (byte) 255;
}
}
}
}
if(Gray_Scale.Checked)
{
for(int i=1;i<Image_height-1;i++)
{
for(int j=1;j<Image_width-1;j++)
{
RGB[j,i,0] = RGB[j,i,1] = RGB[j,i,2] =
(byte)
(
(0.299*RGB[j,i,0]) +
(0.587*RGB[j,i,1]) +
(0.114*RGB[j,i,2])
);
}
}
}
// Byte counter inside one dimenzional matrix
bmp_k = 0;
// Copy new bitmap values of RGB components of color of pixels,
// from two dimenzional to one dimenzional matrix
for (int i=0;i<Image_height;i++)
{
for(int j=0;j<Image_width;j++)
{
// Value of R component of pixel color
bmp_RGB_values[bmp_k+2] = RGB[j,i,0];
// Value of G component of pixel color
bmp_RGB_values[bmp_k+1] = RGB[j,i,1];
// Value of B component of pixel color
bmp_RGB_values[bmp_k+0] = RGB[j,i,2];
bmp_k+=3;
}
bmp_k+=Number_of_alignment_bytes;
}
// Copy new values of RGB components of pixel color from matrix back to bitmap
Marshal.Copy(bmp_RGB_values, 0, bmp_First_byte_adress, Number_of_bytes);
// Unlock bitmap inside memory
bmp.UnlockBits(bmp_Data);
// Show the processed image
Image_2.Image = bmp;
}
{
// Copy original image to new bitmap
Bitmap bmp = (Bitmap)Original_image.Clone();
int Image_width = bmp.Width;
int Image_height = bmp.Height;
// Rectangle size
Rectangle Rectangle = new Rectangle(0, 0, Image_width, Image_height);
// Lock bitmap inside memory for faster processing and load bitmap data
BitmapData bmp_Data = bmp.LockBits(Rectangle, ImageLockMode.ReadWrite, bmp.PixelFormat);
// Load adress of the first byte of the bitmap,
// it is pointer to the adress
IntPtr bmp_First_byte_adress = bmp_Data.Scan0;
int Number_of_pixels = Image_width * Image_height;
int Number_of_bytes = Number_of_pixels * 3;
int Exact_number_of_bytes_in_row = bmp_Data.Stride;
int Necessary_number_of_bytes = Image_width*3;
//
int Number_of_alignment_bytes = Exact_number_of_bytes_in_row - Necessary_number_of_bytes;
//
// Total count of bytes necesary for all image pixels
Number_of_bytes += Image_height * Number_of_alignment_bytes;
//
// One dimensional matrix for memorizing bitmap
// values of RGB components of color of pixels
byte[] bmp_RGB_values = new byte[Number_of_bytes];
// Copy values of RGB components of pixel color from bitmap to matrix
Marshal.Copy(bmp_First_byte_adress, bmp_RGB_values, 0, Number_of_bytes);
// Two dimensional matrix for memorizing bitmap
// values of RGB components of color of pixels
byte [,,] RGB = new byte[Image_width,Image_height,3];
// Matrix for memorizing values of brightness of pixels
float [,] Brightness = new float[Image_width,Image_height];
// Byte counter inside one dimenzional matrix
int bmp_k = 0;
// Copy bitmap values of RGB components of color of pixels,
// from one dimenzional to two dimenzional matrix
// and fill matrix Brightness with values of brightness of pixels
//
// NOTICE :
// When loading bitmap data
// BitmapData bmp_Data = bmp.LockBits(Rectangle, ImageLockMode.ReadWrite, bmp.PixelFormat); ,
// values of RGB components of color of pixels are returned in opposite direction
// RGB -> BGR
//
for (int i=0;i<Image_height;i++)
{
for(int j=0;j<Image_width;j++)
{
// Value of R component of pixel color
RGB[j,i,0] = bmp_RGB_values[bmp_k+2];
// Value of G component of pixel color
RGB[j,i,1] = bmp_RGB_values[bmp_k+1];
// Value of B component of pixel color
RGB[j,i,2] = bmp_RGB_values[bmp_k+0];
// Value of pixel brightness
Brightness[j,i] = Color.FromArgb
(
bmp_RGB_values[bmp_k+2],
bmp_RGB_values[bmp_k+1],
bmp_RGB_values[bmp_k+0]
).GetBrightness();
bmp_k+=3;
}
bmp_k+= Number_of_alignment_bytes;
}
// Load lower and upper limit of the brightness
float lower_limit = (float) Lower_Brightness_Limit.Value;
float upper_limit = (float) Upper_Brightness_Limit.Value;
// Maximum found value for the difference in brightness
// between the opposing pixels
float mfd = 0;
for(int i=1;i<Image_height-1;i++)
{
for(int j=1;j<Image_width-1;j++)
{
//
mfd = Math.Abs(Brightness[j-1,i-1]-Brightness[j+1,i+1]);
//
if(mfd<Math.Abs(Brightness[j-1,i+1]-Brightness[j+1,i-1]))
mfd=Math.Abs(Brightness[j-1,i+1]-Brightness[j+1,i-1]);
//
if(mfd<Math.Abs(Brightness[j,i+1]-Brightness[j,i-1]))
mfd=Math.Abs(Brightness[j,i+1]-Brightness[j,i-1]);
//
if(mfd<Math.Abs(Brightness[j-1,i]-Brightness[j+1,i]))
mfd=Math.Abs(Brightness[j-1,i]-Brightness[j+1,i]);
//
if(Invert_Edge_Color.Checked)
{
if(mfd<lower_limit)
{
RGB[j,i,0] = (byte) 255;
RGB[j,i,1] = (byte) 255;
RGB[j,i,2] = (byte) 255;
}
else if(mfd>upper_limit)
{
RGB[j,i,0] = (byte) 0;
RGB[j,i,1] = (byte) 0;
RGB[j,i,2] = (byte) 0;
}
}
else
{
if(mfd<lower_limit)
{
RGB[j,i,0] = (byte) 0;
RGB[j,i,1] = (byte) 0;
RGB[j,i,2] = (byte) 0;
}
else if(mfd>upper_limit)
{
RGB[j,i,0] = (byte) 255;
RGB[j,i,1] = (byte) 255;
RGB[j,i,2] = (byte) 255;
}
}
}
}
if(Black_White.Checked)
{
for(int i=1;i<Image_height-1;i++)
{
for(int j=1;j<Image_width-1;j++)
{
if(Invert_Edge_Color.Checked)
{
if(RGB[j,i,0] < 255 || RGB[j,i,1] < 255 || RGB[j,i,2] < 255)
RGB[j,i,0] = RGB[j,i,1] = RGB[j,i,2] = (byte) 0;
}
else
{
if(RGB[j,i,0] > 0 || RGB[j,i,1] > 0 || RGB[j,i,2] > 0)
RGB[j,i,0] = RGB[j,i,1] = RGB[j,i,2] = (byte) 255;
}
}
}
}
if(Gray_Scale.Checked)
{
for(int i=1;i<Image_height-1;i++)
{
for(int j=1;j<Image_width-1;j++)
{
RGB[j,i,0] = RGB[j,i,1] = RGB[j,i,2] =
(byte)
(
(0.299*RGB[j,i,0]) +
(0.587*RGB[j,i,1]) +
(0.114*RGB[j,i,2])
);
}
}
}
// Byte counter inside one dimenzional matrix
bmp_k = 0;
// Copy new bitmap values of RGB components of color of pixels,
// from two dimenzional to one dimenzional matrix
for (int i=0;i<Image_height;i++)
{
for(int j=0;j<Image_width;j++)
{
// Value of R component of pixel color
bmp_RGB_values[bmp_k+2] = RGB[j,i,0];
// Value of G component of pixel color
bmp_RGB_values[bmp_k+1] = RGB[j,i,1];
// Value of B component of pixel color
bmp_RGB_values[bmp_k+0] = RGB[j,i,2];
bmp_k+=3;
}
bmp_k+=Number_of_alignment_bytes;
}
// Copy new values of RGB components of pixel color from matrix back to bitmap
Marshal.Copy(bmp_RGB_values, 0, bmp_First_byte_adress, Number_of_bytes);
// Unlock bitmap inside memory
bmp.UnlockBits(bmp_Data);
// Show the processed image
Image_2.Image = bmp;
}
No comments:
Post a Comment