|
|
|
@ -49,7 +49,7 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Processes the given bitmap to apply the current instances <see cref="IEdgeFilter"/>.
|
|
|
|
/// Processes the given bitmap to apply the current instance of <see cref="IEdgeFilter"/>.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="source">The image to process.</param>
|
|
|
|
/// <returns>A processed bitmap.</returns>
|
|
|
|
@ -184,7 +184,7 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Processes the given bitmap to apply the current instances <see cref="IEdgeFilter"/>.
|
|
|
|
/// Processes the given bitmap to apply the current instance of <see cref="I2DEdgeFilter"/>.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="source">The image to process.</param>
|
|
|
|
/// <returns>A processed bitmap.</returns>
|
|
|
|
@ -229,74 +229,79 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection |
|
|
|
using (FastBitmap destinationBitmap = new FastBitmap(destination)) |
|
|
|
{ |
|
|
|
// Loop through the pixels.
|
|
|
|
for (int y = 0; y < height; y++) |
|
|
|
{ |
|
|
|
for (int x = 0; x < width; x++) |
|
|
|
Parallel.For( |
|
|
|
0, |
|
|
|
height, |
|
|
|
y => |
|
|
|
{ |
|
|
|
double rX = 0; |
|
|
|
double rY = 0; |
|
|
|
double gX = 0; |
|
|
|
double gY = 0; |
|
|
|
double bX = 0; |
|
|
|
double bY = 0; |
|
|
|
|
|
|
|
// Apply each matrix multiplier to the color components for each pixel.
|
|
|
|
for (int fy = 0; fy < kernelLength; fy++) |
|
|
|
for (int x = 0; x < width; x++) |
|
|
|
{ |
|
|
|
int fyr = fy - radius; |
|
|
|
int offsetY = y + fyr; |
|
|
|
|
|
|
|
// Skip the current row
|
|
|
|
if (offsetY < 0) |
|
|
|
{ |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
// Outwith the current bounds so break.
|
|
|
|
if (offsetY >= height) |
|
|
|
{ |
|
|
|
break; |
|
|
|
} |
|
|
|
double rX = 0; |
|
|
|
double rY = 0; |
|
|
|
double gX = 0; |
|
|
|
double gY = 0; |
|
|
|
double bX = 0; |
|
|
|
double bY = 0; |
|
|
|
|
|
|
|
for (int fx = 0; fx < kernelLength; fx++) |
|
|
|
// Apply each matrix multiplier to the color components for each pixel.
|
|
|
|
for (int fy = 0; fy < kernelLength; fy++) |
|
|
|
{ |
|
|
|
int fxr = fx - radius; |
|
|
|
int offsetX = x + fxr; |
|
|
|
int fyr = fy - radius; |
|
|
|
int offsetY = y + fyr; |
|
|
|
|
|
|
|
// Skip the column
|
|
|
|
if (offsetX < 0) |
|
|
|
// Skip the current row
|
|
|
|
if (offsetY < 0) |
|
|
|
{ |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
if (offsetX < width) |
|
|
|
// Outwith the current bounds so break.
|
|
|
|
if (offsetY >= height) |
|
|
|
{ |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
for (int fx = 0; fx < kernelLength; fx++) |
|
|
|
{ |
|
|
|
Color currentColor = sourceBitmap.GetPixel(offsetX, offsetY); |
|
|
|
double r = currentColor.R; |
|
|
|
double g = currentColor.G; |
|
|
|
double b = currentColor.B; |
|
|
|
int fxr = fx - radius; |
|
|
|
int offsetX = x + fxr; |
|
|
|
|
|
|
|
rX += horizontalFilter[fy, fx] * r; |
|
|
|
rY += verticalFilter[fy, fx] * r; |
|
|
|
// Skip the column
|
|
|
|
if (offsetX < 0) |
|
|
|
{ |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
gX += horizontalFilter[fy, fx] * g; |
|
|
|
gY += verticalFilter[fy, fx] * g; |
|
|
|
if (offsetX < width) |
|
|
|
{ |
|
|
|
// ReSharper disable once AccessToDisposedClosure
|
|
|
|
Color currentColor = sourceBitmap.GetPixel(offsetX, offsetY); |
|
|
|
double r = currentColor.R; |
|
|
|
double g = currentColor.G; |
|
|
|
double b = currentColor.B; |
|
|
|
|
|
|
|
bX += horizontalFilter[fy, fx] * b; |
|
|
|
bY += verticalFilter[fy, fx] * b; |
|
|
|
rX += horizontalFilter[fy, fx] * r; |
|
|
|
rY += verticalFilter[fy, fx] * r; |
|
|
|
|
|
|
|
gX += horizontalFilter[fy, fx] * g; |
|
|
|
gY += verticalFilter[fy, fx] * g; |
|
|
|
|
|
|
|
bX += horizontalFilter[fy, fx] * b; |
|
|
|
bY += verticalFilter[fy, fx] * b; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Apply the equation and sanitize.
|
|
|
|
byte red = Math.Sqrt((rX * rX) + (rY * rY)).ToByte(); |
|
|
|
byte green = Math.Sqrt((gX * gX) + (gY * gY)).ToByte(); |
|
|
|
byte blue = Math.Sqrt((bX * bX) + (bY * bY)).ToByte(); |
|
|
|
// Apply the equation and sanitize.
|
|
|
|
byte red = Math.Sqrt((rX * rX) + (rY * rY)).ToByte(); |
|
|
|
byte green = Math.Sqrt((gX * gX) + (gY * gY)).ToByte(); |
|
|
|
byte blue = Math.Sqrt((bX * bX) + (bY * bY)).ToByte(); |
|
|
|
|
|
|
|
Color newColor = Color.FromArgb(red, green, blue); |
|
|
|
destinationBitmap.SetPixel(x, y, newColor); |
|
|
|
} |
|
|
|
} |
|
|
|
Color newColor = Color.FromArgb(red, green, blue); |
|
|
|
// ReSharper disable once AccessToDisposedClosure
|
|
|
|
destinationBitmap.SetPixel(x, y, newColor); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|