Skip to content

Commit f3ba887

Browse files
authored
Merge pull request #1 from LdDl/v2
V2
2 parents fa23b83 + d004827 commit f3ba887

File tree

10 files changed

+1235
-4
lines changed

10 files changed

+1235
-4
lines changed

README.md

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Blob tracking via GoCV package
44
## Table of Contents
55

66
- [About](#about)
7-
- [Installation](#usage)
7+
- [Installation](#installation)
88
- [Usage](#usage)
99
- [Support](#support)
1010
- [Thanks](#thanks)
@@ -17,15 +17,41 @@ This small package implements basics of blob tracking (see ref. https://github.c
1717
First of all you need OpenCV to be installed on your operation system. Also you need [GoCV](https://github.com/hybridgroup/gocv) package to be installed too. Please see ref. here https://github.com/hybridgroup/gocv#how-to-install
1818

1919
Then you are good to go with:
20-
```go
21-
go get github.com/LdDl/gocv-blob
20+
```shell
21+
go get github.com/LdDl/gocv-blob/v2
22+
## or (if you want to use legacy version):
23+
## go get github.com/LdDl/gocv-blob
2224
```
2325

2426
p.s. do not be worried when you see *can't load package: package github.com/LdDl/gocv-blob: no Go files....* - this is just warning.
2527

2628
## Usage
2729

28-
It's pretty straightforward (pseudocode'ish)
30+
It's pretty straightforward (pseudocode'ish).
31+
32+
```go
33+
// 1. Define global set of blobs
34+
global_blobs = blob.NewBlobiesDefaults()
35+
36+
// 2. Define new blob objects
37+
new_blob1 = blob.NewSimpleBlobie(image.Rectangle, how many points to store in track, class ID of object , class name of object)
38+
new_blob2 = blob.NewSimpleBlobie(image.Rectangle, how many points to store in track, class ID of object , class name of object)
39+
40+
// 3. Append data to temporary set of blobs
41+
tmp_blobs = []*blob.Blobie{new_blob1, new_blob2}
42+
43+
// 4. Compare blobs ()
44+
global_blobs.MatchToExisting(tmp_blobs)
45+
46+
// 5. Repeat steps 2-4 every time when you find new objects on images. MatchToExisting() will update existing blobs and register new ones.
47+
```
48+
49+
More informative example is here: [v2/array_tracker_test.go](v2/array_tracker_test.go)
50+
51+
**FOR LEGACY v1**:
52+
<details>
53+
<summary>Click to expand</summary>
54+
2955
```go
3056
// 1. Define global set of blobs
3157
global_blobs = blob.NewBlobiesDefaults()
@@ -44,6 +70,7 @@ global_blobs.MatchToExisting(tmp_blobs)
4470

4571
// 5. Repeat steps 2-4 every time when you find new objects on images. MatchToExisting() will update existing blobs and register new ones.
4672
```
73+
</details>
4774

4875
## Support
4976

v2/array_tracker.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package blob
2+
3+
import (
4+
"math"
5+
6+
uuid "github.com/satori/go.uuid"
7+
)
8+
9+
// Blobies - Array of blobs
10+
type Blobies struct {
11+
Objects map[uuid.UUID]Blobie
12+
maxNoMatch int
13+
minThresholdDistance float64
14+
maxPointsInTrack int
15+
16+
DrawingOptions *DrawOptions
17+
}
18+
19+
// NewBlobiesDefaults - Constructor for Blobies (default values)
20+
//
21+
// Default values are:
22+
// maxNoMatch = 5
23+
// minThresholdDistance = 15
24+
// maxPointsInTrack = 10
25+
//
26+
func NewBlobiesDefaults() *Blobies {
27+
return &Blobies{
28+
Objects: make(map[uuid.UUID]Blobie),
29+
maxNoMatch: 5,
30+
minThresholdDistance: 15,
31+
maxPointsInTrack: 10,
32+
DrawingOptions: NewDrawOptionsDefault(),
33+
}
34+
}
35+
36+
// MatchToExisting Check if some of blobs already exists
37+
func (bt *Blobies) MatchToExisting(blobies []Blobie) {
38+
bt.prepare()
39+
for i := range blobies {
40+
minUUID := uuid.UUID{}
41+
minDistance := math.MaxFloat64
42+
for j := range (*bt).Objects {
43+
dist := distanceBetweenPoints(blobies[i].GetCenter(), (*bt).Objects[j].GetCenter())
44+
distPredicted := distanceBetweenPoints(blobies[i].GetCenter(), (*bt).Objects[j].GetPredictedNextPosition())
45+
dist = minf64(dist, distPredicted)
46+
if dist < minDistance {
47+
minDistance = dist
48+
minUUID = j
49+
}
50+
}
51+
if minDistance < blobies[i].GetDiagonal()*0.5 || minDistance < bt.minThresholdDistance {
52+
bt.Objects[minUUID].Update(blobies[i])
53+
} else {
54+
bt.Register(blobies[i])
55+
}
56+
}
57+
bt.RefreshNoMatch()
58+
}
59+
60+
// RefreshNoMatch - Refresh state of each blob
61+
func (bt *Blobies) RefreshNoMatch() {
62+
for i, b := range (*bt).Objects {
63+
if b.Exists() == false {
64+
b.IncrementNoMatchTimes()
65+
}
66+
if b.NoMatchTimes() >= 5 {
67+
b.SetTracking(false)
68+
bt.deregister(i)
69+
}
70+
}
71+
}
72+
73+
func (bt *Blobies) prepare() {
74+
for i := range bt.Objects {
75+
bt.Objects[i].SetExists(false)
76+
bt.Objects[i].PredictNextPosition(bt.maxNoMatch)
77+
}
78+
}
79+
80+
// Register - Register new blob
81+
func (bt *Blobies) Register(b Blobie) error {
82+
newUUID := uuid.NewV4()
83+
b.SetID(newUUID)
84+
bt.Objects[newUUID] = b
85+
return nil
86+
}
87+
88+
// deregister - deregister blob with provided uuid
89+
func (bt *Blobies) deregister(guid uuid.UUID) {
90+
delete(bt.Objects, guid)
91+
}

0 commit comments

Comments
 (0)