@@ -25,12 +25,12 @@ namespace OpenCvSharp.Blob
2525 /// <summary>
2626 /// Blob set
2727 /// </summary>
28- public class CvBlobs : Dictionary < int , CvBlob >
28+ public class CvBlobs : Dictionary < int , CvBlob > , ICloneable
2929 {
3030 /// <summary>
3131 /// Label values
3232 /// </summary>
33- public LabelData Labels { get ; protected set ; }
33+ public LabelData Labels { get ; set ; }
3434
3535 /// <summary>
3636 /// Constructor (init only)
@@ -39,6 +39,26 @@ public CvBlobs()
3939 {
4040 }
4141
42+ /// <summary>
43+ /// Constructor (copy)
44+ /// </summary>
45+ public CvBlobs ( IEnumerable < KeyValuePair < int , CvBlob > > blobData , int [ , ] labelData )
46+ {
47+ foreach ( KeyValuePair < int , CvBlob > pair in blobData )
48+ {
49+ Add ( pair . Key , pair . Value ) ;
50+ }
51+ Labels = new LabelData ( labelData ) ;
52+ }
53+
54+ /// <summary>
55+ /// Constructor (copy)
56+ /// </summary>
57+ public CvBlobs ( IEnumerable < KeyValuePair < int , CvBlob > > blobData , LabelData labelData )
58+ : this ( blobData , labelData . Values )
59+ {
60+ }
61+
4262 /// <summary>
4363 /// Constructor (init and cvLabel)
4464 /// </summary>
@@ -373,24 +393,26 @@ public void UpdateTracks(CvTracks tracks, double thDistance, int thInactive, int
373393 i ++ ;
374394 }
375395
376- int maxTrackID = 0 ;
396+ int maxTrackId = 0 ;
377397 int j = 0 ;
378398 foreach ( CvTrack track in tracks . Values )
379399 {
380400 close . AT [ j ] = 0 ;
381- close . AT [ j ] = track . Id ;
382- if ( track . Id > maxTrackID )
383- maxTrackID = track . Id ;
401+ close . IT [ j ] = track . Id ;
402+ if ( track . Id > maxTrackId )
403+ maxTrackId = track . Id ;
384404 j ++ ;
385405 }
386406
387- // Proximity matrix calculation and "used blob" list inicialization :
407+ // Proximity matrix calculation and "used blob" list initialization :
388408 for ( i = 0 ; i < nBlobs ; i ++ )
389409 {
390410 for ( j = 0 ; j < nTracks ; j ++ )
391411 {
392- CvBlob b = this [ close . IB [ i ] ] ;
393- CvTrack t = tracks [ close . IT [ j ] ] ;
412+ int ib = close . IB [ i ] ;
413+ int it = close . IT [ j ] ;
414+ CvBlob b = this [ ib ] ;
415+ CvTrack t = tracks [ it ] ;
394416 close [ i , j ] = ( DistantBlobTrack ( b , t ) < thDistance ) ? 1 : 0 ;
395417 if ( close [ i , j ] < thDistance )
396418 {
@@ -426,11 +448,12 @@ public void UpdateTracks(CvTracks tracks, double thDistance, int thInactive, int
426448 //cout << *B(i) << endl;
427449
428450 // New track.
429- maxTrackID ++ ;
430- CvBlob blob = this [ i + 1 ] ;
451+ maxTrackId ++ ;
452+ int ib = close . IB [ i ] ;
453+ CvBlob blob = this [ ib ] ;
431454 CvTrack track = new CvTrack
432455 {
433- Id = maxTrackID ,
456+ Id = maxTrackId ,
434457 Label = blob . Label ,
435458 MinX = blob . MinX ,
436459 MinY = blob . MinY ,
@@ -441,7 +464,8 @@ public void UpdateTracks(CvTracks tracks, double thDistance, int thInactive, int
441464 Active = 0 ,
442465 Inactive = 0 ,
443466 } ;
444- tracks [ maxTrackID ] = track ;
467+ tracks [ maxTrackId ] = track ;
468+ //maxTrackId++;
445469 }
446470 }
447471
@@ -451,8 +475,11 @@ public void UpdateTracks(CvTracks tracks, double thDistance, int thInactive, int
451475 int c = close . AT [ j ] ;
452476 if ( c != 0 )
453477 {
454- List < CvTrack > tt = new List < CvTrack > { tracks [ j ] } ;
455- List < CvBlob > bb = new List < CvBlob > ( ) ;
478+ var tt = new List < CvTrack > ( ) ;
479+ var bb = new List < CvBlob > ( ) ;
480+
481+ int it = close . IT [ j ] ;
482+ tt . Add ( tracks [ it ] ) ;
456483
457484 GetClusterForTrack ( j , close , nBlobs , nTracks , this , tracks , bb , tt ) ;
458485
@@ -482,7 +509,8 @@ public void UpdateTracks(CvTracks tracks, double thDistance, int thInactive, int
482509 }
483510
484511 if ( blob == null || track == null )
485- throw new NotSupportedException ( ) ;
512+ //throw new Exception();
513+ continue ;
486514
487515 // Update track
488516 track . Label = blob . Label ;
@@ -591,15 +619,57 @@ private double DistantBlobTrack(CvBlob b, CvTrack t)
591619 return Math . Min ( d1 , d2 ) ;
592620 }
593621
622+ private static void GetClusterForBlob ( int blobPos , ProximityMatrix close ,
623+ int nBlobs , int nTracks , CvBlobs blobs , CvTracks tracks ,
624+ List < CvBlob > bb , List < CvTrack > tt )
625+ {
626+ retry :
627+ var retryList = new List < int > ( ) ;
628+
629+ for ( int j = 0 ; j < nTracks ; j ++ )
630+ {
631+ if ( close [ blobPos , j ] != 0 )
632+ {
633+ int it = close . IT [ j ] ;
634+ tt . Add ( tracks [ it ] ) ;
635+
636+ int c = close . AT [ j ] ;
637+
638+ close [ blobPos , j ] = 0 ;
639+ close . AB [ blobPos ] -- ;
640+ close . AT [ j ] -- ;
641+
642+ if ( c > 1 )
643+ {
644+ retryList . Add ( j ) ;
645+ //GetClusterForTrack(j, close, nBlobs, nTracks, blobs, tracks, bb, tt);
646+ }
647+ }
648+ }
649+
650+ if ( retryList . Count > 0 )
651+ {
652+ foreach ( int j in retryList )
653+ {
654+ GetClusterForTrack ( j , close , nBlobs , nTracks , blobs , tracks , bb , tt ) ;
655+ }
656+ goto retry ;
657+ }
658+ }
659+
594660 private static void GetClusterForTrack ( int trackPos , ProximityMatrix close ,
595661 int nBlobs , int nTracks , CvBlobs blobs ,
596662 CvTracks tracks , List < CvBlob > bb , List < CvTrack > tt )
597663 {
664+ retry :
665+ var retryList = new List < int > ( ) ;
666+
598667 for ( int i = 0 ; i < nBlobs ; i ++ )
599668 {
600669 if ( close [ i , trackPos ] != 0 )
601670 {
602- bb . Add ( blobs [ i ] ) ;
671+ int ib = close . IB [ i ] ;
672+ bb . Add ( blobs [ ib ] ) ;
603673
604674 int c = close . AB [ i ] ;
605675
@@ -609,37 +679,48 @@ private static void GetClusterForTrack(int trackPos, ProximityMatrix close,
609679
610680 if ( c > 1 )
611681 {
612- GetClusterForBlob ( i , close , nBlobs , nTracks , blobs , tracks , bb , tt ) ;
682+ retryList . Add ( i ) ;
683+ //GetClusterForBlob(i, close, nBlobs, nTracks, blobs, tracks, bb, tt);
613684 }
614685 }
615686 }
616- }
617687
618- private static void GetClusterForBlob ( int blobPos , ProximityMatrix close ,
619- int nBlobs , int nTracks , CvBlobs blobs , CvTracks tracks ,
620- List < CvBlob > bb , List < CvTrack > tt )
621- {
622- for ( int j = 0 ; j < nTracks ; j ++ )
688+ if ( retryList . Count > 0 )
623689 {
624- if ( close [ blobPos , j ] != 0 )
690+ foreach ( int i in retryList )
625691 {
626- tt . Add ( tracks [ j ] ) ;
692+ GetClusterForBlob ( i , close , nBlobs , nTracks , blobs , tracks , bb , tt ) ;
693+ }
694+ goto retry ;
695+ }
696+ }
627697
628- int c = close . AT [ j ] ;
698+ #endregion
629699
630- close [ blobPos , j ] = 0 ;
631- close . AB [ blobPos ] -- ;
632- close . AT [ j ] -- ;
700+ #endregion
633701
634- if ( c > 1 )
635- {
636- GetClusterForTrack ( j , close , nBlobs , nTracks , blobs , tracks , bb , tt ) ;
637- }
638- }
702+ #region ICloneable
703+
704+ /// <summary>
705+ ///
706+ /// </summary>
707+ /// <returns></returns>
708+ public CvBlobs Clone ( )
709+ {
710+ var newBlobs = new CvBlobs ( ) ;
711+ foreach ( KeyValuePair < int , CvBlob > pair in this )
712+ {
713+ newBlobs . Add ( pair . Key , pair . Value ) ;
639714 }
715+ newBlobs . Labels = Labels . Clone ( ) ;
716+
717+ return newBlobs ;
640718 }
641719
642- #endregion
720+ object ICloneable . Clone ( )
721+ {
722+ return Clone ( ) ;
723+ }
643724
644725 #endregion
645726 }
0 commit comments