Skip to content

Commit a039e75

Browse files
authored
Merge pull request #14 from LdDl/examples
Examples
2 parents 5522102 + 7f94c3b commit a039e75

File tree

5 files changed

+365
-4
lines changed

5 files changed

+365
-4
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Building and running program:
5050
5151
* Navigate to [example] folder
5252
```shell
53-
cd $GOPATH/github.com/LdDl/go-darknet/example
53+
cd $GOPATH/github.com/LdDl/go-darknet/example/base_example
5454
```
5555
5656
* Download dataset (sample of image, coco.names, yolov4.cfg (or v3), yolov4.weights(or v3)).
@@ -145,5 +145,5 @@ go-darknet follows [Darknet]'s [license].
145145
[darknet.h]: https://github.com/AlexeyAB/darknet/blob/master/include/darknet.h
146146
[include/darknet.h]: https://github.com/AlexeyAB/darknet/blob/master/include/darknet.h
147147
[Makefile]: https://github.com/alexeyab/darknet/blob/master/Makefile
148-
[example]: /example
148+
[example]: /example/base_example
149149
[GoDoc]: https://godoc.org/github.com/LdDl/go-darknet

example/README.md renamed to example/base_example/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ This is an example Go application which uses go-darknet.
88
Navigate to example folder:
99

1010
```shell
11-
cd $GOPATH/github.com/LdDl/go-darknet/example
11+
cd $GOPATH/github.com/LdDl/go-darknet/example/base_example
1212
```
1313

1414
Download dataset (sample of image, coco.names, yolov3.cfg, yolov3.weights).
1515
```shell
16-
./download_data.sh
16+
./download_data_v3.sh
1717
```
1818
Note: you don't need *coco.data* file anymore, because script below does insert *coco.names* into 'names' filed in *yolov3.cfg* file (so AlexeyAB's fork can deal with it properly)
1919
So last rows in yolov3.cfg file will look like:
File renamed without changes.

