forked from madhawav/YOLO3-4-Py
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pydarknet.pyx
102 lines (79 loc) · 3.26 KB
/
pydarknet.pyx
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
# distutils: language = "c++"
import numpy as np
from libc.string cimport memcpy
from libc.stdlib cimport malloc
is_compiled_with_opencv = bool(USE_CV)
cdef class Image:
cdef image img;
def __cinit__(self, np.ndarray ary):
IF USE_CV == 1:
# Code adapted from https://github.com/solivr/cython_opencvMat
assert ary.ndim==3 and ary.shape[2]==3, "ASSERT::3channel RGB only!!"
cdef np.ndarray[np.uint8_t, ndim=3, mode ='c'] np_buff = np.ascontiguousarray(ary, dtype=np.uint8)
cdef unsigned int* im_buff = <unsigned int*> np_buff.data
cdef int r = ary.shape[0]
cdef int c = ary.shape[1]
cdef Mat m
m.create(r, c, CV_8UC3)
memcpy(m.data, im_buff, r*c*3)
# End of adapted code block
self.img = get_darknet_image(m)
m.release()
ELSE:
# Code adapted from https://github.com/solivr/cython_opencvMat
assert ary.ndim==3 and ary.shape[2]==3, "ASSERT::3channel RGB only!!"
# Re-arrange to suite Darknet input format
ary = ary.transpose(2, 0, 1)
# RGB to BGR
ary = ary[::-1,:,:]
# 0..1 Range
ary = ary/255.0
# To c_array
cdef np.ndarray[np.float32_t, ndim=3, mode ='c'] np_buff = np.ascontiguousarray(ary, dtype=np.float32)
cdef int c = ary.shape[0]
cdef int h = ary.shape[1]
cdef int w = ary.shape[2]
# Copy to Darknet image
self.img.w = w
self.img.h = h
self.img.c = c
self.img.data = <float*>malloc(h*w*c*4)
memcpy(self.img.data, np_buff.data, h*w*c*4)
def show_image(self, char* title):
show_image(self.img, title)
def __dealloc__(self):
free_image(self.img)
cdef class Detector:
cdef network* net
cdef metadata meta
def __cinit__(self, char* config, char* weights, int p, char* meta):
self.net = load_network(config, weights, p)
self.meta = get_metadata(meta)
# Code adapted from https://github.com/pjreddie/darknet/blob/master/python/darknet.py
def classify(self, Image img):
out = network_predict_image(self.net, img.img)
res = []
for i in range(self.meta.classes):
res.append((self.meta.names[i], out[i]))
res = sorted(res, key=lambda x: -x[1])
return res
def detect(self, Image image, float thresh=.5, float hier_thresh=.5, float nms=.45):
cdef int num = 0
cdef int* pnum = &num
network_predict_image(self.net, image.img)
dets = get_network_boxes(self.net, image.img.w, image.img.h, thresh, hier_thresh, <int*>0, 0, pnum)
num = pnum[0]
if (nms > 0):
do_nms_obj(dets, num, self.meta.classes, nms)
res = []
for j in range(num):
for i in range(self.meta.classes):
if dets[j].prob[i] > 0:
b = dets[j].bbox
res.append((self.meta.names[i], dets[j].prob[i], (b.x, b.y, b.w, b.h)))
res = sorted(res, key=lambda x: -x[1])
free_detections(dets, num)
return res
# End of adapted code block
def __dealloc__(self):
free_network(self.net)