MyCaffe  1.12.2.41
Deep learning software for Windows C# programmers.
MasterIndexes.cs
1using MyCaffe.basecode;
3using System;
4using System.Collections.Generic;
5using System.Linq;
6using System.Text;
7using System.Threading.Tasks;
8
9namespace MyCaffe.db.image
10{
14 public class MasterIndexes : IDisposable
15 {
23 protected Index m_index = null;
27 protected LabelIndex m_rgLabels = null;
31 protected Index m_boosted = null;
35 protected LabelIndex m_rgLabelsBoosted = null;
36 CryptoRandom m_random;
37 CryptoRandom m_randomLabel = new CryptoRandom(CryptoRandom.METHOD.CRYPTO);
38 CryptoRandom m_randomLabelBoosted = new CryptoRandom(CryptoRandom.METHOD.CRYPTO);
39 DatasetFactory m_factory = new DatasetFactory();
40 List<DbItem> m_rgImageIdx = null;
41 IMGDB_SORT m_sort = IMGDB_SORT.BYIDX;
42 int m_nLoadLimit = 0;
43
50 public MasterIndexes(CryptoRandom random, SourceDescriptor src, int nLoadLimit = 0)
51 {
52 m_random = random;
53 m_src = src;
54 m_factory.Open(src);
55 m_nLoadLimit = nLoadLimit;
56
57 if (m_nLoadLimit > src.ImageCount)
58 m_nLoadLimit = src.ImageCount;
59
60 m_rgImageIdx = m_factory.LoadImageIndexes(false);
61 load(m_rgImageIdx.Where(p => p != null).ToList());
62 }
63
64 private void load(List<DbItem> rgItems)
65 {
66 m_index = new Index("ALL", m_random, rgItems);
67 List<DbItem> rgBoosted = rgItems.Where(p => p.Boost > 0).ToList();
68 m_boosted = new Index("BOOSTED", m_random, rgBoosted, -1, true);
69
70 List<LabelDescriptor> rgLabels = m_src.Labels.OrderBy(p => p.ActiveLabel).ToList();
71
72 m_rgLabels = new LabelIndex("LABELED", m_randomLabel, m_random, m_src, false, rgItems);
73 m_rgLabelsBoosted = new LabelIndex("LABELED BOOSTED", m_randomLabelBoosted, m_random, m_src, true, rgBoosted);
74 }
75
82 {
83 m_sort = sort;
84 m_src = idx.m_src;
85 m_random = idx.m_random;
86 m_nLoadLimit = idx.m_nLoadLimit;
87 m_factory = new DatasetFactory(idx.m_factory);
88
89 m_index = idx.m_index.Clone(sort);
90 m_rgLabels = new LabelIndex(idx.m_rgLabels);
91
92 m_boosted = idx.m_boosted.Clone(sort);
93 m_rgLabelsBoosted = new LabelIndex(idx.m_rgLabelsBoosted);
94 }
95
99 public void Dispose()
100 {
101 if (m_factory != null)
102 {
103 m_factory.Close();
104 m_factory.Dispose();
105 m_factory = null;
106 }
107 }
108
112 public List<DbItem> RawIndexes
113 {
114 get { return m_rgImageIdx; }
115 }
116
120 public int LoadLimit
121 {
122 get { return m_nLoadLimit; }
123 }
124
128 public int LabelCount
129 {
130 get { return m_rgLabels.Count; }
131 }
132
138 public List<DbItem> FindImageIndexes(DateTime dt)
139 {
140 return m_index.FindImageIndexes(dt);
141 }
142
147 public void Reload(List<DbItem> rgItems)
148 {
149 load(rgItems);
150 }
151
158 public Index GetIndex(int? nLabel = null, bool bBoosted = false)
159 {
160 if (!nLabel.HasValue)
161 {
162 if (!bBoosted)
163 return m_index;
164 else
165 return m_boosted;
166 }
167 else
168 {
169 if (!bBoosted)
170 return m_rgLabels.GetNextIndex(Index.SELECTION_TYPE.DIRECT, nLabel);
171 else
172 return m_rgLabelsBoosted.GetNextIndex(Index.SELECTION_TYPE.DIRECT, nLabel);
173 }
174 }
175
182 public void SetIndex(Index idx, int? nLabel = null, bool bBoosted = false)
183 {
184 if (!nLabel.HasValue)
185 {
186 if (!bBoosted)
187 m_index = idx;
188 else
189 m_boosted = idx;
190 }
191 else
192 {
193 if (!bBoosted)
194 m_rgLabels.SetIndex(nLabel.Value, idx);
195 else
196 m_rgLabelsBoosted.SetIndex(nLabel.Value, idx);
197 }
198 }
199
209 public List<int> GetIndexes(int nStartIdx, int nQueryCount = int.MaxValue, string strFilterVal = null, int? nBoostVal = null, bool bBoostValIsExact = false)
210 {
211 if (m_nLoadLimit > 0)
212 throw new Exception("The GetIndexes method is not valid when using LoadLimit > 0.");
213
214 Index idx = GetIndex(null, nBoostVal.HasValue);
215 List<DbItem> rgIdx = idx.FindImageIndexes(nStartIdx, nQueryCount, strFilterVal, nBoostVal, bBoostValIsExact);
216 return rgIdx.Select(p => p.Index).ToList();
217 }
218
228 public List<int> GetIndexes(DateTime dtStart, int nQueryCount = int.MaxValue, string strFilterVal = null, int? nBoostVal = null, bool bBoostValIsExact = false)
229 {
230 if (m_nLoadLimit > 0)
231 throw new Exception("The GetIndexes method is not valid when using LoadLimit > 0.");
232
233 Index idx = GetIndex(null, nBoostVal.HasValue);
234 List<DbItem> rgIdx = idx.FindImageIndexes(dtStart, nQueryCount, strFilterVal, nBoostVal, bBoostValIsExact);
235 return rgIdx.Select(p => p.Index).ToList();
236 }
237
244 public virtual int? GetNextLabel(Index.SELECTION_TYPE type, bool bBoosted = false)
245 {
246 LabelIndex rgIdx = (bBoosted) ? m_rgLabelsBoosted : m_rgLabels;
247 if (rgIdx.Count == 0)
248 return null;
249
250 return rgIdx.GetNextLabel(type, null, false);
251 }
252
261 public virtual int? GetNextImage(Index.SELECTION_TYPE type, int? nLabel = null, bool bBoosted = false, int nDirectIdx = -1)
262 {
263 if (m_nLoadLimit == 0)
264 {
265 Index idx = GetIndex(nLabel, bBoosted);
266 return idx.GetNext(type);
267 }
268 else
269 {
270 if (type != Index.SELECTION_TYPE.RANDOM)
271 throw new Exception("Only RANDOM selections are valid when using LoadLimit > 0.");
272
273 if (nLabel.HasValue)
274 throw new Exception("Label selections are not valid when using LoadLimit > 0");
275
276 if (bBoosted != false)
277 throw new Exception("Boosted queries are not valid when using LoadLimit > 0.");
278
279 if (nDirectIdx != -1)
280 throw new Exception("DirectIndex queries are not valid when using LoadLimit > 0.");
281
282 return m_random.Next(m_nLoadLimit);
283 }
284 }
285
290 public override string ToString()
291 {
292 string strOut = "";
293
294 if (m_sort == IMGDB_SORT.NONE)
295 {
296 strOut = "NONE";
297 }
298 else
299 {
300 if ((m_sort & IMGDB_SORT.BYID) == IMGDB_SORT.BYID)
301 strOut += "ID";
302
303 if ((m_sort & IMGDB_SORT.BYDESC) == IMGDB_SORT.BYDESC)
304 {
305 if (strOut.Length > 0)
306 strOut += " | ";
307 strOut += "DESC";
308 }
309
310 if ((m_sort & IMGDB_SORT.BYIDX) == IMGDB_SORT.BYIDX)
311 {
312 if (strOut.Length > 0)
313 strOut += " | ";
314 strOut += "IDX";
315 }
316
317 if ((m_sort & IMGDB_SORT.BYID_DESC) == IMGDB_SORT.BYID_DESC)
318 {
319 if (strOut.Length > 0)
320 strOut += " | ";
321 strOut += "ID(desc)";
322 }
323
324
325 if ((m_sort & IMGDB_SORT.BYTIME) == IMGDB_SORT.BYTIME)
326 {
327 if (strOut.Length > 0)
328 strOut += " | ";
329 strOut += "TIME";
330 }
331 }
332
333 return strOut;
334 }
335 }
336
337#pragma warning disable 1591
338
339 public class LabelIndex
340 {
341 string m_strName;
342 CryptoRandom m_randomData;
343 CryptoRandom m_randomLabel;
344 SourceDescriptor m_src;
345 Dictionary<int, int> m_rgLabelToIdxMap = new Dictionary<int, int>();
346 Dictionary<int, int> m_rgIdxToLabelMap = new Dictionary<int, int>();
347 Index[] m_rgLabels = null;
348 bool m_bBoosted = false;
349 List<int> m_rgIdx = new List<int>();
350 int m_nIdx = 0;
351 object m_objSync = new object();
352
353 public LabelIndex(string strName, CryptoRandom randomLabel, CryptoRandom randomData, SourceDescriptor src, bool bBoosted, List<DbItem> rgItems)
354 {
355 m_strName = strName;
356 m_randomLabel = randomLabel;
357 m_randomData = randomData;
358 m_src = src;
359 m_bBoosted = bBoosted;
360
361 m_rgIdx = new List<int>();
362 m_rgLabelToIdxMap = new Dictionary<int, int>();
363 m_rgIdxToLabelMap = new Dictionary<int, int>();
364
365 List<LabelDescriptor> rgLabels = src.Labels.Where(p => p.ImageCount > 0).OrderBy(p => p.ActiveLabel).ToList();
366 if (rgLabels.Count > 0)
367 {
368 m_rgLabels = new Index[rgLabels.Count];
369
370 for (int i = 0; i < rgLabels.Count; i++)
371 {
372 int nLabel = rgLabels[i].ActiveLabel;
373 List<DbItem> rgLabelList = rgItems.Where(p => p.Label == nLabel).ToList();
374
375 if (i < rgLabels.Count - 1)
376 rgItems = rgItems.Where(p => p.Label != nLabel).ToList();
377
378 m_rgLabels[i] = new Index(strName + " label " + nLabel.ToString(), randomData, rgLabelList, nLabel, false);
379 if (rgLabelList.Count > 0)
380 m_rgIdx.Add(i);
381
382 m_rgLabelToIdxMap[nLabel] = i;
383 m_rgIdxToLabelMap[i] = nLabel;
384 }
385 }
386 }
387
388 public LabelIndex(LabelIndex idx)
389 {
390 m_strName = idx.m_strName + " copy";
391 m_randomLabel = idx.m_randomLabel;
392 m_randomData = idx.m_randomData;
393 m_src = idx.m_src;
394 m_bBoosted = idx.m_bBoosted;
395
396 m_rgIdx = new List<int>();
397
398 if (idx.m_rgLabels != null && idx.m_rgLabels.Length > 0)
399 {
400 m_rgLabels = new Index[idx.m_rgLabels.Length];
401
402 bool bFillLabelMap = false;
403 if (m_rgLabelToIdxMap == null || m_rgLabelToIdxMap.Count == 0 || m_rgIdxToLabelMap == null || m_rgIdxToLabelMap.Count == 0)
404 {
405 m_rgLabelToIdxMap = new Dictionary<int, int>();
406 m_rgIdxToLabelMap = new Dictionary<int, int>();
407 bFillLabelMap = true;
408 }
409
410 for (int i = 0; i < idx.m_rgLabels.Length; i++)
411 {
412 m_rgLabels[i] = idx.m_rgLabels[i].Clone();
413 if (m_rgLabels[i].Count > 0)
414 m_rgIdx.Add(i);
415
416 if (bFillLabelMap)
417 {
418 int nLabel = m_rgLabels[i].Label;
419 m_rgLabelToIdxMap[nLabel] = i;
420 m_rgIdxToLabelMap[i] = nLabel;
421 }
422 }
423 }
424 }
425
426 public void ReLoad()
427 {
428 if (m_rgIdx.Count == m_rgLabels.Length)
429 return;
430
431 lock (m_objSync)
432 {
433 for (int i = 0; i < m_rgLabels.Length; i++)
434 {
435 if (m_rgLabels[i].Count > 0)
436 m_rgIdx.Add(i);
437 }
438 }
439 }
440
441 public void SetIndex(int nLabel, Index idx)
442 {
443 int nIdx = m_rgLabelToIdxMap[nLabel];
444 m_rgLabels[nIdx] = idx;
445 }
446
447 public int Count
448 {
449 get { return (m_rgLabels == null) ? 0 : m_rgLabels.Length; }
450 }
451
452 public bool Boosted
453 {
454 get { return m_bBoosted; }
455 }
456
457 public bool IsEmpty
458 {
459 get { return (m_rgIdx.Count == 0) ? true : false; }
460 }
461
462 public LabelIndex Clone()
463 {
464 return new LabelIndex(this);
465 }
466
467 public int? GetNextLabel(Index.SELECTION_TYPE type, int? nLabel, bool bRemove = false)
468 {
469 if (m_rgIdx.Count == 0)
470 return null;
471
472 if (nLabel.HasValue)
473 {
474 return nLabel.Value;
475 }
476 else if (type == Index.SELECTION_TYPE.SEQUENTIAL)
477 {
478 int nIdx = m_rgIdx[m_nIdx];
479
480 m_nIdx++;
481 if (m_nIdx >= m_rgIdx.Count)
482 m_nIdx = 0;
483
484 return m_rgIdxToLabelMap[nIdx];
485 }
486 else
487 {
488 lock (m_objSync)
489 {
490 int nIdxLoc = 0;
491
492 // Reload on the fly if empty.
493 if (m_rgIdx.Count == 0)
494 {
495 for (int i = 0; i < m_rgLabels.Length; i++)
496 {
497 if (m_rgLabels[i].Count > 0)
498 m_rgIdx.Add(i);
499 }
500 }
501
502 int nIdx = m_rgIdx[nIdxLoc];
503
504 if (m_rgIdx.Count > 1)
505 {
506 nIdxLoc = m_randomLabel.Next(0, m_rgIdx.Count - 1, true);
507 nIdx = m_rgIdx[nIdxLoc];
508 }
509
510 if (bRemove)
511 m_rgIdx.RemoveAt(nIdxLoc);
512
513 return m_rgIdxToLabelMap[nIdx];
514 }
515 }
516 }
517
518 public Index GetNextIndex(Index.SELECTION_TYPE type, int? nLabel, bool bRemove = false)
519 {
520 nLabel = GetNextLabel(type, nLabel, bRemove);
521 if (!nLabel.HasValue)
522 return null;
523
524 if (!m_rgLabelToIdxMap.ContainsKey(nLabel.Value))
525 return null;
526
527 int nIdx = m_rgLabelToIdxMap[nLabel.Value];
528
529 return m_rgLabels[nIdx];
530 }
531
532 public override string ToString()
533 {
534 return m_strName;
535 }
536 }
537
538 public class Index
539 {
540 string m_strName;
541 CryptoRandom m_random;
542 int m_nLabel = -1;
543 bool m_bBoosted = false;
544 int m_nIdx = 0;
545 List<DbItem> m_rgItems;
546 double m_dfProbability = 0;
547 object m_objSync = new object();
548
549 public enum SELECTION_TYPE
550 {
551 DIRECT,
552 SEQUENTIAL,
553 RANDOM
554 }
555
556 public Index(string strName, CryptoRandom random, List<DbItem> rgItems, int nLabel = -1, bool bBoosted = false, double dfProbability = 0)
557 {
558 m_strName = strName;
559 m_random = random;
560 m_rgItems = rgItems;
561 m_nLabel = nLabel;
562 m_bBoosted = bBoosted;
563 m_dfProbability = dfProbability;
564 }
565
566 public int Count
567 {
568 get { return m_rgItems.Count; }
569 }
570
571 public double Probability
572 {
573 get { return m_dfProbability; }
574 set { m_dfProbability = value; }
575 }
576
577 public int Label
578 {
579 get { return m_nLabel; }
580 }
581
582 public bool Boosted
583 {
584 get { return m_bBoosted; }
585 }
586
587 public bool IsEmpty
588 {
589 get { return (m_rgItems.Count == 0) ? true : false; }
590 }
591
592 public Index Clone(IMGDB_SORT sort = IMGDB_SORT.NONE)
593 {
594 List<DbItem> rgItems = new List<DbItem>();
595
596 for (int i = 0; i < m_rgItems.Count; i++)
597 {
598 rgItems.Add(m_rgItems[i].Clone());
599 }
600
601 switch (sort)
602 {
603 case IMGDB_SORT.BYID:
604 rgItems = rgItems.OrderBy(p => p.ID).ToList();
605 break;
606
607 case IMGDB_SORT.BYID_DESC:
608 rgItems = rgItems.OrderByDescending(p => p.ID).ToList();
609 break;
610
611 case IMGDB_SORT.BYIDX:
612 rgItems = rgItems.OrderBy(p => p.Index).ToList();
613 break;
614
615 case IMGDB_SORT.BYDESC:
616 rgItems = rgItems.OrderBy(p => p.Desc).ThenBy(p => p.Index).ToList();
617 break;
618
619 case IMGDB_SORT.BYTIME:
620 rgItems = rgItems.OrderBy(p => p.Time).ToList();
621 break;
622
623 default:
624 if ((sort & (IMGDB_SORT.BYDESC | IMGDB_SORT.BYTIME)) == (IMGDB_SORT.BYDESC | IMGDB_SORT.BYTIME))
625 rgItems = rgItems.OrderBy(p => p.Desc).ThenBy(p => p.Time).ToList();
626 break;
627 }
628
629 return new Index(m_strName + " copy", m_random, rgItems, m_nLabel, m_bBoosted, m_dfProbability);
630 }
631
632 public List<DbItem> FindImageIndexes(int nStartIdx, int nQueryCount = int.MaxValue, string strFilter = null, int? nBoostVal = null, bool bBoostValIsExact = false)
633 {
634 IEnumerable<DbItem> iQuery = m_rgItems.Where(p => p.Index >= nStartIdx);
635
636 if (strFilter != null)
637 iQuery = iQuery.Where(p => p.Desc == strFilter);
638
639 if (nBoostVal.HasValue)
640 {
641 if (bBoostValIsExact)
642 iQuery = iQuery.Where(p => p.Boost == nBoostVal.Value);
643 else
644 iQuery = iQuery.Where(p => p.Boost >= nBoostVal.Value);
645 }
646
647 return iQuery.Take(nQueryCount).ToList();
648 }
649
650 public List<DbItem> FindImageIndexes(DateTime dtStart, int nQueryCount = int.MaxValue, string strFilter = null, int? nBoostVal = null, bool bBoostValIsExact = false)
651 {
652 IEnumerable<DbItem> iQuery = m_rgItems.Where(p => p.Time >= dtStart);
653
654 if (strFilter != null)
655 iQuery = iQuery.Where(p => p.Desc == strFilter);
656
657 if (nBoostVal.HasValue)
658 {
659 if (bBoostValIsExact)
660 iQuery = iQuery.Where(p => p.Boost == nBoostVal.Value);
661 else
662 iQuery = iQuery.Where(p => p.Boost >= nBoostVal.Value);
663 }
664
665 return iQuery.Take(nQueryCount).ToList();
666 }
667
668 public List<DbItem> FindImageIndexes(DateTime dt)
669 {
670 return m_rgItems.Where(p => p.Time == dt).ToList();
671 }
672
673 public int? GetNext(SELECTION_TYPE type, bool bRemove = false)
674 {
675 if (m_rgItems.Count == 0)
676 return null;
677
678 if (type == SELECTION_TYPE.SEQUENTIAL)
679 {
680 int nIdx = m_rgItems[m_nIdx].Index;
681
682 m_nIdx++;
683 if (m_nIdx >= m_rgItems.Count)
684 m_nIdx = 0;
685
686 return nIdx;
687 }
688 else
689 {
690 lock (m_objSync)
691 {
692 int nCount = m_rgItems.Count;
693 if (nCount == 0)
694 return null;
695
696 int nIdx = m_random.Next(nCount);
697 if (m_rgItems[nIdx] == null)
698 {
699 m_rgItems.RemoveAt(nIdx);
700 nCount = m_rgItems.Count;
701 if (nCount == 0)
702 return null;
703
704 nIdx = m_random.Next(nCount);
705 }
706
707 int nFinalIdx = m_rgItems[nIdx].Index;
708
709 if (bRemove)
710 m_rgItems.RemoveAt(nIdx);
711
712 m_nIdx = nIdx + 1;
713 if (m_nIdx == m_rgItems.Count)
714 m_nIdx = 0;
715
716 return nFinalIdx;
717 }
718 }
719 }
720
721 public int? GetIndex(int nDirectIdx)
722 {
723 if (nDirectIdx < 0 || nDirectIdx >= m_rgItems.Count)
724 return null;
725
726 m_nIdx = nDirectIdx;
727 if (m_nIdx == m_rgItems.Count)
728 m_nIdx = 0;
729
730 return m_rgItems[nDirectIdx].Index;
731 }
732
733 public override string ToString()
734 {
735 return m_strName + ": Count = " + m_rgItems.Count().ToString() + " CurIdx = " + m_nIdx.ToString() + "; Label = " + m_nLabel.ToString() + "; Boosted = " + m_bBoosted.ToString() + " => (" + m_rgItems.Count.ToString() + ") p = " + m_dfProbability.ToString("P");
736 }
737 }
738
739#pragma warning restore 1591
740}
The CryptoRandom is a random number generator that can use either the standard .Net Random objec or t...
Definition: CryptoRandom.cs:14
METHOD
Defines the random number generation method to use.
Definition: CryptoRandom.cs:25
int Next(int nMinVal, int nMaxVal, bool bMaxInclusive=true)
Returns a random int within the range
The SourceDescriptor class contains all information describing a data source.
List< LabelDescriptor > Labels
Get/set the list of LabelDescriptors that describe the labels used by the data items.
int ImageCount
Returns the number of images within this data source.
The DatasetFactory manages the connection to the Database object.
List< DbItem > LoadImageIndexes(bool bBoostedOnly, bool bIncludeActive=true, bool bIncludeInactive=false)
Returns a list of the image indexes of all boosted images in the Data Source.
void Close()
Close the current data source used.
void Dispose()
Releases all resources used.
void Open(SourceDescriptor src, int nCacheMax=500, ConnectInfo ci=null)
Open a given data source.
The MasterIndexes stores the indexes that define the index structure of the data source data.
void Dispose()
Release all resources used.
override string ToString()
Returns a string representation of the master indexes.
LabelIndex m_rgLabelsBoosted
Specifies the list of all boosted images listed by label where each label contains an index into all ...
virtual ? int GetNextImage(Index.SELECTION_TYPE type, int? nLabel=null, bool bBoosted=false, int nDirectIdx=-1)
Returns the next image in the Index set based on the selection criteria.
virtual ? int GetNextLabel(Index.SELECTION_TYPE type, bool bBoosted=false)
Returns the next label in the Index set selected based on the selection criteria.
List< int > GetIndexes(DateTime dtStart, int nQueryCount=int.MaxValue, string strFilterVal=null, int? nBoostVal=null, bool bBoostValIsExact=false)
Returns the indexes fitting the criteria.
int LabelCount
Returns the number of labels.
void SetIndex(Index idx, int? nLabel=null, bool bBoosted=false)
Set a given index based on the criteria.
void Reload(List< DbItem > rgItems)
Reload all images by re-loading the master index list.
int LoadLimit
Returns the load limit set during initialization.
SourceDescriptor m_src
Specifies the data source descriptor.
MasterIndexes(MasterIndexes idx, IMGDB_SORT sort)
The constructor used to copy another MasterIndexes and optionally specify a sorting for the indexes.
Index m_index
Specifies the index into all of the data source images.
LabelIndex m_rgLabels
Specifies the list of images listed by label where each label contains an index into all images with ...
List< DbItem > RawIndexes
Returns the raw indexes.
MasterIndexes(CryptoRandom random, SourceDescriptor src, int nLoadLimit=0)
The constructor.
List< DbItem > FindImageIndexes(DateTime dt)
Returns all DbItems that point to images iwth a given date.
List< int > GetIndexes(int nStartIdx, int nQueryCount=int.MaxValue, string strFilterVal=null, int? nBoostVal=null, bool bBoostValIsExact=false)
Returns the indexes fitting the criteria.
Index GetIndex(int? nLabel=null, bool bBoosted=false)
Returns the Index matching the criteria.
Index m_boosted
Specifies the list of all boosted images.
The descriptors namespace contains all descriptor used to describe various items stored within the da...
The MyCaffe.basecode contains all generic types used throughout MyCaffe.
Definition: Annotation.cs:12
@ RANDOM
Randomly select the images, ignore the input index.
IMGDB_SORT
Defines the sorting method.
Definition: Interfaces.cs:358
The MyCaffe.db.image namespace contains all image database related classes.
Definition: Database.cs:18
The MyCaffe namespace contains the main body of MyCaffe code that closesly tracks the C++ Caffe open-...
Definition: Annotation.cs:12