example/rest_example/README.md

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
# Example Go application using go-darknet and REST
2+
3+
This is an example Go server application (in terms of REST) which uses go-darknet.
4+
5+
## Run
6+
7+
Navigate to example folder:
8+
9+
```shell
10+
cd $GOPATH/github.com/LdDl/go-darknet/example/rest_example
11+
```
12+
13+
Download dataset (sample of image, coco.names, yolov3.cfg, yolov3.weights).
14+
```shell
15+
./download_data_v3.sh
16+
```
17+
Note: you don't need *coco.data* file anymore, because script below does insert *coco.names* into 'names' filed in *yolov3.cfg* file (so AlexeyAB's fork can deal with it properly)
18+
So last rows in yolov3.cfg file will look like:
19+
```bash
20+
......
21+
[yolo]
22+
mask = 0,1,2
23+
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
24+
classes=80
25+
num=9
26+
jitter=.3
27+
ignore_thresh = .7
28+
truth_thresh = 1
29+
random=1
30+
names = coco.names # this is path to coco.names file
31+
```
32+
33+
Build and run program
34+
```
35+
go build main.go && ./main --configFile=yolov3.cfg --weightsFile=yolov3.weights --port 8090
36+
```
37+
38+
After server started check if REST-requests works. We provide cURL-based example
39+
```shell
40+
curl -F 'image=@sample.jpg' 'http://localhost:8090/detect_objects'
41+
```
42+
43+
Servers response should be something like this:
44+
```json
45+
{
46+
"net_time": "43.269289ms",
47+
"overall_time": "43.551604ms",
48+
"num_detections": 44,
49+
"detections": [
50+
{
51+
"class_id": 7,
52+
"class_name": "truck",
53+
"probability": 49.51231,
54+
"start_point": {
55+
"x": 0,
56+
"y": 136
57+
},
58+
"end_point": {
59+
"x": 85,
60+
"y": 311
61+
}
62+
},
63+
{
64+
"class_id": 2,
65+
"class_name": "car",
66+
"probability": 36.36933,
67+
"start_point": {
68+
"x": 95,
69+
"y": 152
70+
},
71+
"end_point": {
72+
"x": 186,
73+
"y": 283
74+
}
75+
},
76+
{
77+
"class_id": 7,
78+
"class_name": "truck",
79+
"probability": 48.417683,
80+
"start_point": {
81+
"x": 95,
82+
"y": 152
83+
},
84+
"end_point": {
85+
"x": 186,
86+
"y": 283
87+
}
88+
},
89+
{
90+
"class_id": 7,
91+
"class_name": "truck",
92+
"probability": 45.652023,
93+
"start_point": {
94+
"x": 694,
95+
"y": 178
96+
},
97+
"end_point": {
98+
"x": 798,
99+
"y": 310
100+
}
101+
},
102+
{
103+
"class_id": 2,
104+
"class_name": "car",
105+
"probability": 76.8402,
106+
"start_point": {
107+
"x": 1,
108+
"y": 145
109+
},
110+
"end_point": {
111+
"x": 84,
112+
"y": 324
113+
}
114+
},
115+
{
116+
"class_id": 7,
117+
"class_name": "truck",
118+
"probability": 25.592052,
119+
"start_point": {
120+
"x": 107,
121+
"y": 89
122+
},
123+
"end_point": {
124+
"x": 215,
125+
"y": 263
126+
}
127+
},
128+
{
129+
"class_id": 2,
130+
"class_name": "car",
131+
"probability": 99.87823,
132+
"start_point": {
133+
"x": 511,
134+
"y": 185
135+
},
136+
"end_point": {
137+
"x": 748,
138+
"y": 328
139+
}
140+
},
141+
{
142+
"class_id": 2,
143+
"class_name": "car",
144+
"probability": 99.819336,
145+
"start_point": {
146+
"x": 261,
147+
"y": 189
148+
},
149+
"end_point": {
150+
"x": 427,
151+
"y": 322
152+
}
153+
},
154+
{
155+
"class_id": 2,
156+
"class_name": "car",
157+
"probability": 99.64055,
158+
"start_point": {
159+
"x": 426,
160+
"y": 197
161+
},
162+
"end_point": {
163+
"x": 539,
164+
"y": 311
165+
}
166+
},
167+
{
168+
"class_id": 2,
169+
"class_name": "car",
170+
"probability": 74.56263,
171+
"start_point": {
172+
"x": 692,
173+
"y": 186
174+
},
175+
"end_point": {
176+
"x": 796,
177+
"y": 316
178+
}
179+
},
180+
{
181+
"class_id": 2,
182+
"class_name": "car",
183+
"probability": 72.79756,
184+
"start_point": {
185+
"x": 388,
186+
"y": 206
187+
},
188+
"end_point": {
189+
"x": 437,
190+
"y": 276
191+
}
192+
},
193+
{
194+
"class_id": 1,
195+
"class_name": "bicycle",
196+
"probability": 72.27595,
197+
"start_point": {
198+
"x": 178,
199+
"y": 270
200+
},
201+
"end_point": {
202+
"x": 268,
203+
"y": 406
204+
}
205+
},
206+
{
207+
"class_id": 0,
208+
"class_name": "person",
209+
"probability": 97.30075,
210+
"start_point": {
211+
"x": 143,
212+
"y": 135
213+
},
214+
"end_point": {
215+
"x": 268,
216+
"y": 343
217+
}
218+
}
219+
]
220+
}
221+
```

