MyCaffe  1.12.2.41
Deep learning software for Windows C# programmers.
SsdSampler.cs
1using MyCaffe.basecode;
2using MyCaffe.fillers;
3using MyCaffe.param;
4using MyCaffe.param.ssd;
5using System;
6using System.Collections.Generic;
7using System.Linq;
8using System.Text;
9using System.Threading.Tasks;
10
11namespace MyCaffe.common
12{
20 public class SsdSampler<T> : IDisposable
21 {
22 Log m_log;
23 CudaDnn<T> m_cuda;
24 BBoxUtility<T> m_util;
25 Blob<T> m_blobWork;
26 CryptoRandom m_random = new CryptoRandom();
27
31 public SsdSampler(CudaDnn<T> cuda, Log log)
32 {
33 m_log = log;
34 m_cuda = cuda;
35 m_blobWork = new Blob<T>(cuda, log, false);
36 m_util = new BBoxUtility<T>(cuda, log);
37 }
38
42 public void Dispose()
43 {
44 if (m_blobWork != null)
45 {
46 m_blobWork.Dispose();
47 m_blobWork = null;
48 }
49 }
50
56 public List<NormalizedBBox> GroupObjectBBoxes(SimpleDatum anno_datum)
57 {
58 List<NormalizedBBox> rgObjectBboxes = new List<NormalizedBBox>();
59
60 if (anno_datum.annotation_group == null)
61 return rgObjectBboxes;
62
63 for (int i = 0; i < anno_datum.annotation_group.Count; i++)
64 {
65 AnnotationGroup anno_group = anno_datum.annotation_group[i];
66
67 for (int j = 0; j < anno_group.annotations.Count; j++)
68 {
69 Annotation annotation = anno_group.annotations[j];
70 rgObjectBboxes.Add(annotation.bbox);
71 }
72 }
73
74 return rgObjectBboxes;
75 }
76
84 public bool SatisfySampleConstraint(NormalizedBBox sampledBBox, List<NormalizedBBox> rgObjectBboxes, SamplerConstraint sampleConstraint)
85 {
86 bool bHasJaccardOverlap = sampleConstraint.min_jaccard_overlap.HasValue || sampleConstraint.max_jaccard_overlap.HasValue;
87 bool bHasSampleCoverage = sampleConstraint.min_sample_coverage.HasValue || sampleConstraint.max_sample_coverage.HasValue;
88 bool bHasObjectCoverage = sampleConstraint.min_object_coverage.HasValue || sampleConstraint.max_object_coverage.HasValue;
89 bool bSatisfy = !bHasJaccardOverlap && !bHasSampleCoverage && !bHasObjectCoverage;
90
91 // By default, the sampledBBox is 'positive' if not constraints are defined.
92 if (bSatisfy)
93 return true;
94
95 // Check constraints.
96 bool bFound = false;
97 for (int i = 0; i < rgObjectBboxes.Count; i++)
98 {
99 NormalizedBBox objectBbox = rgObjectBboxes[i];
100
101 // Test jaccard overlap.
102 if (bHasJaccardOverlap)
103 {
104 float fJaccardOverlap = m_util.JaccardOverlap(sampledBBox, objectBbox);
105
106 if (sampleConstraint.min_jaccard_overlap.HasValue && fJaccardOverlap < sampleConstraint.min_jaccard_overlap.Value)
107 continue;
108
109 if (sampleConstraint.max_jaccard_overlap.HasValue && fJaccardOverlap > sampleConstraint.max_jaccard_overlap.Value)
110 continue;
111
112 bFound = true;
113 }
114
115 // Test sample coverage
116 if (bHasSampleCoverage)
117 {
118 float fSampleCoverage = m_util.Coverage(sampledBBox, objectBbox);
119
120 if (sampleConstraint.min_sample_coverage.HasValue && fSampleCoverage < sampleConstraint.min_sample_coverage.Value)
121 continue;
122
123 if (sampleConstraint.max_sample_coverage.HasValue && fSampleCoverage > sampleConstraint.max_sample_coverage.Value)
124 continue;
125
126 bFound = true;
127 }
128
129 // Test object coverage
130 if (bHasObjectCoverage)
131 {
132 float fObjectOverage = m_util.Coverage(objectBbox, sampledBBox);
133
134 if (sampleConstraint.min_object_coverage.HasValue && fObjectOverage < sampleConstraint.min_object_coverage.Value)
135 continue;
136
137 if (sampleConstraint.max_jaccard_overlap.HasValue && fObjectOverage > sampleConstraint.max_jaccard_overlap.Value)
138 continue;
139
140 bFound = true;
141 }
142
143 if (bFound)
144 return true;
145 }
146
147 return bFound;
148 }
149
150 private float randomUniformValue(float fMin, float fMax)
151 {
152 fMin = (float)Math.Round(fMin, 5);
153 fMax = (float)Math.Round(fMax, 5);
154
155 m_log.CHECK_LE(fMin, fMax, "The min mumst be <= the max!");
156
157 if (fMin == 0 && fMax == 0)
158 return 0.0f;
159 else if (fMin == 1 && fMax == 1)
160 return 1.0f;
161 else
162 {
163 double dfRandom = m_random.NextDouble();
164 float fRange = fMax - fMin;
165
166 return (float)(dfRandom * fRange) + fMin;
167 }
168 }
169
170 private NormalizedBBox sampleBBox(Sampler sampler)
171 {
172 // Get random scale.
173 m_log.CHECK_GE(sampler.max_scale, sampler.min_scale, "The sampler max scale must be >= the min scale.");
174 m_log.CHECK_GT(sampler.min_scale, 0, "The sampler min scale must be > 0.");
175 m_log.CHECK_LE(sampler.max_scale, 1, "The sampler max scale must be <= 1.");
176
177 float fScale = randomUniformValue(sampler.min_scale, sampler.max_scale);
178 float fAspectRatio = randomUniformValue(sampler.min_aspect_ratio, sampler.max_aspect_ratio);
179 float fPow2Scale = (float)Math.Pow(fScale, 2.0);
180
181 fAspectRatio = (float)Math.Max(fAspectRatio, fPow2Scale);
182 fAspectRatio = (float)Math.Min(fAspectRatio, 1.0 / fPow2Scale);
183 float fSqrtAspectRatio = (float)Math.Sqrt(fAspectRatio);
184
185 // Figure out bbox dimension
186 float fBboxWidth = fScale * fSqrtAspectRatio;
187 float fBboxHeight = fScale / fSqrtAspectRatio;
188
189 // Figure out top left coordinates
190 float fWoff = randomUniformValue(0, 1.0f - fBboxWidth);
191 float fHoff = randomUniformValue(0, 1.0f - fBboxHeight);
192
193 return new NormalizedBBox(fWoff, fHoff, fWoff + fBboxWidth, fHoff + fBboxHeight);
194 }
195
203 public List<NormalizedBBox> GenerateSamples(NormalizedBBox sourceBBox, List<NormalizedBBox> rgObjectBboxes, BatchSampler batchSampler)
204 {
205 List<NormalizedBBox> rgSampledBBoxes = new List<NormalizedBBox>();
206 int nFound = 0;
207
208 for (int i = 0; i < batchSampler.max_trials; i++)
209 {
210 if (batchSampler.max_sample > 0 && nFound >= batchSampler.max_sample)
211 break;
212
213 // Generate sampleBbox in the normalized space [0,1]
214 NormalizedBBox sampledBbox = sampleBBox(batchSampler.sampler);
215
216 // Transform the sampledBbox w.r.t. the source BBox.
217 sampledBbox = m_util.Locate(sourceBBox, sampledBbox);
218
219 // Determine if the sampled BBox is positive or negative by the constraint.
220 if (SatisfySampleConstraint(sampledBbox, rgObjectBboxes, batchSampler.sample_constraint))
221 {
222 nFound++;
223 rgSampledBBoxes.Add(sampledBbox);
224 }
225 }
226
227 return rgSampledBBoxes;
228 }
229
236 public List<NormalizedBBox> GenerateBatchSamples(SimpleDatum anno_datum, List<BatchSampler> rgBatchSamplers)
237 {
238 List<NormalizedBBox> rgSampledBBoxes = new List<NormalizedBBox>();
239 List<NormalizedBBox> rgObjectBBoxes = GroupObjectBBoxes(anno_datum);
240
241 for (int i = 0; i < rgBatchSamplers.Count; i++)
242 {
243 if (rgBatchSamplers[i].use_original_image)
244 {
245 NormalizedBBox unitBbox = new NormalizedBBox(0, 0, 1, 1);
246 rgSampledBBoxes.AddRange(GenerateSamples(unitBbox, rgObjectBBoxes, rgBatchSamplers[i]));
247 }
248 }
249
250 return rgSampledBBoxes;
251 }
252 }
253}
int Count
Specifies the number of items in the collection.
Definition: Annotation.cs:350
The AnnoationGroup class manages a group of annotations.
Definition: Annotation.cs:124
List< Annotation > annotations
Get/set the group annoations.
Definition: Annotation.cs:202
The Annotation class is used by annotations attached to SimpleDatum's and used in SSD.
Definition: Annotation.cs:22
NormalizedBBox bbox
Get/set the bounding box.
Definition: Annotation.cs:64
The CryptoRandom is a random number generator that can use either the standard .Net Random objec or t...
Definition: CryptoRandom.cs:14
double NextDouble()
Returns a random double within the range .
Definition: CryptoRandom.cs:83
The Log class provides general output in text form.
Definition: Log.cs:13
The NormalizedBBox manages a bounding box used in SSD.
The SimpleDatum class holds a data input within host memory.
Definition: SimpleDatum.cs:161
AnnotationGroupCollection annotation_group
When using annoations, each annotation group contains an annotation for a particular class used with ...
The BBox class processes the NormalizedBBox data used with SSD.
Definition: BBoxUtility.cs:22
float Coverage(NormalizedBBox bbox1, NormalizedBBox bbox2)
Compute the coverage of bbox1 by bbox2.
NormalizedBBox Locate(NormalizedBBox srcBbox, NormalizedBBox bbox)
Locate bbox in the coordinate system of the source Bbox.
float JaccardOverlap(NormalizedBBox bbox1, NormalizedBBox bbox2, bool bNormalized=true)
Calculates the Jaccard overlap between two bounding boxes.
The Blob is the main holder of data that moves through the Layers of the Net.
Definition: Blob.cs:25
virtual void Dispose(bool bDisposing)
Releases all resources used by the Blob (including both GPU and Host).
Definition: Blob.cs:402
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
Definition: CudaDnn.cs:969
The SsdSampler is used by the SSD algorithm to sample BBoxes.
Definition: SsdSampler.cs:21
List< NormalizedBBox > GroupObjectBBoxes(SimpleDatum anno_datum)
Find all annotated NormalizedBBox.
Definition: SsdSampler.cs:56
SsdSampler(CudaDnn< T > cuda, Log log)
The constructor.
Definition: SsdSampler.cs:31
List< NormalizedBBox > GenerateSamples(NormalizedBBox sourceBBox, List< NormalizedBBox > rgObjectBboxes, BatchSampler batchSampler)
Generate samples from the NormalizedBBox using the BatchSampler.
Definition: SsdSampler.cs:203
bool SatisfySampleConstraint(NormalizedBBox sampledBBox, List< NormalizedBBox > rgObjectBboxes, SamplerConstraint sampleConstraint)
Check if the sampled bbox satisfies the constraints with all object bboxes.
Definition: SsdSampler.cs:84
void Dispose()
Free all resources used.
Definition: SsdSampler.cs:42
List< NormalizedBBox > GenerateBatchSamples(SimpleDatum anno_datum, List< BatchSampler > rgBatchSamplers)
Generate samples from the annotated Datum using the list of BatchSamplers.
Definition: SsdSampler.cs:236
Specifies a sample of batch of bboxes with provided constraints in SSD.
Definition: BatchSampler.cs:22
SamplerConstraint sample_constraint
Get/set the sample constraint.
Sampler sampler
Specifies the constraints for sampling the bbox
uint max_trials
Maximum number of trials for sampling to avoid an infinite loop.
uint max_sample
If provided (greater than zero), break when found certain number of samples satisfying the sample con...
Definition: BatchSampler.cs:95
Specifies the constratins for selecting sampled bbox used in SSD.
float? max_object_coverage
Get/set the maximum Object coverage between sampled bbox and all boxes in AnnotationGroup.
float? min_object_coverage
Get/set the minimum Object coverage between sampled bbox and all boxes in AnnotationGroup.
float? max_jaccard_overlap
Get/set the maximum Jaccard overlap between sampled bbox and all boxes in AnnotationGroup.
float? min_sample_coverage
Get/set the minimum Sample coverage between sampled bbox and all boxes in AnnotationGroup.
float? max_sample_coverage
Get/set the maximum Sample coverage between sampled bbox and all boxes in AnnotationGroup.
float? min_jaccard_overlap
Get/set the minimum Jaccard overlap between sampled bbox and all boxes in AnnotationGroup.
Specifies the sample of a bbox in the normalized space [0,1] with provided constraints used in SSD.
Definition: Sampler.cs:22
float max_scale
Get/set the maximum scale of the sampled bbox.
Definition: Sampler.cs:92
float max_aspect_ratio
Get/set the maximum aspect ratio of the sampled bbox.
Definition: Sampler.cs:110
float min_scale
Get/set the minimum scale of the sampled bbox.
Definition: Sampler.cs:83
float min_aspect_ratio
Get/set the minimum aspect ratio of the sampled bbox.
Definition: Sampler.cs:101
The MyCaffe.basecode contains all generic types used throughout MyCaffe.
Definition: Annotation.cs:12
The MyCaffe.common namespace contains common MyCaffe classes.
Definition: BatchInput.cs:8
The MyCaffe.fillers namespace contains all fillers including the Filler class.
The MyCaffe.param.ssd namespace contains all SSD related parameter objects that correspond to the nat...
The MyCaffe.param namespace contains parameters used to create models.
The MyCaffe namespace contains the main body of MyCaffe code that closesly tracks the C++ Caffe open-...
Definition: Annotation.cs:12