12 private readonly Dictionary<ushort, ObjectInformation> objectsById =
new Dictionary<ushort, ObjectInformation>();
24 this.image = this.
Image;
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);
133 this.image = this.
Image;
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();
322#pragma warning disable IDE1006
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 };
325#pragma warning restore IDE1006
329 public Rec(
Point P,
int Dir)
352 return this.
Extract(Nrs, this.image);
364 if (Source.
Width !=
this.Width || Source.
Height !=
this.Height)
365 throw new ArgumentOutOfRangeException(nameof(Source));
370 return this.Extract<float>(Nrs, M, Infos,
float.MinValue);
372 return this.Extract<int>(Nrs, M2, Infos,
int.MinValue);
374 return this.Extract<uint>(Nrs, M3, Infos, 0);
376 return this.Extract<byte>(Nrs, M4, Infos, 0);
378 throw new InvalidOperationException(
"Underlying image type not supported.");
383 int i, c = Nrs.Length;
386 for (i = 0; i < c; i++)
389 throw new ArgumentOutOfRangeException(nameof(Nrs));
407 if (Source.Width !=
this.Width || Source.Height !=
this.Height)
408 throw new ArgumentOutOfRangeException(nameof(Source));
412 return this.
Extract<T>(Nrs, Source, Infos,
default);
418 int x, y, c = Nrs.Length;
420 throw new ArgumentException(
"Array size mismatch.", nameof(
Objects));
431 for (x = 1; x < c; x++)
435 if (Info.
MinX < SrcX1)
438 if (Info.
MaxX > SrcX2)
441 if (Info.
MinY < SrcY1)
444 if (Info.
MaxY > SrcY2)
451 bool[] Included =
new bool[y + 2];
452 for (x = 0; x < c; x++)
453 Included[
Objects[x].Nr + 1] =
true;
457 int w = SrcX2 - SrcX1 + 1;
458 int h = SrcY2 - SrcY1 + 1;
460 int SrcSkip = Image.Skip + Image.Width - w;
461 int MaskIndex = this.
StartIndex(SrcX1, SrcY1);
462 int MaskSkip = Image.Width - w;
465 ushort[] Mask = this.
Data;
466 T[] Src =
Image.Data;
467 T[] Dest = Result.
Data;
470 for (y = SrcY1; y <= SrcY2; y++, SrcIndex += SrcSkip, MaskIndex += MaskSkip)
472 for (x = SrcX1; x <= SrcX2; x++, SrcIndex++)
474 i = Mask[MaskIndex++];
476 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.