Skip to content

Commit

Permalink
Complete edge detection
Browse files Browse the repository at this point in the history
  • Loading branch information
JimBobSquarePants committed Oct 22, 2019
1 parent 12d22b6 commit 5ab1772
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 24 deletions.
21 changes: 11 additions & 10 deletions src/ImageProcessor/ImageFactory.Processing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,22 +127,23 @@ public ImageFactory DetectEdges(EdgeDetectionOperators filter, bool grayscale)
switch (filter)
{
case EdgeDetectionOperators.Kayyali:
throw new NotImplementedException();
case EdgeDetectionOperators.Kirsch:
throw new NotImplementedException();
processor = new Kayyali(grayscale);
break;
case EdgeDetectionOperators.Laplacian3x3:
processor = new Laplacian3x3(grayscale);
break;
case EdgeDetectionOperators.Laplacian5x5:
throw new NotImplementedException();
processor = new Laplacian5x5(grayscale);
break;
case EdgeDetectionOperators.LaplacianOfGaussian:
throw new NotImplementedException();
processor = new LaplacianOfGaussian(grayscale);
break;
case EdgeDetectionOperators.Prewitt:
throw new NotImplementedException();
processor = new Prewitt(grayscale);
break;
case EdgeDetectionOperators.RobertsCross:
throw new NotImplementedException();
case EdgeDetectionOperators.Robinson:
throw new NotImplementedException();
processor = new RobertsCross(grayscale);
break;
case EdgeDetectionOperators.Scharr:
processor = new Scharr(grayscale);
break;
Expand All @@ -161,7 +162,7 @@ public ImageFactory DetectEdges(EdgeDetectionOperators filter, bool grayscale)
/// </summary>
/// <param name="degrees">The rotation angle in degrees to adjust the hue.</param>
/// <returns>The <see cref="ImageFactory"/>.</returns>
public ImageFactory Hue(int degrees)
public ImageFactory Hue(float degrees)
{
this.CheckLoaded();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ public enum EdgeDetectionOperators
/// </summary>
Kayyali,

/// <summary>
/// The Kirsch operator filter.
/// </summary>
Kirsch,

/// <summary>
/// The Laplacian3X3 operator filter.
/// </summary>
Expand All @@ -43,11 +38,6 @@ public enum EdgeDetectionOperators
/// </summary>
RobertsCross,

/// <summary>
/// The Robinson operator filter.
/// </summary>
Robinson,

/// <summary>
/// The Scharr operator filter.
/// </summary>
Expand Down
35 changes: 35 additions & 0 deletions src/ImageProcessor/Processing/Convolution/Kayyali.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.

namespace ImageProcessor.Processing
{
/// <summary>
/// Detects edges within an image using Kayyali operators.
/// <see href="https://edgedetection.webs.com/"/>.
/// </summary>
public class Kayyali : EdgeDetection2DProcessor
{
private static readonly double[,] KernelX = new double[,]
{
{ 6, 0, -6 },
{ 0, 0, 0 },
{ -6, 0, 6 }
};

private static readonly double[,] KernelY = new double[,]
{
{ -6, 0, 6 },
{ 0, 0, 0 },
{ 6, 0, -6 }
};

/// <summary>
/// Initializes a new instance of the <see cref="Kayyali"/> class.
/// </summary>
/// <param name="grayscale">Whether to convert the image to grascale before processing.</param>
public Kayyali(bool grayscale)
: base(new KernelPair(KernelX, KernelY), grayscale)
{
}
}
}
30 changes: 30 additions & 0 deletions src/ImageProcessor/Processing/Convolution/Laplacian5x5.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.

namespace ImageProcessor.Processing
{
/// <summary>
/// Detects edges within an image using Laplacian 5x5 operators.
/// <see href="http://en.wikipedia.org/wiki/Discrete_Laplace_operator"/>.
/// </summary>
public class Laplacian5x5 : EdgeDetectionProcessor
{
private static readonly double[,] KernelXY = new double[,]
{
{ -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1 },
{ -1, -1, 24, -1, -1 },
{ -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1 }
};

/// <summary>
/// Initializes a new instance of the <see cref="Laplacian5x5"/> class.
/// </summary>
/// <param name="grayscale">Whether to convert the image to grascale before processing.</param>
public Laplacian5x5(bool grayscale)
: base(KernelXY, grayscale)
{
}
}
}
30 changes: 30 additions & 0 deletions src/ImageProcessor/Processing/Convolution/LaplacianOfGaussian.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.

namespace ImageProcessor.Processing
{
/// <summary>
/// Detects edges within an image using Laplacian of Gaussian operators.
/// <see href="http://fourier.eng.hmc.edu/e161/lectures/gradient/node9.html"/>.
/// </summary>
public class LaplacianOfGaussian : EdgeDetectionProcessor
{
private static readonly double[,] KernelXY = new double[,]
{
{ 0, 0, -1, 0, 0 },
{ 0, -1, -2, -1, 0 },
{ -1, -2, 16, -2, -1 },
{ 0, -1, -2, -1, 0 },
{ 0, 0, -1, 0, 0 }
};

/// <summary>
/// Initializes a new instance of the <see cref="LaplacianOfGaussian"/> class.
/// </summary>
/// <param name="grayscale">Whether to convert the image to grascale before processing.</param>
public LaplacianOfGaussian(bool grayscale)
: base(KernelXY, grayscale)
{
}
}
}
35 changes: 35 additions & 0 deletions src/ImageProcessor/Processing/Convolution/Prewitt.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.

namespace ImageProcessor.Processing
{
/// <summary>
/// Detects edges within an image using Prewitt operators.
/// <see href="http://en.wikipedia.org/wiki/Prewitt_operator"/>.
/// </summary>
public class Prewitt : EdgeDetection2DProcessor
{
private static readonly double[,] KernelX = new double[,]
{
{ -1, 0, 1 },
{ -1, 0, 1 },
{ -1, 0, 1 }
};

private static readonly double[,] KernelY = new double[,]
{
{ 1, 1, 1 },
{ 0, 0, 0 },
{ -1, -1, -1 }
};

/// <summary>
/// Initializes a new instance of the <see cref="Prewitt"/> class.
/// </summary>
/// <param name="grayscale">Whether to convert the image to grascale before processing.</param>
public Prewitt(bool grayscale)
: base(new KernelPair(KernelX, KernelY), grayscale)
{
}
}
}
33 changes: 33 additions & 0 deletions src/ImageProcessor/Processing/Convolution/RobertsCross.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.

namespace ImageProcessor.Processing
{
/// <summary>
/// Detects edges within an image using RobertsCross operators.
/// <see href="http://en.wikipedia.org/wiki/Roberts_cross"/>.
/// </summary>
public class RobertsCross : EdgeDetection2DProcessor
{
private static readonly double[,] KernelX = new double[,]
{
{ 1, 0 },
{ 0, -1 }
};

private static readonly double[,] KernelY = new double[,]
{
{ 0, 1 },
{ -1, 0 }
};

/// <summary>
/// Initializes a new instance of the <see cref="RobertsCross"/> class.
/// </summary>
/// <param name="grayscale">Whether to convert the image to grascale before processing.</param>
public RobertsCross(bool grayscale)
: base(new KernelPair(KernelX, KernelY), grayscale)
{
}
}
}
28 changes: 24 additions & 4 deletions tests/ImageProcessor.Tests/Processing/DetectEdgesTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using ImageProcessor.Processing;
using Xunit;

Expand All @@ -7,11 +9,16 @@ public class DetectEdgesTests
{
private const string category = "DetectEdges";

// TODO: Test all operators.
public static IEnumerable<object[]> EdgeDetectionOperatorsData()
{
foreach (object value in Enum.GetValues(typeof(EdgeDetectionOperators)))
{
yield return new object[] { value };
}
}

[Theory]
[InlineData(EdgeDetectionOperators.Sobel)]
[InlineData(EdgeDetectionOperators.Scharr)]
[InlineData(EdgeDetectionOperators.Laplacian3x3)]
[MemberData(nameof(EdgeDetectionOperatorsData))]
public void FactoryCanDetectEdges(EdgeDetectionOperators mode)
{
TestFile file = TestFiles.Png.Penguins;
Expand All @@ -22,5 +29,18 @@ public void FactoryCanDetectEdges(EdgeDetectionOperators mode)
.SaveAndCompare(file, category, mode);
}
}

[Theory]
[MemberData(nameof(EdgeDetectionOperatorsData))]
public void FactoryCanDetectEdgesWithColor(EdgeDetectionOperators mode)
{
TestFile file = TestFiles.Png.Penguins;
using (var factory = new ImageFactory())
{
factory.Load(file.FullName)
.DetectEdges(mode, false)
.SaveAndCompare(file, category, mode, "color");
}
}
}
}

0 comments on commit 5ab1772

Please sign in to comment.