diff --git a/build/darknet/x64/darknet.py b/build/darknet/x64/darknet.py index da66e9c7..ee561dac 100644 --- a/build/darknet/x64/darknet.py +++ b/build/darknet/x64/darknet.py @@ -63,6 +63,9 @@ class DETECTION(Structure): ("uc", POINTER(c_float)), ("points", c_int)] +class DETNUMPAIR(Structure): + _fields_ = [("num", c_int), + ("dets", POINTER(DETECTION))] class IMAGE(Structure): _fields_ = [("w", c_int), @@ -161,6 +164,9 @@ make_network_boxes.restype = POINTER(DETECTION) free_detections = lib.free_detections free_detections.argtypes = [POINTER(DETECTION), c_int] +free_batch_detections = lib.free_batch_detections +free_batch_detections.argtypes = [POINTER(DETNUMPAIR), c_int] + free_ptrs = lib.free_ptrs free_ptrs.argtypes = [POINTER(c_void_p), c_int] @@ -210,6 +216,11 @@ predict_image_letterbox = lib.network_predict_image_letterbox predict_image_letterbox.argtypes = [c_void_p, IMAGE] predict_image_letterbox.restype = POINTER(c_float) +network_predict_batch = lib.network_predict_batch +network_predict_batch.argtypes = [c_void_p, IMAGE, c_int, c_int, c_int, + c_float, c_float, POINTER(c_int), c_int, c_int] +network_predict_batch.restype = POINTER(DETNUMPAIR) + def array_to_image(arr): import numpy as np # need to return old values to avoid python freeing memory @@ -445,5 +456,72 @@ def performDetect(imagePath="data/dog.jpg", thresh= 0.25, configPath = "./cfg/yo print("Unable to show image: "+str(e)) return detections +def performBatchDetect(thresh= 0.25, configPath = "./cfg/yolov3.cfg", weightPath = "yolov3.weights", metaPath= "./cfg/coco.data", hier_thresh=.5, nms=.45, batch_size=3): + import cv2 + import numpy as np + # NB! Image sizes should be the same + # You can change the images, yet, be sure that they have the same width and height + img_samples = ['data/person.jpg', 'data/person.jpg', 'data/person.jpg'] + image_list = [cv2.imread(k) for k in img_samples] + + net = load_net_custom(configPath.encode('utf-8'), weightPath.encode('utf-8'), 0, batch_size) + meta = load_meta(metaPath.encode('utf-8')) + pred_height, pred_width, c = image_list[0].shape + net_width, net_height = (network_width(net), network_height(net)) + img_list = [] + for custom_image_bgr in image_list: + custom_image = cv2.cvtColor(custom_image_bgr, cv2.COLOR_BGR2RGB) + custom_image = cv2.resize( + custom_image, (net_width, net_height), interpolation=cv2.INTER_NEAREST) + custom_image = custom_image.transpose(2, 0, 1) + img_list.append(custom_image) + + arr = np.concatenate(img_list, axis=0) + arr = np.ascontiguousarray(arr.flat, dtype=np.float32) / 255.0 + data = arr.ctypes.data_as(POINTER(c_float)) + im = IMAGE(net_width, net_height, c, data) + + batch_dets = network_predict_batch(net, im, batch_size, pred_width, + pred_height, thresh, hier_thresh, None, 0, 0) + batch_boxes = [] + batch_scores = [] + batch_classes = [] + for b in range(batch_size): + num = batch_dets[b].num + dets = batch_dets[b].dets + if nms: + do_nms_obj(dets, num, meta.classes, nms) + boxes = [] + scores = [] + classes = [] + for i in range(num): + det = dets[i] + score = -1 + label = None + for c in range(det.classes): + p = det.prob[c] + if p > score: + score = p + label = c + if score > thresh: + box = det.bbox + left, top, right, bottom = map(int,(box.x - box.w / 2, box.y - box.h / 2, + box.x + box.w / 2, box.y + box.h / 2)) + boxes.append((top, left, bottom, right)) + scores.append(score) + classes.append(label) + boxColor = (int(255 * (1 - (score ** 2))), int(255 * (score ** 2)), 0) + cv2.rectangle(image_list[b], (left, top), + (right, bottom), boxColor, 2) + cv2.imwrite(os.path.basename(img_samples[b]),image_list[b]) + + batch_boxes.append(boxes) + batch_scores.append(scores) + batch_classes.append(classes) + free_batch_detections(batch_dets, batch_size) + return batch_boxes, batch_scores, batch_classes + if __name__ == "__main__": print(performDetect()) + #Uncomment the following line to see batch inference working + #print(performBatchDetect()) \ No newline at end of file diff --git a/darknet.py b/darknet.py index 51876f6d..ee561dac 100644 --- a/darknet.py +++ b/darknet.py @@ -522,6 +522,6 @@ def performBatchDetect(thresh= 0.25, configPath = "./cfg/yolov3.cfg", weightPath return batch_boxes, batch_scores, batch_classes if __name__ == "__main__": - #print(performDetect()) + print(performDetect()) #Uncomment the following line to see batch inference working - print(performBatchDetect()) \ No newline at end of file + #print(performBatchDetect()) \ No newline at end of file diff --git a/include/darknet.h b/include/darknet.h index cbae6bc4..ac83788a 100644 --- a/include/darknet.h +++ b/include/darknet.h @@ -831,10 +831,10 @@ typedef struct detection{ } detection; // network.c -batch inference -typedef struct detNumPair { +typedef struct det_num_pair { int num; detection *dets; -} detNumPair, *pdetNumPair; +} det_num_pair, *pdet_num_pair; // matrix.h typedef struct matrix { @@ -945,7 +945,9 @@ LIB_API void diounms_sort(detection *dets, int total, int classes, float thresh, LIB_API float *network_predict(network net, float *input); LIB_API float *network_predict_ptr(network *net, float *input); LIB_API detection *get_network_boxes(network *net, int w, int h, float thresh, float hier, int *map, int relative, int *num, int letter); +LIB_API det_num_pair* network_predict_batch(network *net, image im, int batch_size, int w, int h, float thresh, float hier, int *map, int relative, int letter); LIB_API void free_detections(detection *dets, int n); +LIB_API void free_batch_detections(det_num_pair *det_num_pairs, int n); LIB_API void fuse_conv_batchnorm(network net); LIB_API void calculate_binary_weights(network net); LIB_API char *detection_to_json(detection *dets, int nboxes, int classes, char **names, long long int frame_id, char *filename); diff --git a/results/tmp.txt b/results/tmp.txt new file mode 100644 index 00000000..e69de29b diff --git a/src/demo.c b/src/demo.c index 7bca349d..6bd00303 100644 --- a/src/demo.c +++ b/src/demo.c @@ -322,12 +322,12 @@ void demo(char *cfgfile, char *weightfile, float thresh, float hier_thresh, int } while (custom_atomic_load_int(&run_detect_in_thread)) { - if(avg_fps > 200) this_thread_yield(); + if(avg_fps > 180) this_thread_yield(); else this_thread_sleep_for(thread_wait_ms); // custom_join(detect_thread, 0); } if (!benchmark) { while (custom_atomic_load_int(&run_fetch_in_thread)) { - if (avg_fps > 200) this_thread_yield(); + if (avg_fps > 180) this_thread_yield(); else this_thread_sleep_for(thread_wait_ms); // custom_join(fetch_thread, 0); } free_image(det_s); diff --git a/src/network.c b/src/network.c index 8a791f0e..31574f90 100644 --- a/src/network.c +++ b/src/network.c @@ -895,12 +895,12 @@ void free_detections(detection *dets, int n) free(dets); } -void free_batch_detections(detNumPair *detNumPairs, int n) +void free_batch_detections(det_num_pair *det_num_pairs, int n) { int i; for(i=0; i