3using System.Collections.Generic;
12 private readonly Dictionary<ushort, ObjectInformation> objectsById =
new Dictionary<ushort, ObjectInformation>();
28 int SrcIndex = M.
Start;
32 ushort[] Dest = this.
Data;
37 for (y = 0; y < h; y++, SrcIndex += SrcSkip)
39 for (x = 0; x < w; x++, DestIndex++)
44 Obj = Dest[DestIndex];
47 Obj = (ushort)this.objectsById.Count;
49 this.objectsById[Obj] = Info;
50 this.FloodFill(x, y, M, Threshold, Info);
57 this.objectsById.Values.CopyTo(this.objects, 0);
65 ushort[] Dest = this.
Data;
72 ushort Nr = (ushort)(Info.
Nr + 1);
75 while (x1 > 0 && Src[SrcIndex + x1 - 1] >= Threshold && Dest[DestIndex + x1 - 1] == 0)
78 while (x2 < w - 1 && Src[SrcIndex + x2 + 1] >= Threshold && Dest[DestIndex + x2 + 1] == 0)
81 Info.AddPixels(x1, x2, y);
85 Dest[di] = (ushort)(Nr | 0x8000);
96 Dest[di] = (ushort)(Nr | 0x8000);
98 for (x = x1, si = SrcIndex + x, di = DestIndex + x; x <= x2; x++, si++, di++)
102 if (Src[si - SrcRow] >= Threshold)
104 if (Dest[di - DestRow] == 0)
105 this.FloodFill(x, y - 1, M, Threshold, Info);
113 if (Src[si + SrcRow] >= Threshold)
115 if (Dest[di + DestRow] == 0)
116 this.FloodFill(x, y + 1, M, Threshold, Info);
137 int SrcIndex = M.
Start;
138 int SrcSkip = M.
Skip;
141 ushort[] Dest = this.
Data;
146 for (y = 0; y < h; y++, SrcIndex += SrcSkip)
148 for (x = 0; x < w; x++, DestIndex++)
153 Obj = Dest[DestIndex];
156 Obj = (ushort)this.objectsById.Count;
158 this.objectsById[Obj] = Info;
159 this.FloodFill(x, y, M, Threshold, Info);
166 this.objectsById.Values.CopyTo(this.objects, 0);
174 ushort[] Dest = this.
Data;
178 int h = M.Height - 1;
181 ushort Nr = (ushort)(Info.
Nr + 1);
184 while (x1 > 0 && Src[SrcIndex + x1 - 1] >= Threshold && Dest[DestIndex + x1 - 1] == 0)
187 while (x2 < w - 1 && Src[SrcIndex + x2 + 1] >= Threshold && Dest[DestIndex + x2 + 1] == 0)
190 Info.AddPixels(x1, x2, y);
194 Dest[di] = (ushort)(Nr | 0x8000);
205 Dest[di] = (ushort)(Nr | 0x8000);
207 for (x = x1, si = SrcIndex + x, di = DestIndex + x; x <= x2; x++, si++, di++)
211 if (Src[si - SrcRow] >= Threshold)
213 if (Dest[di - DestRow] == 0)
214 this.FloodFill(x, y - 1, M, Threshold, Info);
222 if (Src[si + SrcRow] >= Threshold)
224 if (Dest[di + DestRow] == 0)
225 this.FloodFill(x, y + 1, M, Threshold, Info);
250 internal Point[] FindContour(
int X0,
int Y0,
int Nr)
252 List<Point> Result =
new List<Point>();
253 LinkedList<Rec> History =
new LinkedList<Rec>();
271 Result.Add(P =
new Point(X0, Y0));
272 History.AddLast(
new Rec(P, Dir));
273 Data[Index] &= 0x3fff;
277 for (i = 0; i < 8; i++)
279 dx = DirectionX[Dir];
280 dy = DirectionY[Dir];
285 if (x1 >= 0 && x1 < w && y1 >= 0 && y1 < h)
287 Index1 = Index + dx + dy *
RowSize;
289 if ((v & 0x3fff) == Nr && (v & 0xc000) > 0)
294 Result.Add(P =
new Point(x, y));
295 History.AddLast(
new Rec(P, Dir));
296 Data[Index] &= 0x3fff;
306 if (History.Last is
null)
310 Rec Rec = History.Last.Value;
311 History.RemoveLast();
320 return Result.ToArray();
323 private static readonly
int[] DirectionX =
new int[] { 1, 1, 0, -1, -1, -1, 0, 1 };
324 private static readonly
int[] DirectionY =
new int[] { 0, -1, -1, -1, 0, 1, 1, 1 };
328 public Rec(
Point P,
int Dir)
351 return this.
Extract(Nrs, this.image);
363 if (Source.
Width !=
this.Width || Source.
Height !=
this.Height)
364 throw new ArgumentOutOfRangeException(nameof(Source));
369 return this.Extract<float>(Nrs, M, Infos,
float.MinValue);
371 return this.Extract<int>(Nrs, M2, Infos,
int.MinValue);
373 return this.Extract<uint>(Nrs, M3, Infos, 0);
375 return this.Extract<byte>(Nrs, M4, Infos, 0);
377 throw new InvalidOperationException(
"Underlying image type not supported.");
382 int i, c = Nrs.Length;
385 for (i = 0; i < c; i++)
388 throw new ArgumentOutOfRangeException(nameof(Nrs));
406 if (Source.Width !=
this.Width || Source.Height !=
this.Height)
407 throw new ArgumentOutOfRangeException(nameof(Source));
411 return this.
Extract<T>(Nrs, Source, Infos,
default);
417 int x, y, c = Nrs.Length;
419 throw new ArgumentException(
"Array size mismatch.", nameof(
Objects));
430 for (x = 1; x < c; x++)
434 if (Info.
MinX < SrcX1)
437 if (Info.
MaxX > SrcX2)
440 if (Info.
MinY < SrcY1)
443 if (Info.
MaxY > SrcY2)
450 bool[] Included =
new bool[y + 2];
451 for (x = 0; x < c; x++)
452 Included[
Objects[x].Nr + 1] =
true;
456 int w = SrcX2 - SrcX1 + 1;
457 int h = SrcY2 - SrcY1 + 1;
459 int SrcSkip = Image.Skip + Image.Width - w;
460 int MaskIndex = this.
StartIndex(SrcX1, SrcY1);
461 int MaskSkip = Image.Width - w;
464 ushort[] Mask = this.
Data;
465 T[] Src =
Image.Data;
466 T[] Dest = Result.
Data;
469 for (y = SrcY1; y <= SrcY2; y++, SrcIndex += SrcSkip, MaskIndex += MaskSkip)
471 for (x = SrcX1; x <= SrcX2; x++, SrcIndex++)
473 i = Mask[MaskIndex++];
475 Dest[DestIndex++] = i < c && Included[i] ? Src[SrcIndex] : BackgroundValue;
Implements a Matrix, basic component for computations in Image Processing and Computer Vision.
int Height
Height of matrix (number of rows)
T[] Data
Underlying data on which the matrix is defined.
int Width
Width of matrix (number of columns)
int RowSize
Number of elements per row in underlying data array.
int Skip
Number of elements to skip from the right edge in the underlying data to the left edge of the new row...
int StartIndex(int X, int Y)
Gets the start index of a point in the image.
int Start
Start offset of matrix in underlying data.
Contains an object map of contents in an image.
ObjectMap(Matrix< float > M, float Threshold)
Contains an object map of contents in an image.
int NrObjects
Number of objects in map.
Matrix< T > Extract< T >(ushort[] Nrs, Matrix< T > Source)
Extracts one or more objects in the form of image from the underlying image. Only pixels pertaining t...
ObjectInformation[] Objects
Objects found in map.
IMatrix Extract(params ushort[] Nrs)
Extracts one or more objects in the form of image from the underlying image. Only pixels pertaining t...
IMatrix Image
Underlying image.
ObjectMap(Matrix< int > M, int Threshold)
Contains an object map of contents in an image.
IMatrix Extract(ushort[] Nrs, IMatrix Source)
Extracts one or more objects in the form of image from the underlying image. Only pixels pertaining t...
int Height
Height of matrix (number of rows)
int StartIndex(int X, int Y)
Gets the start index of a point in the image.
int Width
Width of matrix (number of columns)
Represents a point in an image.