-
Notifications
You must be signed in to change notification settings - Fork 70
/
Copy pathRawBoundingBoxParser.cs
104 lines (83 loc) · 3.2 KB
/
RawBoundingBoxParser.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
namespace Compunet.YoloV8.Services;
internal class RawBoundingBoxParser(YoloMetadata metadata,
YoloConfiguration configuration,
IMemoryAllocatorService memoryAllocator,
INonMaxSuppressionService nonMaxSuppression) : IRawBoundingBoxParser
{
private T[] ParseYoloV8<T>(DenseTensor<float> tensor) where T : IRawBoundingBox<T>
{
var stride1 = tensor.Strides[1];
var boxesCount = tensor.Dimensions[2];
var namesCount = metadata.Names.Length;
var boxes = memoryAllocator.Allocate<T>(boxesCount);
var boxesIndex = 0;
var boxesSpan = boxes.Memory.Span;
var tensorSpan = tensor.Buffer.Span;
var context = new RawParsingContext
{
Architecture = YoloArchitecture.YoloV8,
Tensor = tensor,
Stride1 = stride1,
NameCount = namesCount,
};
for (var boxIndex = 0; boxIndex < boxesCount; boxIndex++)
{
for (var nameIndex = 0; nameIndex < namesCount; nameIndex++)
{
var confidence = tensorSpan[(nameIndex + 4) * stride1 + boxIndex];
if (confidence <= configuration.Confidence)
{
continue;
}
var box = T.Parse(ref context, boxIndex, nameIndex, confidence);
if (box.Bounds.Width == 0 || box.Bounds.Height == 0)
{
continue;
}
boxesSpan[boxesIndex++] = box;
}
}
return nonMaxSuppression.Suppress(boxesSpan[..boxesIndex], configuration.IoU);
}
private T[] ParseYoloV10<T>(DenseTensor<float> tensor) where T : IRawBoundingBox<T>
{
var stride1 = tensor.Strides[1];
var stride2 = tensor.Strides[2];
var boxesCount = tensor.Dimensions[1];
var boxes = memoryAllocator.Allocate<T>(boxesCount);
var boxesIndex = 0;
var boxesSpan = boxes.Memory.Span;
var tensorSpan = tensor.Buffer.Span;
var context = new RawParsingContext
{
Architecture = YoloArchitecture.YoloV10,
Tensor = tensor,
Stride1 = stride1
};
for (var index = 0; index < boxesCount; index++)
{
var boxOffset = index * stride1;
var confidence = tensorSpan[boxOffset + 4 * stride2];
if (confidence <= configuration.Confidence)
{
continue;
}
var nameIndex = (int)tensorSpan[boxOffset + 5 * stride2];
var box = T.Parse(ref context, index, nameIndex, confidence);
if (box.Bounds.Width == 0 || box.Bounds.Height == 0)
{
continue;
}
boxesSpan[boxesIndex++] = box;
}
return nonMaxSuppression.Suppress(boxesSpan[..boxesIndex], configuration.IoU);
}
public T[] Parse<T>(DenseTensor<float> tensor) where T : IRawBoundingBox<T>
{
if (metadata.Architecture == YoloArchitecture.YoloV10)
{
return ParseYoloV10<T>(tensor);
}
return ParseYoloV8<T>(tensor);
}
}