example/rest_example/main.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"flag"
7+
"fmt"
8+
"image"
9+
_ "image/jpeg"
10+
"io/ioutil"
11+
"log"
12+
"net/http"
13+
14+
"github.com/LdDl/go-darknet"
15+
)
16+
17+
var configFile = flag.String("configFile", "",
18+
"Path to network layer configuration file. Example: cfg/yolov3.cfg")
19+
var weightsFile = flag.String("weightsFile", "",
20+
"Path to weights file. Example: yolov3.weights")
21+
var serverPort = flag.Int("port", 8090,
22+
"Listening port")
23+
24+
func main() {
25+
flag.Parse()
26+
27+
if *configFile == "" || *weightsFile == "" {
28+
flag.Usage()
29+
return
30+
}
31+
32+
n := darknet.YOLONetwork{
33+
GPUDeviceIndex: 0,
34+
NetworkConfigurationFile: *configFile,
35+
WeightsFile: *weightsFile,
36+
Threshold: .25,
37+
}
38+
if err := n.Init(); err != nil {
39+
log.Println(err)
40+
return
41+
}
42+
defer n.Close()
43+
44+
http.HandleFunc("/detect_objects", detectObjects(&n))
45+
http.ListenAndServe(fmt.Sprintf(":%d", *serverPort), nil)
46+
}
47+
48+
// DarknetResp Response
49+
type DarknetResp struct {
50+
NetTime string `json:"net_time"`
51+
OverallTime string `json:"overall_time"`
52+
Detections []*DarknetDetection `json:"detections"`
53+
}
54+
55+
// DarknetDetection Information about single detection
56+
type DarknetDetection struct {
57+
ClassID int `json:"class_id"`
58+
ClassName string `json:"class_name"`
59+
Probability float32 `json:"probability"`
60+
StartPoint *DarknetPoint `json:"start_point"`
61+
EndPoint *DarknetPoint `json:"end_point"`
62+
}
63+
64+
// DarknetPoint image.Image point
65+
type DarknetPoint struct {
66+
X int `json:"x"`
67+
Y int `json:"y"`
68+
}
69+
70+
func detectObjects(n *darknet.YOLONetwork) func(w http.ResponseWriter, req *http.Request) {
71+
return func(w http.ResponseWriter, req *http.Request) {
72+
// Restrict file size up to 10mb
73+
req.ParseMultipartForm(10 << 20)
74+
75+
file, _, err := req.FormFile("image")
76+
if err != nil {
77+
fmt.Fprintf(w, fmt.Sprintf("Error reading FormFile: %s", err.Error()))
78+
return
79+
}
80+
defer file.Close()
81+
82+
fileBytes, err := ioutil.ReadAll(file)
83+
if err != nil {
84+
fmt.Fprintf(w, fmt.Sprintf("Error reading bytes: %s", err.Error()))
85+
return
86+
}
87+
88+
imgSrc, _, err := image.Decode(bytes.NewReader(fileBytes))
89+
if err != nil {
90+
fmt.Fprintf(w, fmt.Sprintf("Error decoding bytes to image: %s", err.Error()))
91+
return
92+
}
93+
94+
imgDarknet, err := darknet.Image2Float32(imgSrc)
95+
if err != nil {
96+
fmt.Fprintf(w, fmt.Sprintf("Error converting image.Image to darknet.DarknetImage: %s", err.Error()))
97+
return
98+
}
99+
defer imgDarknet.Close()
100+
101+
dr, err := n.Detect(imgDarknet)
102+
if err != nil {
103+
fmt.Fprintf(w, fmt.Sprintf("Error detecting objects: %s", err.Error()))
104+
return
105+
}
106+
107+
resp := DarknetResp{
108+
NetTime: fmt.Sprintf("%v", dr.NetworkOnlyTimeTaken),
109+
OverallTime: fmt.Sprintf("%v", dr.OverallTimeTaken),
110+
Detections: []*DarknetDetection{},
111+
}
112+
113+
for _, d := range dr.Detections {
114+
for i := range d.ClassIDs {
115+
bBox := d.BoundingBox
116+
resp.Detections = append(resp.Detections, &DarknetDetection{
117+
ClassID: d.ClassIDs[i],
118+
ClassName: d.ClassNames[i],
119+
Probability: d.Probabilities[i],
120+
StartPoint: &DarknetPoint{
121+
X: bBox.StartPoint.X,
122+
Y: bBox.StartPoint.Y,
123+
},
124+
EndPoint: &DarknetPoint{
125+
X: bBox.EndPoint.X,
126+
Y: bBox.EndPoint.Y,
127+
},
128+
})
129+
}
130+
}
131+
132+
respBytes, err := json.Marshal(resp)
133+
if err != nil {
134+
fmt.Fprintf(w, fmt.Sprintf("Error encoding response: %s", err.Error()))
135+
return
136+
}
137+
138+
fmt.Fprintf(w, string(respBytes))
139+
}
140+
}

0 commit comments

Comments
 (0)