-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmain.go
133 lines (111 loc) · 3.71 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package main
import (
"fmt"
"image"
"image/color"
"os"
"gocv.io/x/gocv"
)
// getOutputsNames : YOLO Layer
func getOutputsNames(net *gocv.Net) []string {
var outputLayers []string
for _, i := range net.GetUnconnectedOutLayers() {
layer := net.GetLayer(i)
layerName := layer.GetName()
if layerName != "_input" {
outputLayers = append(outputLayers, layerName)
}
}
return outputLayers
}
// PostProcess : All Detect Box
func PostProcess(frame gocv.Mat, outs *[]gocv.Mat) ([]image.Rectangle, []float32, []int) {
var classIds []int
var confidences []float32
var boxes []image.Rectangle
for _, out := range *outs {
data, _ := out.DataPtrFloat32()
for i := 0; i < out.Rows(); i, data = i+1, data[out.Cols():] {
scoresCol := out.RowRange(i, i+1)
scores := scoresCol.ColRange(5, out.Cols())
_, confidence, _, classIDPoint := gocv.MinMaxLoc(scores)
if confidence > 0.5 {
centerX := int(data[0] * float32(frame.Cols()))
centerY := int(data[1] * float32(frame.Rows()))
width := int(data[2] * float32(frame.Cols()))
height := int(data[3] * float32(frame.Rows()))
left := centerX - width/2
top := centerY - height/2
classIds = append(classIds, classIDPoint.X)
confidences = append(confidences, float32(confidence))
boxes = append(boxes, image.Rect(left, top, width, height))
}
}
}
return boxes, confidences, classIds
}
// ReadCOCO : Read coco.names
func ReadCOCO() []string {
var classes []string
read, _ := os.Open("./assets/coco.names")
defer read.Close()
for {
var t string
_, err := fmt.Fscan(read, &t)
if err != nil {
break
}
classes = append(classes, t)
}
return classes
}
// drawRect : Detect Class to Draw Rect
func drawRect(img gocv.Mat, boxes []image.Rectangle, classes []string, classIds []int, indices []int) (gocv.Mat, []string) {
var detectClass []string
for _, idx := range indices {
if idx == 0 {
continue
}
gocv.Rectangle(&img, image.Rect(boxes[idx].Max.X, boxes[idx].Max.Y, boxes[idx].Max.X+boxes[idx].Min.X, boxes[idx].Max.Y+boxes[idx].Min.Y), color.RGBA{255, 0, 0, 0}, 2)
gocv.PutText(&img, classes[classIds[idx]], image.Point{boxes[idx].Max.X, boxes[idx].Max.Y + 30}, gocv.FontHersheyPlain, 10, color.RGBA{0, 0, 255, 0}, 3)
detectClass = append(detectClass, classes[classIds[idx]])
}
return img, detectClass
}
// Detect : Run YOLOv4 Process
func Detect(net *gocv.Net, src gocv.Mat, scoreThreshold float32, nmsThreshold float32, OutputNames []string, classes []string) (gocv.Mat, []string) {
img := src.Clone()
img.ConvertTo(&img, gocv.MatTypeCV32F)
blob := gocv.BlobFromImage(img, 1/255.0, image.Pt(416, 416), gocv.NewScalar(0, 0, 0, 0), true, false)
net.SetInput(blob, "")
probs := net.ForwardLayers(OutputNames)
boxes, confidences, classIds := PostProcess(img, &probs)
indices := make([]int, 100)
if len(boxes) == 0 { // No Classes
return src, []string{}
}
gocv.NMSBoxes(boxes, confidences, scoreThreshold, nmsThreshold, indices)
return drawRect(src, boxes, classes, classIds, indices)
}
// Process : Read Picture and Process
func Process(filename string) {
// Init
classes := ReadCOCO()
net := gocv.ReadNet("./assets/yolov4.weights", "./assets/yolov4.cfg")
defer net.Close()
net.SetPreferableBackend(gocv.NetBackendType(gocv.NetBackendDefault))
net.SetPreferableTarget(gocv.NetTargetType(gocv.NetTargetCPU))
OutputNames := getOutputsNames(&net)
window := gocv.NewWindow("yolo")
img := gocv.IMRead(filename, gocv.IMReadColor)
defer img.Close()
detectImg, detectClass := Detect(&net, img.Clone(), 0.45, 0.5, OutputNames, classes)
defer detectImg.Close()
fmt.Printf("Dectect Class : %v\n", detectClass)
window.IMShow(detectImg)
gocv.IMWrite("result.jpg", detectImg)
gocv.WaitKey(0)
}
func main() {
Process(os.Args[1])
}