Skip to content

Commit 000f806

Browse files
committed
NMSBoxes fix & webcam example
1 parent a15edc0 commit 000f806

File tree

9 files changed

+146
-13
lines changed

9 files changed

+146
-13
lines changed

Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ lint:
1515

1616
# Runs the examples
1717
bird-example:
18-
cd cmd/example && go run .
18+
@cd cmd/image && go run .
1919

2020
street-example:
21-
cd cmd/example && go run . -i ../../data/example_images/street.jpg
21+
@cd cmd/image && go run . -i ../../data/example_images/street.jpg
22+
23+
webcam-example:
24+
@cd cmd/webcam && go run .
25+
26+
cuda-example:
27+
@cd cmd/cuda && go run .

README.md

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
# Go YOLO V3
22

3-
This repository provides an implementation of the [Yolo V3](https://pjreddie.com/darknet/yolo/) object detection system in Go leveraging [gocv](https://github.com/hybridgroup/gocv).
3+
This repository provides a plug and play implementation of the [Yolo V3](https://pjreddie.com/darknet/yolo/) object detection system in Go, leveraging [gocv](https://github.com/hybridgroup/gocv).
44

5-
# Before you begin
5+
# Prerequisites
66

77
Since this implementation builds on top of the [gocv](https://github.com/hybridgroup/gocv) library, make sure you either use one of the provided [docker images](https://github.com/hybridgroup/gocv/blob/release/Dockerfile) to run the example, or install the opencv dependencies on your system.
88

9-
Furthermore, make sure you've got the yolov3 models downloaded before running the examples. Simply run `$ make models`
9+
Furthermore, make sure you've got the yolov3 models downloaded before running the examples.
1010

11-
# Run the example
11+
Simply run `$ make models`
1212

13-
Execute the bird example:
13+
# Run the examples
14+
15+
## Bird example
1416

1517
`$ make bird-example`
1618

@@ -19,7 +21,7 @@ Output
1921
<img src="data/example_outputs/birds-output.png"
2022
alt="birds output"/>
2123

22-
Execute the street example:
24+
## Street example
2325

2426
`$ make street-example`
2527

@@ -28,10 +30,33 @@ Output
2830
<img src="data/example_outputs/street-output.png"
2931
alt="street output"/>
3032

33+
## Webcam example
34+
35+
`$ make webcam-example`
36+
37+
Note that this will not run smoothly on most machines, as the default net target type is set to `NetTargetCPU`. If you have cuda installed, adjust the net initialization to:
38+
```GOLANG
39+
conf := yolov3.DefaultConfig()
40+
// Adjust the backend and target type
41+
conf.NetBackendType = gocv.NetBackendCUDA
42+
conf.NetTargetType = gocv.NetTargetCUDA
43+
44+
// Create the net with created config
45+
yolonet, err := yolov3.NewNetWithConfig(vehicleWeights, vehicleNetcfg, cocoNames, conf)
46+
if err != nil {
47+
log.WithError(err).Fatal("unable to create yolo net")
48+
}
49+
```
50+
51+
## Cuda example
52+
Execute 50 fps test render with cuda, also see the [CUDA](#CUDA) section.
53+
54+
`$ make cuda-example`
55+
3156
# CUDA
3257

33-
If you're interested in running yolo in Go with CUDA support, check the `cmd/example_cuda` to see a dummy example and test results of running object detection at 50 fps.
58+
If you're interested in running yolo in Go with CUDA support, check the `cmd/example_cuda` to see a dummy example and test results of running object detection at 50 fps. The [gocv cuda README](https://github.com/hybridgroup/gocv/blob/release/cuda/README.md) provides detailed installation instructions.
3459

3560
# Issues
3661

37-
If you have any issues, feel free to open a PR or create an issue!
62+
If you have any issues, feel free to open a PR or create an issue!

cmd/example_cuda/README.md renamed to cmd/cuda/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ For CUDA installation instruction, see the gocv [CUDA README](https://github.com
88

99
Software
1010
- Ubuntu 20.04 (64-bit)
11-
- Nvidea-smi 460.32.03
11+
- Nvidia-smi 460.32.03
1212
- CUDA version 11.2
1313
- OpenCV 4.5.1
1414

@@ -26,4 +26,4 @@ Hardware
2626

2727
<img src="nvidia-smi.png"
2828
alt="GPU Usage"
29-
style="float: left; margin-right: 10px;" />
29+
style="float: left; margin-right: 10px;" />
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

cmd/webcam/main.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"image"
6+
"image/color"
7+
8+
log "github.com/sirupsen/logrus"
9+
"github.com/wimspaargaren/yolov3"
10+
"gocv.io/x/gocv"
11+
)
12+
13+
const (
14+
vehicleWeights = "../../data/yolov3/yolov3.weights"
15+
vehicleNetcfg = "../../data/yolov3/yolov3.cfg"
16+
cocoNames = "../../data/yolov3/coco.names"
17+
)
18+
19+
func main() {
20+
yolonet, err := yolov3.NewNet(vehicleWeights, vehicleNetcfg, cocoNames)
21+
if err != nil {
22+
log.WithError(err).Fatal("unable to create yolo net")
23+
}
24+
25+
// Gracefully close the net when the program is done
26+
defer func() {
27+
err := yolonet.Close()
28+
if err != nil {
29+
log.WithError(err).Error("unable to gracefully close yolo net")
30+
}
31+
}()
32+
33+
videoCapture, err := gocv.OpenVideoCapture(0)
34+
if err != nil {
35+
log.WithError(err).Fatal("unable to start video capture")
36+
}
37+
38+
window := gocv.NewWindow("Result Window")
39+
defer func() {
40+
err := window.Close()
41+
if err != nil {
42+
log.WithError(err).Error("unable to close window")
43+
}
44+
}()
45+
46+
frame := gocv.NewMat()
47+
defer func() {
48+
err := frame.Close()
49+
if err != nil {
50+
log.WithError(err).Errorf("unable to close image")
51+
}
52+
}()
53+
54+
for {
55+
if ok := videoCapture.Read(&frame); !ok {
56+
log.Error("unable to read videostram")
57+
}
58+
if frame.Empty() {
59+
continue
60+
}
61+
detections, err := yolonet.GetDetections(frame)
62+
if err != nil {
63+
log.WithError(err).Fatal("unable to retrieve predictions")
64+
}
65+
66+
drawDetections(&frame, detections)
67+
68+
window.IMShow(frame)
69+
window.WaitKey(1)
70+
}
71+
}
72+
73+
func drawDetections(frame *gocv.Mat, detections []yolov3.ObjectDetection) {
74+
for i := 0; i < len(detections); i++ {
75+
detection := detections[i]
76+
text := fmt.Sprintf("%s:%.2f", detection.ClassName, detection.Confidence)
77+
78+
// Create bounding box of object
79+
blue := color.RGBA{0, 0, 255, 0}
80+
gocv.Rectangle(frame, detection.BoundingBox, blue, 3)
81+
82+
// Add text background
83+
black := color.RGBA{0, 0, 0, 0}
84+
size := gocv.GetTextSize(text, gocv.FontHersheySimplex, 0.5, 1)
85+
r := detection.BoundingBox
86+
textBackground := image.Rect(r.Min.X, r.Min.Y-size.Y-1, r.Min.X+size.X, r.Min.Y)
87+
gocv.Rectangle(frame, textBackground, black, int(gocv.Filled))
88+
89+
// Add text
90+
pt := image.Pt(r.Min.X, r.Min.Y-4)
91+
white := color.RGBA{255, 255, 255, 0}
92+
gocv.PutText(frame, text, pt, gocv.FontHersheySimplex, 0.5, white, 1)
93+
}
94+
}

yolov3.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,19 @@ func (y *yoloNet) processOutputs(frame gocv.Mat, outputs []gocv.Mat) ([]ObjectDe
164164
}
165165
}
166166
}
167+
if len(bboxes) == 0 {
168+
return detections, nil
169+
}
167170
indices := make([]int, len(bboxes))
168171

169172
gocv.NMSBoxes(bboxes, confidences, y.confidenceThreshold, y.nmsThreshold, indices)
170173
result := []ObjectDetection{}
171-
for _, indice := range indices {
174+
for i, indice := range indices {
175+
// If we encounter value 0 skip the detection
176+
// except for the first indice
177+
if i != 0 && indice == 0 {
178+
continue
179+
}
172180
result = append(result, detections[indice])
173181
}
174182
return result, nil

0 commit comments

Comments
 (0)