Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
Matrix.cs
1using SkiaSharp;
2using System;
3
4namespace IdApp.Cv
5{
10 public class Matrix<T> : IMatrix
11 where T : struct
12 {
13 private T[] data;
14 private int width;
15 private int height;
16 private int left;
17 private int top;
18 private int rowSize;
19 private int dataSize;
20 private int start;
21 private int skip;
22
23 private Matrix()
24 {
25 this.data = [];
26 }
27
33 public Matrix(int Width, int Height)
34 : this(Width, Height, new T[Width * Height])
35 {
36 }
37
44 public Matrix(int Width, int Height, T[] Data)
45 {
46 this.dataSize = Width * Height;
47 if (this.dataSize != Data.Length)
48 throw new ArgumentOutOfRangeException(nameof(Data));
49
50 this.data = Data;
51 this.width = Width;
52 this.height = Height;
53 this.left = 0;
54 this.top = 0;
55 this.start = 0;
56 this.rowSize = Width;
57 this.skip = 0;
58 }
59
71 protected Matrix(int Width, int Height, T[] Data, int Left, int Top, int RowSize,
72 int Start, int Skip)
73 {
74 this.dataSize = Data.Length;
75 this.data = Data;
76 this.width = Width;
77 this.height = Height;
78 this.left = Left;
79 this.top = Top;
80 this.start = Start;
81 this.rowSize = RowSize;
82 this.skip = Skip;
83 }
84
90 public virtual Matrix<T> ShallowCopy()
91 {
92 return new Matrix<T>()
93 {
94 data = this.data,
95 width = this.width,
96 height = this.height,
97 left = this.left,
98 top = this.top,
99 start = this.start,
100 rowSize = this.rowSize,
101 dataSize = this.dataSize,
102 skip = this.skip
103 };
104 }
105
109 public Type ElementType => typeof(T);
110
114 public T[] Data => this.data;
115
119 public int Width
120 {
121 get => this.width;
122 set
123 {
124 if (value <= 0 || value >= this.rowSize - this.left)
125 throw new ArgumentOutOfRangeException(nameof(this.Width));
126
127 this.width = value;
128 this.skip = this.rowSize - this.width;
129 }
130 }
131
135 public int Height
136 {
137 get => this.height;
138 set
139 {
140 if (value <= 0 || (this.top + value) * this.width >= this.dataSize)
141 throw new ArgumentOutOfRangeException(nameof(this.Height));
142
143 this.height = value;
144 }
145 }
146
150 public int Left
151 {
152 get => this.left;
153 set
154 {
155 if (value < 0 || value >= this.rowSize - this.width)
156 throw new ArgumentOutOfRangeException(nameof(this.Left));
157
158 this.left = value;
159 this.start = this.left + this.top * this.rowSize;
160 }
161 }
162
166 public int Top
167 {
168 get => this.top;
169 set
170 {
171 if (value < 0 || (value + this.height) * this.width >= this.dataSize)
172 throw new ArgumentOutOfRangeException(nameof(this.Top));
173
174 this.top = value;
175 this.start = this.left + this.top * this.rowSize;
176 }
177 }
178
184 public void SetXSpan(int Left, int Width)
185 {
186 if (Left < 0 || Left + Width > this.rowSize)
187 throw new ArgumentOutOfRangeException(nameof(Left));
188
189 if (Width <= 0)
190 throw new ArgumentOutOfRangeException(nameof(Width));
191
192 this.left = Left;
193 this.start = this.left + this.top * this.rowSize;
194 this.width = Width;
195 this.skip = this.rowSize - this.width;
196 }
197
203 public void SetYSpan(int Top, int Height)
204 {
205 if (Top < 0 || (Top + Height) * this.width > this.dataSize)
206 throw new ArgumentOutOfRangeException(nameof(Top));
207
208 if (Height <= 0)
209 throw new ArgumentOutOfRangeException(nameof(Height));
210
211 this.top = Top;
212 this.height = Height;
213 this.start = this.left + this.top * this.rowSize;
214 }
218 public int RowSize => this.rowSize;
219
223 public int DataSize => this.dataSize;
224
228 public int Start => this.start;
229
233 public int Skip => this.skip;
234
241 public T this[int X, int Y]
242 {
243 get => this.data[(X + this.left) + (Y + this.top) * this.rowSize];
244 set => this.data[(X + this.left) + (Y + this.top) * this.rowSize] = value;
245 }
246
253 public int StartIndex(int X, int Y)
254 {
255 return (X + this.left) + (Y + this.top) * this.rowSize;
256 }
257
263 public Matrix<T> Row(int RowIndex)
264 {
265 if (RowIndex < 0 || RowIndex >= this.height)
266 throw new ArgumentOutOfRangeException(nameof(RowIndex));
267
268 return new Matrix<T>()
269 {
270 data = this.data,
271 width = this.width,
272 height = 1,
273 left = this.left,
274 top = this.top + RowIndex,
275 rowSize = this.rowSize,
276 dataSize = this.dataSize,
277 start = this.start + (RowIndex * this.rowSize),
278 skip = this.skip
279 };
280 }
281
287 public Matrix<T> Column(int ColumnIndex)
288 {
289 if (ColumnIndex < 0 || ColumnIndex >= this.width)
290 throw new ArgumentOutOfRangeException(nameof(ColumnIndex));
291
292 return new Matrix<T>()
293 {
294 data = this.data,
295 width = 1,
296 height = this.height,
297 left = this.left + ColumnIndex,
298 top = this.top,
299 rowSize = this.rowSize,
300 dataSize = this.dataSize,
301 start = this.start + ColumnIndex,
302 skip = this.rowSize - 1
303 };
304 }
305
314 public Matrix<T> Region(int Left, int Top, int Width, int Height)
315 {
316 if (Left < 0 || Left >= this.width)
317 throw new ArgumentOutOfRangeException(nameof(Left));
318
319 if (Top < 0 || Top >= this.height)
320 throw new ArgumentOutOfRangeException(nameof(Top));
321
322 if (Width <= 0 || Width > this.width - this.left - Left)
323 throw new ArgumentOutOfRangeException(nameof(Width));
324
325 if (Height <= 0 || Height > this.height - this.top - Top)
326 throw new ArgumentOutOfRangeException(nameof(Height));
327
328 return new Matrix<T>()
329 {
330 data = this.data,
331 width = Width,
332 height = Height,
333 left = this.left + Left,
334 top = this.top + Top,
335 rowSize = this.rowSize,
336 dataSize = this.dataSize,
337 start = this.start + Left + (Top * this.rowSize),
338 skip = this.rowSize - Width
339 };
340 }
341
347 public static IMatrix LoadFromFile(string FileName)
348 {
349 using SKBitmap Bmp = SKBitmap.Decode(FileName);
350 byte[] Data = Bmp.Bytes;
351
352 switch (Bmp.BytesPerPixel)
353 {
354 case 1:
355 return new Matrix<byte>(Bmp.Width, Bmp.Height, Data);
356
357 case 2:
358 int i, j, c = Data.Length;
359 ushort[] Bin16 = new ushort[c / 2];
360 ushort u;
361
362 i = j = 0;
363 while (i < c)
364 {
365 u = Data[i++];
366 u <<= 8;
367 u |= Data[i++];
368 Bin16[j++] = u;
369 }
370
371 return new Matrix<ushort>(Bmp.Width, Bmp.Height, Bin16);
372
373 case 3:
374 c = Data.Length;
375 uint[] Bin32 = new uint[c / 3];
376 uint v;
377
378 i = j = 0;
379 while (i < c)
380 {
381 v = Data[i++];
382 v <<= 8;
383 v |= Data[i++];
384 v <<= 8;
385 v |= Data[i++];
386 Bin32[j++] = v;
387 }
388
389 return new Matrix<uint>(Bmp.Width, Bmp.Height, Bin32);
390
391 case 4:
392 c = Data.Length;
393 Bin32 = new uint[c / 4];
394
395 i = j = 0;
396 while (i < c)
397 {
398 v = Data[i++];
399 v <<= 8;
400 v |= Data[i++];
401 v <<= 8;
402 v |= Data[i++];
403 v <<= 8;
404 v |= Data[i++];
405 Bin32[j++] = v;
406 }
407
408 return new Matrix<uint>(Bmp.Width, Bmp.Height, Bin32);
409
410 default:
411 throw new ArgumentException("Color type not supported.", nameof(FileName));
412 }
413 }
414
415 }
416}
Implements a Matrix, basic component for computations in Image Processing and Computer Vision.
Definition: Matrix.cs:12
void SetYSpan(int Top, int Height)
Sets Top and Height simultaneously.
Definition: Matrix.cs:203
virtual Matrix< T > ShallowCopy()
Creates a shallow copy of the matrix. The shallow copy points to the same underlying pixel data.
Definition: Matrix.cs:90
int Height
Height of matrix (number of rows)
Definition: Matrix.cs:136
T[] Data
Underlying data on which the matrix is defined.
Definition: Matrix.cs:114
static IMatrix LoadFromFile(string FileName)
Loads an image into a matrix.
Definition: Matrix.cs:347
int Width
Width of matrix (number of columns)
Definition: Matrix.cs:120
Matrix(int Width, int Height)
Implements a Matrix, basic component for computations in Image Processing and Computer Vision.
Definition: Matrix.cs:33
Matrix(int Width, int Height, T[] Data, int Left, int Top, int RowSize, int Start, int Skip)
Implements a Matrix, basic component for computations in Image Processing and Computer Vision.
Definition: Matrix.cs:71
Matrix< T > Row(int RowIndex)
Returns a row vector as a matrix.
Definition: Matrix.cs:263
Matrix< T > Region(int Left, int Top, int Width, int Height)
Returns a region of the matrix, as a new matrix.
Definition: Matrix.cs:314
int Left
Left offset of matrix in underlying data array.
Definition: Matrix.cs:151
int DataSize
Total number of elements in underlying data array.
Definition: Matrix.cs:223
Matrix(int Width, int Height, T[] Data)
Implements a Matrix, basic component for computations in Image Processing and Computer Vision.
Definition: Matrix.cs:44
Type ElementType
Type of elements in matrix.
Definition: Matrix.cs:109
int RowSize
Number of elements per row in underlying data array.
Definition: Matrix.cs:218
int Skip
Number of elements to skip from the right edge in the underlying data to the left edge of the new row...
Definition: Matrix.cs:233
int StartIndex(int X, int Y)
Gets the start index of a point in the image.
Definition: Matrix.cs:253
Matrix< T > Column(int ColumnIndex)
Returns a column vector as a matrix.
Definition: Matrix.cs:287
void SetXSpan(int Left, int Width)
Sets Left and Width simultaneously.
Definition: Matrix.cs:184
int Top
Top offset of matrix in underlying data array.
Definition: Matrix.cs:167
int Start
Start offset of matrix in underlying data.
Definition: Matrix.cs:228
Interface for matrices.
Definition: IMatrix.cs:9
Definition: Abs.cs:2