From 9bb1439ec9117572d65f3e77625df6655ffc3995 Mon Sep 17 00:00:00 2001 From: Winner-Timothy Bolorunduro Date: Sun, 11 Aug 2024 00:10:36 +0100 Subject: [PATCH] ft: update convolution references and fix formatting --- src/DotNetANPR.CLI/Program.cs | 3 +- src/dotnetANPR/DotNetANPR.csproj | 1 - src/dotnetANPR/ImageAnalysis/Band.cs | 36 +++++++---- src/dotnetANPR/ImageAnalysis/CarSnapshot.cs | 13 ++-- src/dotnetANPR/ImageAnalysis/Character.cs | 60 +++++++++---------- .../ImageAnalysis/HoughTransformation.cs | 44 +++++++------- src/dotnetANPR/ImageAnalysis/Photo.cs | 15 ++--- src/dotnetANPR/ImageAnalysis/PixelMap.cs | 30 +++++----- src/dotnetANPR/ImageAnalysis/Plate.cs | 45 +++++++------- src/dotnetANPR/ImageAnalysis/PlateGraph.cs | 6 +- .../ImageAnalysis/PlateHorizontalGraph.cs | 4 +- src/dotnetANPR/ImageAnalysis/Statistics.cs | 14 ++--- src/dotnetANPR/Intelligence/Intelligence.cs | 6 +- .../Intelligence/Parser/PlateForm.cs | 2 +- .../Intelligence/RecognizedPlate.cs | 2 +- src/dotnetANPR/NeuralNetwork/NeuralNetwork.cs | 30 +++++----- src/dotnetANPR/NeuralNetwork/Neuron.cs | 2 +- .../Recognizer/CharacterRecognizer.cs | 38 +++++++++++- 18 files changed, 195 insertions(+), 156 deletions(-) diff --git a/src/DotNetANPR.CLI/Program.cs b/src/DotNetANPR.CLI/Program.cs index 9f5f57f..8c5727f 100644 --- a/src/DotNetANPR.CLI/Program.cs +++ b/src/DotNetANPR.CLI/Program.cs @@ -2,7 +2,8 @@ using DotNetANPR; -const string sourceFilePath = ""; +const string sourceFilePath = "/Users/bolorundurowb/Downloads/snapshots/test_093.jpg"; +const string reportPath = "/Users/bolorundurowb/Downloads/report"; var result = ANPR.Recognize(sourceFilePath); Console.WriteLine("The result is: " + result); diff --git a/src/dotnetANPR/DotNetANPR.csproj b/src/dotnetANPR/DotNetANPR.csproj index d797f0b..084ea81 100644 --- a/src/dotnetANPR/DotNetANPR.csproj +++ b/src/dotnetANPR/DotNetANPR.csproj @@ -3,7 +3,6 @@ netstandard2.0 latest enable - true diff --git a/src/dotnetANPR/ImageAnalysis/Band.cs b/src/dotnetANPR/ImageAnalysis/Band.cs index 5055950..86545d9 100644 --- a/src/dotnetANPR/ImageAnalysis/Band.cs +++ b/src/dotnetANPR/ImageAnalysis/Band.cs @@ -67,26 +67,36 @@ public BandGraph Histogram(Bitmap bitmap) public static void FullEdgeDetector(Bitmap source) { - float[] verticalMatrix = [-1, 0, 1, -2, 0, 2, -1, 0, 1]; - float[] horizontalMatrix = [-1, -2, -1, 0, 0, 0, 1, 2, 1]; - var i1 = CreateBlankBitmap(source); - var i2 = CreateBlankBitmap(source); + float[,] verticalMatrix = + { + { -1, 0, 1 }, + { -2, 0, 2 }, + { -1, 0, 1 } + }; + + float[,] horizontalMatrix = + { + { -1, -2, -1 }, + { 0, 0, 0 }, + { 1, 2, 1 } + }; // Apply vertical edge detection - source.ConvolutionFilter(i1, verticalMatrix); + var i1 = source.Convolve(verticalMatrix); // Apply horizontal edge detection - source.ConvolutionFilter(i2, horizontalMatrix); + var i2 = source.Convolve(horizontalMatrix); // Combine edge detection results var width = source.Width; var height = source.Height; + for (var x = 0; x < width; x++) - for (var y = 0; y < height; y++) - { - var sum = GetBrightness(i1, x, y); - sum += GetBrightness(i2, x, y); - SetBrightness(source, x, y, Math.Min(1f, sum)); - } + for (var y = 0; y < height; y++) + { + var sum = GetBrightness(i1, x, y); + sum += GetBrightness(i2, x, y); + SetBrightness(source, x, y, Math.Min(1f, sum)); + } } -} +} \ No newline at end of file diff --git a/src/dotnetANPR/ImageAnalysis/CarSnapshot.cs b/src/dotnetANPR/ImageAnalysis/CarSnapshot.cs index b7affe8..00afbe6 100644 --- a/src/dotnetANPR/ImageAnalysis/CarSnapshot.cs +++ b/src/dotnetANPR/ImageAnalysis/CarSnapshot.cs @@ -42,11 +42,16 @@ public List Bands() return response; } - public void VerticalEdge(Bitmap image) + public Bitmap VerticalEdge(Bitmap image) { var imageCopy = DuplicateBitmap(image); - float[] data = [-1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1]; - imageCopy.ConvolutionFilter(image, data); + float[,] data = { + { -1, 0, 1, }, + { -1, 0, 1 }, + { -1, 0, 1 }, + { -1, 0, 1 } + }; + return image.Convolve(data); } public CarSnapshotGraph Histogram(Bitmap bitmap) @@ -69,7 +74,7 @@ private List ComputeGraph() if (_graphHandle == null) { var imageCopy = DuplicateBitmap(Image); - VerticalEdge(imageCopy); + imageCopy = VerticalEdge(imageCopy); Thresholding(imageCopy); _graphHandle = Histogram(imageCopy); diff --git a/src/dotnetANPR/ImageAnalysis/Character.cs b/src/dotnetANPR/ImageAnalysis/Character.cs index b378a06..9767dc7 100644 --- a/src/dotnetANPR/ImageAnalysis/Character.cs +++ b/src/dotnetANPR/ImageAnalysis/Character.cs @@ -97,24 +97,24 @@ public List ExtractEdgeFeatures() var output = new double[features.Length * 4]; for (var f = 0; f < features.Length; f++) - for (var my = 0; my < height - 1; my++) - for (var mx = 0; mx < width - 1; mx++) - { - double featureMatch = 0; - featureMatch += Math.Abs(array[mx, my] - features[f][0]); - featureMatch += Math.Abs(array[mx + 1, my] - features[f][1]); - featureMatch += Math.Abs(array[mx, my + 1] - features[f][2]); - featureMatch += Math.Abs(array[mx + 1, my + 1] - features[f][3]); + for (var my = 0; my < height - 1; my++) + for (var mx = 0; mx < width - 1; mx++) + { + double featureMatch = 0; + featureMatch += Math.Abs(array[mx, my] - features[f][0]); + featureMatch += Math.Abs(array[mx + 1, my] - features[f][1]); + featureMatch += Math.Abs(array[mx, my + 1] - features[f][2]); + featureMatch += Math.Abs(array[mx + 1, my + 1] - features[f][3]); - var bias = 0; - if (mx >= width / 2) - bias += features.Length; // if we are in the right quadrant, move the bias by one class + var bias = 0; + if (mx >= width / 2) + bias += features.Length; // if we are in the right quadrant, move the bias by one class - if (my >= height / 2) - bias += features.Length * 2; // if we are in the left quadrant, move the bias by two classes + if (my >= height / 2) + bias += features.Length * 2; // if we are in the left quadrant, move the bias by two classes - output[bias + f] += featureMatch < 0.05 ? 1 : 0; - } + output[bias + f] += featureMatch < 0.05 ? 1 : 0; + } return output.ToList(); } @@ -123,8 +123,8 @@ public List ExtractMapFeatures() { List vectorInput = []; for (var y = 0; y < Height; y++) - for (var x = 0; x < Width; x++) - vectorInput.Add(GetBrightness(x, y)); + for (var x = 0; x < Width; x++) + vectorInput.Add(GetBrightness(x, y)); return vectorInput; } @@ -180,8 +180,8 @@ private void ComputeStatisticContrast(Bitmap bi) var w = bi.Width; var h = bi.Height; for (var x = 0; x < w; x++) - for (var y = 0; y < h; y++) - sum += Math.Abs(StatisticAverageBrightness - GetBrightness(bi, x, y)); + for (var y = 0; y < h; y++) + sum += Math.Abs(StatisticAverageBrightness - GetBrightness(bi, x, y)); StatisticContrast = sum / (w * h); } @@ -195,13 +195,13 @@ private void ComputeStatisticBrightness(Bitmap bi) var w = bi.Width; var h = bi.Height; for (var x = 0; x < w; x++) - for (var y = 0; y < h; y++) - { - var value = GetBrightness(bi, x, y); - sum += value; - min = Math.Min(min, value); - max = Math.Max(max, value); - } + for (var y = 0; y < h; y++) + { + var value = GetBrightness(bi, x, y); + sum += value; + min = Math.Min(min, value); + max = Math.Max(max, value); + } StatisticAverageBrightness = sum / (w * h); StatisticMinimumBrightness = min; @@ -214,8 +214,8 @@ private void ComputeStatisticHue(Bitmap bi) var w = bi.Width; var h = bi.Height; for (var x = 0; x < w; x++) - for (var y = 0; y < h; y++) - sum += GetHue(bi, x, y); + for (var y = 0; y < h; y++) + sum += GetHue(bi, x, y); StatisticAverageHue = sum / (w * h); } @@ -226,8 +226,8 @@ private void ComputeStatisticSaturation(Bitmap bi) var w = bi.Width; var h = bi.Height; for (var x = 0; x < w; x++) - for (var y = 0; y < h; y++) - sum += GetSaturation(bi, x, y); + for (var y = 0; y < h; y++) + sum += GetSaturation(bi, x, y); StatisticAverageSaturation = sum / (w * h); } diff --git a/src/dotnetANPR/ImageAnalysis/HoughTransformation.cs b/src/dotnetANPR/ImageAnalysis/HoughTransformation.cs index 73db3b2..c699cdd 100644 --- a/src/dotnetANPR/ImageAnalysis/HoughTransformation.cs +++ b/src/dotnetANPR/ImageAnalysis/HoughTransformation.cs @@ -41,8 +41,8 @@ public HoughTransformation(int width, int height) _height = height; for (var x = 0; x < width; x++) - for (var y = 0; y < height; y++) - _bitmap[x, y] = 0; + for (var y = 0; y < height; y++) + _bitmap[x, y] = 0; } public void AddLine(int x, int y, float brightness) @@ -76,8 +76,8 @@ private float GetAverageValue() { float sum = 0; for (var x = 0; x < _width; x++) - for (var y = 0; y < _height; y++) - sum += _bitmap[x, y]; + for (var y = 0; y < _height; y++) + sum += _bitmap[x, y]; return sum / (_width * _height); } @@ -89,16 +89,16 @@ public Bitmap Render(RenderType renderType, ColorType colorType) var g = Graphics.FromImage(output); for (var x = 0; x < _width; x++) - for (var y = 0; y < _height; y++) - { - var value = (int)(255 * _bitmap[x, y] / average / 3); - value = Math.Max(0, Math.Min(value, 255)); + for (var y = 0; y < _height; y++) + { + var value = (int)(255 * _bitmap[x, y] / average / 3); + value = Math.Max(0, Math.Min(value, 255)); - output.SetPixel(x, y, - colorType == ColorType.BlackAndWhite - ? Color.FromArgb(value, value, value) - : ColorExtensions.HsbToRgb(0.67f - (float)value / 255 * 2 / 3, 1.0f, 1.0f)); - } + output.SetPixel(x, y, + colorType == ColorType.BlackAndWhite + ? Color.FromArgb(value, value, value) + : ColorExtensions.HsbToRgb(0.67f - (float)value / 255 * 2 / 3, 1.0f, 1.0f)); + } var maximumPoint = FindMaxPoint(); g.DrawImage(output, 0, 0); @@ -138,17 +138,17 @@ private Point FindMaxPoint() float max = 0; int maxX = 0, maxY = 0; for (var x = 0; x < _width; x++) - for (var y = 0; y < _height; y++) - { - var curr = _bitmap[x, y]; + for (var y = 0; y < _height; y++) + { + var curr = _bitmap[x, y]; - if (!(curr >= max)) - continue; + if (!(curr >= max)) + continue; - maxX = x; - maxY = y; - max = curr; - } + maxX = x; + maxY = y; + max = curr; + } return new Point(maxX, maxY); } diff --git a/src/dotnetANPR/ImageAnalysis/Photo.cs b/src/dotnetANPR/ImageAnalysis/Photo.cs index 2a6cecc..4d7e115 100644 --- a/src/dotnetANPR/ImageAnalysis/Photo.cs +++ b/src/dotnetANPR/ImageAnalysis/Photo.cs @@ -23,7 +23,9 @@ public class Photo(Bitmap image) : IDisposable, ICloneable public Bitmap Image { get => image; - protected set => image = value; + // TODO: fix this travesty + // protected set => image = value; + internal set => image = value; } public static void SetBrightness(Bitmap image, int x, int y, float value) @@ -233,13 +235,6 @@ public Bitmap AverageResizeImage(Bitmap origin, int width, int height) #endregion - public virtual void VerticalEdgeDetector(Bitmap source) - { - var destination = DuplicateBitmap(source); - float[] kernel = [-1, 0, 1, -2, 0, 2, -1, 0, 1]; - destination.ConvolutionFilter(source, kernel); - } - public float[,] BitmapToArray(Bitmap image, int width, int height) { var array = new float[width, height]; @@ -307,11 +302,11 @@ public void PlainThresholding(Statistics stat) public void AdaptiveThresholding() { - var stat = new Statistics(this); + var statistics = new Statistics(this); var radius = Configurator.Instance.Get("photo_adaptivethresholdingradius"); if (radius == 0) { - PlainThresholding(stat); + PlainThresholding(statistics); return; } diff --git a/src/dotnetANPR/ImageAnalysis/PixelMap.cs b/src/dotnetANPR/ImageAnalysis/PixelMap.cs index 96965b7..730d9bc 100644 --- a/src/dotnetANPR/ImageAnalysis/PixelMap.cs +++ b/src/dotnetANPR/ImageAnalysis/PixelMap.cs @@ -19,8 +19,8 @@ public Bitmap Render() { var image = new Bitmap(_width, _height, PixelFormat.Format24bppRgb); for (var x = 0; x < _width; x++) - for (var y = 0; y < _height; y++) - image.SetPixel(x, y, _matrix[x, y] ? Color.Black : Color.White); + for (var y = 0; y < _height; y++) + image.SetPixel(x, y, _matrix[x, y] ? Color.Black : Color.White); return image; } @@ -75,9 +75,9 @@ public PixelMap ReduceNoise() { PointSet pointsToReduce = []; for (var x = 0; x < _width; x++) - for (var y = 0; y < _height; y++) - if (N(x, y) < 4) - pointsToReduce.Add(new Point(x, y)); // recommended 4 + for (var y = 0; y < _height; y++) + if (N(x, y) < 4) + pointsToReduce.Add(new Point(x, y)); // recommended 4 // remove marked points foreach (var point in pointsToReduce) @@ -92,9 +92,9 @@ public PieceSet FindPieces() // put all black points into a set PointSet unsorted = []; for (var x = 0; x < _width; x++) - for (var y = 0; y < _height; y++) - if (_matrix[x, y]) - unsorted.Add(new Point(x, y)); + for (var y = 0; y < _height; y++) + if (_matrix[x, y]) + unsorted.Add(new Point(x, y)); while (!unsorted.Any()) pieces.Add(CreatePiece(unsorted)); @@ -137,8 +137,8 @@ private void MatrixInit(Photo bi) _height = bi.Height; _matrix = new bool[_width, _height]; for (var x = 0; x < _width; x++) - for (var y = 0; y < _height; y++) - _matrix[x, y] = bi.GetBrightness(x, y) < 0.5; + for (var y = 0; y < _height; y++) + _matrix[x, y] = bi.GetBrightness(x, y) < 0.5; } private bool GetPointValue(int x, int y) @@ -252,9 +252,9 @@ private void FindBoundaryPoints(PointSet set) set.Clear(); for (var x = 0; x < _width; x++) - for (var y = 0; y < _height; y++) - if (IsBoundaryPoint(x, y)) - set.Add(new Point(x, y)); + for (var y = 0; y < _height; y++) + if (IsBoundaryPoint(x, y)) + set.Add(new Point(x, y)); } private bool SeedShouldBeAdded(Piece piece, Point point) @@ -393,8 +393,8 @@ public class Piece : PointSet var image = new Bitmap(Width, Height); for (var x = MostLeftPoint; x <= MostRightPoint; x++) - for (var y = MostTopPoint; y <= MostBottomPoint; y++) - image.SetPixel(x - MostLeftPoint, y - MostTopPoint, _matrix[x, y] ? Color.Black : Color.White); + for (var y = MostTopPoint; y <= MostBottomPoint; y++) + image.SetPixel(x - MostLeftPoint, y - MostTopPoint, _matrix[x, y] ? Color.Black : Color.White); return image; } diff --git a/src/dotnetANPR/ImageAnalysis/Plate.cs b/src/dotnetANPR/ImageAnalysis/Plate.cs index 8f570bd..37e2009 100644 --- a/src/dotnetANPR/ImageAnalysis/Plate.cs +++ b/src/dotnetANPR/ImageAnalysis/Plate.cs @@ -31,7 +31,7 @@ public Plate(Bitmap image, bool isCopy = false) : base(image) } } - public new object Clone() => new Plate(DuplicateBitmap(Image)); + public new object Clone() => new Plate(DuplicateBitmap(Image)); public Bitmap RenderGraph() { @@ -50,35 +50,31 @@ public List Characters() // we have to apply an inverse transformation to the coordinates calculated from imageCopy if (peak.Diff <= 0) continue; - - characters.Add(new Character(Image.SubImage(peak.Left, 0, peak.Diff, Image.Height), + var positionInPlate = new PositionInPlate(peak.Left, peak.Right); + var character = new Character(Image.SubImage(peak.Left, 0, peak.Diff, Image.Height), _plateCopy!.Image.SubImage(peak.Left, 0, peak.Diff, Image.Height), - new PositionInPlate(peak.Left, peak.Right))); + positionInPlate); + characters.Add(character); } - return characters; - } + characters.ForEach(x => x.Save($"/Users/bolorundurowb/Downloads/{Guid.NewGuid()}.jpg")); - public void HorizontalEdgeBi(Bitmap image) - { - var imageCopy = DuplicateBitmap(image); - float[] data = [-1, 0, 1]; - imageCopy.ConvolutionFilter(image, data); + return characters; } public void Normalize() { var clone1 = (Plate)Clone(); - clone1.VerticalEdgeDetector(clone1.Image); + clone1.Image = clone1.VerticalEdgeDetector(clone1.Image); var vertical = clone1.HistogramYaxis(clone1.Image); Image = CutTopBottom(Image, vertical); _plateCopy!.Image = CutTopBottom(_plateCopy.Image, vertical); var clone2 = (Plate)Clone(); if (HorizontalDetectionType == 1) - clone2.HorizontalEdgeDetector(clone2.Image); + clone2.Image = clone2.HorizontalEdgeDetector(clone2.Image); - var horizontal = clone1.HistogramXaxis(clone2.Image); + var horizontal = clone1.HistogramXAxis(clone2.Image); Image = CutLeftRight(Image, horizontal); _plateCopy.Image = CutLeftRight(_plateCopy.Image, horizontal); } @@ -98,18 +94,16 @@ public PlateGraph Histogram(Bitmap bi) return graph; } - public override void VerticalEdgeDetector(Bitmap source) + public Bitmap VerticalEdgeDetector(Bitmap source) { - float[] matrix = [-1, 0, 1]; - var destination = DuplicateBitmap(source); - destination.ConvolutionFilter(source, matrix); + float[,] matrix = { { -1, 0, 1 } }; + return source.Convolve(matrix); } - public void HorizontalEdgeDetector(Bitmap source) + public Bitmap HorizontalEdgeDetector(Bitmap source) { - var destination = DuplicateBitmap(source); - float[] matrix = [-1, -2, -1, 0, 0, 0, 1, 2, 1]; - destination.ConvolutionFilter(source, matrix); + float[,] matrix = { { -1, -2, -1 }, { 0, 0, 0 }, { 1, 2, 1 } }; + return source.Convolve(matrix); } public float CharactersWidthDispersion(List characters) @@ -210,13 +204,14 @@ private PlateVerticalGraph HistogramYaxis(Bitmap bi) return graph; } - private PlateHorizontalGraph HistogramXaxis(Bitmap bi) + private PlateHorizontalGraph HistogramXAxis(Bitmap bi) { var graph = new PlateHorizontalGraph(); for (var x = 0; x < bi.Width; x++) { float counter = 0; - for (var y = 0; y < bi.Height; y++) counter += GetBrightness(bi, x, y); + for (var y = 0; y < bi.Height; y++) + counter += GetBrightness(bi, x, y); graph.AddPeak(counter); } @@ -225,4 +220,4 @@ private PlateHorizontalGraph HistogramXaxis(Bitmap bi) } #endregion -} +} \ No newline at end of file diff --git a/src/dotnetANPR/ImageAnalysis/PlateGraph.cs b/src/dotnetANPR/ImageAnalysis/PlateGraph.cs index eef3310..6126f6d 100644 --- a/src/dotnetANPR/ImageAnalysis/PlateGraph.cs +++ b/src/dotnetANPR/ImageAnalysis/PlateGraph.cs @@ -33,9 +33,9 @@ public List FindPeaks(int count) List spacesTemp = []; var diffGVal = 2 * AverageValue() - MaxValue(); YValues = YValues.Select(f => f - diffGVal).ToList(); - + DeActualizeFlags(); - + for (var c = 0; c < count; c++) { var maxValue = 0.0f; @@ -54,7 +54,7 @@ public List FindPeaks(int count) } // we found the biggest peak - if (YValues[maxIndex] < _plategraphRelMinpeaksize * MaxValue()) + if (YValues[maxIndex] < _plategraphRelMinpeaksize * MaxValue()) break; // width of the detected space diff --git a/src/dotnetANPR/ImageAnalysis/PlateHorizontalGraph.cs b/src/dotnetANPR/ImageAnalysis/PlateHorizontalGraph.cs index 69cd420..7a20ae7 100644 --- a/src/dotnetANPR/ImageAnalysis/PlateHorizontalGraph.cs +++ b/src/dotnetANPR/ImageAnalysis/PlateHorizontalGraph.cs @@ -11,8 +11,8 @@ public class PlateHorizontalGraph : Graph public float Derivation(int index1, int index2) => YValues[index1] - YValues[index2]; - public List FindPeak() => HorizontalDetectionType == 1 - ? FindPeakEdgeDetection() + public List FindPeak() => HorizontalDetectionType == 1 + ? FindPeakEdgeDetection() : FindPeakDerivative(); public List FindPeakDerivative() diff --git a/src/dotnetANPR/ImageAnalysis/Statistics.cs b/src/dotnetANPR/ImageAnalysis/Statistics.cs index 893ea3d..40e0b4c 100644 --- a/src/dotnetANPR/ImageAnalysis/Statistics.cs +++ b/src/dotnetANPR/ImageAnalysis/Statistics.cs @@ -15,13 +15,13 @@ public Statistics(Photo photo) var height = photo.Height; for (var x = 0; x < width; x++) - for (var y = 0; y < height; y++) - { - var pixelValue = photo.GetBrightness(x, y); - _maximum = Math.Max(pixelValue, _maximum); - _minimum = Math.Min(pixelValue, _minimum); - sum += pixelValue; - } + for (var y = 0; y < height; y++) + { + var pixelValue = photo.GetBrightness(x, y); + _maximum = Math.Max(pixelValue, _maximum); + _minimum = Math.Min(pixelValue, _minimum); + sum += pixelValue; + } _average = sum / (width * height); } diff --git a/src/dotnetANPR/Intelligence/Intelligence.cs b/src/dotnetANPR/Intelligence/Intelligence.cs index a35e5a2..e18aa4f 100644 --- a/src/dotnetANPR/Intelligence/Intelligence.cs +++ b/src/dotnetANPR/Intelligence/Intelligence.cs @@ -72,7 +72,7 @@ public Intelligence() if (generateReport || skewDetectionMode != 0) { notNormalizedCopy = (Plate)plate.Clone(); - notNormalizedCopy.HorizontalEdgeDetector(notNormalizedCopy.Image); + notNormalizedCopy.Image = notNormalizedCopy.HorizontalEdgeDetector(notNormalizedCopy.Image); hough = notNormalizedCopy.GetHoughTransformation(); renderedHoughTransform = hough.Render(HoughTransformation.RenderType.RenderAll, HoughTransformation.ColorType.BlackAndWhite); @@ -177,7 +177,7 @@ public Intelligence() continue; } - if (chr.PositionInPlate is null) + if (chr.PositionInPlate is null) throw new ArgumentNullException(nameof(chr.PositionInPlate), "Character position in plate is null"); if ((chr.PositionInPlate.LeftX < 2 || chr.PositionInPlate.RightX > plate.Width - 1) && widthHeightRatio < 0.12) @@ -239,7 +239,7 @@ public Intelligence() { rc = _chrRecognizer.Recognize(chr); - if (rc.Patterns is null || rc.Patterns.Count == 0) + if (rc.Patterns is null || rc.Patterns.Count == 0) throw new ArgumentNullException(nameof(rc), "Recognized character does not have any patterns"); similarityCost = rc.Patterns![0].Cost; diff --git a/src/dotnetANPR/Intelligence/Parser/PlateForm.cs b/src/dotnetANPR/Intelligence/Parser/PlateForm.cs index 8ff9601..38b639f 100644 --- a/src/dotnetANPR/Intelligence/Parser/PlateForm.cs +++ b/src/dotnetANPR/Intelligence/Parser/PlateForm.cs @@ -5,7 +5,7 @@ namespace DotNetANPR.Intelligence.Parser; public class PlateForm(string name) { public List Positions { get; private set; } = []; - + public int Length => Positions.Count; public bool IsFlagged { get; set; } diff --git a/src/dotnetANPR/Intelligence/RecognizedPlate.cs b/src/dotnetANPR/Intelligence/RecognizedPlate.cs index df3713b..3e62b15 100644 --- a/src/dotnetANPR/Intelligence/RecognizedPlate.cs +++ b/src/dotnetANPR/Intelligence/RecognizedPlate.cs @@ -7,7 +7,7 @@ namespace DotNetANPR.Intelligence; public class RecognizedPlate { private readonly List _characters = []; - + public List Characters => _characters; public void AddCharacter(RecognizedCharacter character) => _characters.Add(character); diff --git a/src/dotnetANPR/NeuralNetwork/NeuralNetwork.cs b/src/dotnetANPR/NeuralNetwork/NeuralNetwork.cs index 36cefed..36cae42 100644 --- a/src/dotnetANPR/NeuralNetwork/NeuralNetwork.cs +++ b/src/dotnetANPR/NeuralNetwork/NeuralNetwork.cs @@ -352,21 +352,21 @@ private void Adaptation(SetOfIOPairs trainingSet, int maxK, double eps, double l private List Activities(List inputs) { for (var layerIndex = 0; layerIndex < Layers.Count; layerIndex++) - for (var neuronIndex = 0; neuronIndex < GetLayer(layerIndex).Neurons.Count; neuronIndex++) - { - var sum = GetLayer(layerIndex).Neurons[neuronIndex].Threshold; // sum <- threshold - for (var inputIndex = 0; - inputIndex < GetLayer(layerIndex).Neurons[neuronIndex].Inputs.Count; - inputIndex++) - if (layerIndex == 0) - sum += GetLayer(layerIndex).Neurons[neuronIndex].Inputs[inputIndex].Weight * - inputs[neuronIndex]; - else - sum += GetLayer(layerIndex).Neurons[neuronIndex].Inputs[inputIndex] - .Weight * GetLayer(layerIndex - 1).Neurons[inputIndex].Output; - - GetLayer(layerIndex).Neurons[neuronIndex].Output = GainFunction(sum); - } + for (var neuronIndex = 0; neuronIndex < GetLayer(layerIndex).Neurons.Count; neuronIndex++) + { + var sum = GetLayer(layerIndex).Neurons[neuronIndex].Threshold; // sum <- threshold + for (var inputIndex = 0; + inputIndex < GetLayer(layerIndex).Neurons[neuronIndex].Inputs.Count; + inputIndex++) + if (layerIndex == 0) + sum += GetLayer(layerIndex).Neurons[neuronIndex].Inputs[inputIndex].Weight * + inputs[neuronIndex]; + else + sum += GetLayer(layerIndex).Neurons[neuronIndex].Inputs[inputIndex] + .Weight * GetLayer(layerIndex - 1).Neurons[inputIndex].Output; + + GetLayer(layerIndex).Neurons[neuronIndex].Output = GainFunction(sum); + } List output = new(); foreach (var t in GetLayer(Layers.Count - 1).Neurons) diff --git a/src/dotnetANPR/NeuralNetwork/Neuron.cs b/src/dotnetANPR/NeuralNetwork/Neuron.cs index ef182bf..6a4531b 100644 --- a/src/dotnetANPR/NeuralNetwork/Neuron.cs +++ b/src/dotnetANPR/NeuralNetwork/Neuron.cs @@ -6,7 +6,7 @@ namespace DotNetANPR.NeuralNetwork; public class Neuron { public double Threshold { get; set; } - + public double Output { get; set; } public NeuralLayer NeuralLayer { get; } diff --git a/src/dotnetANPR/Recognizer/CharacterRecognizer.cs b/src/dotnetANPR/Recognizer/CharacterRecognizer.cs index bba1dd8..82dedeb 100644 --- a/src/dotnetANPR/Recognizer/CharacterRecognizer.cs +++ b/src/dotnetANPR/Recognizer/CharacterRecognizer.cs @@ -6,8 +6,42 @@ public abstract class CharacterRecognizer { public static char[] Alphabet = [ - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z' ]; public static readonly float[][] Features =