From fc496d52bf22a0bb257300d3c79be9cd80e722cb Mon Sep 17 00:00:00 2001
From: AlexeyAB <alexeyab84@gmail.com>
Date: Thu, 12 Apr 2018 19:32:57 +0000
Subject: [PATCH] Yolo can be used from Python 2.x using /darknet.py on Linux or darknet/x64/darknet.py on Windows

---
 src/network.c                        |   34 +++
 src/yolo.c                           |    4 
 src/box.h                            |   20 +
 build/darknet/x64/darknet_python.cmd |    8 
 src/utils.h                          |   16 +
 src/network.h                        |   13 +
 src/yolo_v2_class.cpp                |    2 
 darknet.py                           |  158 +++++++++++++++++
 src/cuda.h                           |   16 +
 src/box.c                            |    7 
 build/darknet/x64/darknet.py         |  158 +++++++++++++++++
 src/coco.c                           |    4 
 src/option_list.h                    |   21 ++
 src/demo.c                           |    2 
 src/option_list.c                    |   19 ++
 src/detector.c                       |   11 
 src/image.h                          |   10 
 17 files changed, 476 insertions(+), 27 deletions(-)

diff --git a/build/darknet/x64/darknet.py b/build/darknet/x64/darknet.py
new file mode 100644
index 0000000..cb72dca
--- /dev/null
+++ b/build/darknet/x64/darknet.py
@@ -0,0 +1,158 @@
+from ctypes import *
+import math
+import random
+
+def sample(probs):
+    s = sum(probs)
+    probs = [a/s for a in probs]
+    r = random.uniform(0, 1)
+    for i in range(len(probs)):
+        r = r - probs[i]
+        if r <= 0:
+            return i
+    return len(probs)-1
+
+def c_array(ctype, values):
+    arr = (ctype*len(values))()
+    arr[:] = values
+    return arr
+
+class BOX(Structure):
+    _fields_ = [("x", c_float),
+                ("y", c_float),
+                ("w", c_float),
+                ("h", c_float)]
+
+class DETECTION(Structure):
+    _fields_ = [("bbox", BOX),
+                ("classes", c_int),
+                ("prob", POINTER(c_float)),
+                ("mask", POINTER(c_float)),
+                ("objectness", c_float),
+                ("sort_class", c_int)]
+
+
+class IMAGE(Structure):
+    _fields_ = [("w", c_int),
+                ("h", c_int),
+                ("c", c_int),
+                ("data", POINTER(c_float))]
+
+class METADATA(Structure):
+    _fields_ = [("classes", c_int),
+                ("names", POINTER(c_char_p))]
+
+    
+
+#lib = CDLL("/home/pjreddie/documents/darknet/libdarknet.so", RTLD_GLOBAL)
+#lib = CDLL("darknet.so", RTLD_GLOBAL)
+lib = CDLL("yolo_cpp_dll.dll", RTLD_GLOBAL)
+lib.network_width.argtypes = [c_void_p]
+lib.network_width.restype = c_int
+lib.network_height.argtypes = [c_void_p]
+lib.network_height.restype = c_int
+
+predict = lib.network_predict
+predict.argtypes = [c_void_p, POINTER(c_float)]
+predict.restype = POINTER(c_float)
+
+set_gpu = lib.cuda_set_device
+set_gpu.argtypes = [c_int]
+
+make_image = lib.make_image
+make_image.argtypes = [c_int, c_int, c_int]
+make_image.restype = IMAGE
+
+get_network_boxes = lib.get_network_boxes
+get_network_boxes.argtypes = [c_void_p, c_int, c_int, c_float, c_float, POINTER(c_int), c_int, POINTER(c_int), c_int]
+get_network_boxes.restype = POINTER(DETECTION)
+
+make_network_boxes = lib.make_network_boxes
+make_network_boxes.argtypes = [c_void_p]
+make_network_boxes.restype = POINTER(DETECTION)
+
+free_detections = lib.free_detections
+free_detections.argtypes = [POINTER(DETECTION), c_int]
+
+free_ptrs = lib.free_ptrs
+free_ptrs.argtypes = [POINTER(c_void_p), c_int]
+
+network_predict = lib.network_predict
+network_predict.argtypes = [c_void_p, POINTER(c_float)]
+
+reset_rnn = lib.reset_rnn
+reset_rnn.argtypes = [c_void_p]
+
+load_net = lib.load_network
+load_net.argtypes = [c_char_p, c_char_p, c_int]
+load_net.restype = c_void_p
+
+do_nms_obj = lib.do_nms_obj
+do_nms_obj.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]
+
+do_nms_sort = lib.do_nms_sort
+do_nms_sort.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]
+
+free_image = lib.free_image
+free_image.argtypes = [IMAGE]
+
+letterbox_image = lib.letterbox_image
+letterbox_image.argtypes = [IMAGE, c_int, c_int]
+letterbox_image.restype = IMAGE
+
+load_meta = lib.get_metadata
+lib.get_metadata.argtypes = [c_char_p]
+lib.get_metadata.restype = METADATA
+
+load_image = lib.load_image_color
+load_image.argtypes = [c_char_p, c_int, c_int]
+load_image.restype = IMAGE
+
+rgbgr_image = lib.rgbgr_image
+rgbgr_image.argtypes = [IMAGE]
+
+predict_image = lib.network_predict_image
+predict_image.argtypes = [c_void_p, IMAGE]
+predict_image.restype = POINTER(c_float)
+
+def classify(net, meta, im):
+    out = predict_image(net, im)
+    res = []
+    for i in range(meta.classes):
+        res.append((meta.names[i], out[i]))
+    res = sorted(res, key=lambda x: -x[1])
+    return res
+
+def detect(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45):
+    im = load_image(image, 0, 0)
+    num = c_int(0)
+    pnum = pointer(num)
+    predict_image(net, im)
+    dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, None, 0, pnum, 1)
+    num = pnum[0]
+    #if (nms): do_nms_obj(dets, num, meta.classes, nms);
+    if (nms): do_nms_sort(dets, num, meta.classes, nms);
+    
+    res = []
+    for j in range(num):
+        for i in range(meta.classes):
+            if dets[j].prob[i] > 0:
+                b = dets[j].bbox
+                res.append((meta.names[i], dets[j].prob[i], (b.x, b.y, b.w, b.h)))
+    res = sorted(res, key=lambda x: -x[1])
+    free_image(im)
+    free_detections(dets, num)
+    return res
+    
+if __name__ == "__main__":
+    #net = load_net("cfg/densenet201.cfg", "/home/pjreddie/trained/densenet201.weights", 0)
+    #im = load_image("data/wolf.jpg", 0, 0)
+    #meta = load_meta("cfg/imagenet1k.data")
+    #r = classify(net, meta, im)
+    #print r[:10]
+    net = load_net("cfg/yolov3.cfg", "yolov3.weights", 0)
+    meta = load_meta("data/coco.data")
+    r = detect(net, meta, "data/dog.jpg", 0.25)
+    print r
+    
+
diff --git a/build/darknet/x64/darknet_python.cmd b/build/darknet/x64/darknet_python.cmd
new file mode 100644
index 0000000..79611b5
--- /dev/null
+++ b/build/darknet/x64/darknet_python.cmd
@@ -0,0 +1,8 @@
+rem download Python 2.7.14 from: https://www.python.org/downloads/release/python-2714/
+rem C:\Python27\Scripts\pip install numpy
+
+
+C:\Python27\python.exe darknet.py
+
+
+pause
\ No newline at end of file
diff --git a/darknet.py b/darknet.py
new file mode 100644
index 0000000..7d7dc69
--- /dev/null
+++ b/darknet.py
@@ -0,0 +1,158 @@
+from ctypes import *
+import math
+import random
+
+def sample(probs):
+    s = sum(probs)
+    probs = [a/s for a in probs]
+    r = random.uniform(0, 1)
+    for i in range(len(probs)):
+        r = r - probs[i]
+        if r <= 0:
+            return i
+    return len(probs)-1
+
+def c_array(ctype, values):
+    arr = (ctype*len(values))()
+    arr[:] = values
+    return arr
+
+class BOX(Structure):
+    _fields_ = [("x", c_float),
+                ("y", c_float),
+                ("w", c_float),
+                ("h", c_float)]
+
+class DETECTION(Structure):
+    _fields_ = [("bbox", BOX),
+                ("classes", c_int),
+                ("prob", POINTER(c_float)),
+                ("mask", POINTER(c_float)),
+                ("objectness", c_float),
+                ("sort_class", c_int)]
+
+
+class IMAGE(Structure):
+    _fields_ = [("w", c_int),
+                ("h", c_int),
+                ("c", c_int),
+                ("data", POINTER(c_float))]
+
+class METADATA(Structure):
+    _fields_ = [("classes", c_int),
+                ("names", POINTER(c_char_p))]
+
+    
+
+#lib = CDLL("/home/pjreddie/documents/darknet/libdarknet.so", RTLD_GLOBAL)
+lib = CDLL("darknet.so", RTLD_GLOBAL)
+#lib = CDLL("yolo_cpp_dll.dll", RTLD_GLOBAL)
+lib.network_width.argtypes = [c_void_p]
+lib.network_width.restype = c_int
+lib.network_height.argtypes = [c_void_p]
+lib.network_height.restype = c_int
+
+predict = lib.network_predict
+predict.argtypes = [c_void_p, POINTER(c_float)]
+predict.restype = POINTER(c_float)
+
+set_gpu = lib.cuda_set_device
+set_gpu.argtypes = [c_int]
+
+make_image = lib.make_image
+make_image.argtypes = [c_int, c_int, c_int]
+make_image.restype = IMAGE
+
+get_network_boxes = lib.get_network_boxes
+get_network_boxes.argtypes = [c_void_p, c_int, c_int, c_float, c_float, POINTER(c_int), c_int, POINTER(c_int), c_int]
+get_network_boxes.restype = POINTER(DETECTION)
+
+make_network_boxes = lib.make_network_boxes
+make_network_boxes.argtypes = [c_void_p]
+make_network_boxes.restype = POINTER(DETECTION)
+
+free_detections = lib.free_detections
+free_detections.argtypes = [POINTER(DETECTION), c_int]
+
+free_ptrs = lib.free_ptrs
+free_ptrs.argtypes = [POINTER(c_void_p), c_int]
+
+network_predict = lib.network_predict
+network_predict.argtypes = [c_void_p, POINTER(c_float)]
+
+reset_rnn = lib.reset_rnn
+reset_rnn.argtypes = [c_void_p]
+
+load_net = lib.load_network
+load_net.argtypes = [c_char_p, c_char_p, c_int]
+load_net.restype = c_void_p
+
+do_nms_obj = lib.do_nms_obj
+do_nms_obj.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]
+
+do_nms_sort = lib.do_nms_sort
+do_nms_sort.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]
+
+free_image = lib.free_image
+free_image.argtypes = [IMAGE]
+
+letterbox_image = lib.letterbox_image
+letterbox_image.argtypes = [IMAGE, c_int, c_int]
+letterbox_image.restype = IMAGE
+
+load_meta = lib.get_metadata
+lib.get_metadata.argtypes = [c_char_p]
+lib.get_metadata.restype = METADATA
+
+load_image = lib.load_image_color
+load_image.argtypes = [c_char_p, c_int, c_int]
+load_image.restype = IMAGE
+
+rgbgr_image = lib.rgbgr_image
+rgbgr_image.argtypes = [IMAGE]
+
+predict_image = lib.network_predict_image
+predict_image.argtypes = [c_void_p, IMAGE]
+predict_image.restype = POINTER(c_float)
+
+def classify(net, meta, im):
+    out = predict_image(net, im)
+    res = []
+    for i in range(meta.classes):
+        res.append((meta.names[i], out[i]))
+    res = sorted(res, key=lambda x: -x[1])
+    return res
+
+def detect(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45):
+    im = load_image(image, 0, 0)
+    num = c_int(0)
+    pnum = pointer(num)
+    predict_image(net, im)
+    dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, None, 0, pnum, 1)
+    num = pnum[0]
+    #if (nms): do_nms_obj(dets, num, meta.classes, nms);
+    if (nms): do_nms_sort(dets, num, meta.classes, nms);
+    
+    res = []
+    for j in range(num):
+        for i in range(meta.classes):
+            if dets[j].prob[i] > 0:
+                b = dets[j].bbox
+                res.append((meta.names[i], dets[j].prob[i], (b.x, b.y, b.w, b.h)))
+    res = sorted(res, key=lambda x: -x[1])
+    free_image(im)
+    free_detections(dets, num)
+    return res
+    
+if __name__ == "__main__":
+    #net = load_net("cfg/densenet201.cfg", "/home/pjreddie/trained/densenet201.weights", 0)
+    #im = load_image("data/wolf.jpg", 0, 0)
+    #meta = load_meta("cfg/imagenet1k.data")
+    #r = classify(net, meta, im)
+    #print r[:10]
+    net = load_net("cfg/yolov3.cfg", "yolov3.weights", 0)
+    meta = load_meta("data/coco.data")
+    r = detect(net, meta, "data/dog.jpg", 0.25)
+    print r
+    
+
diff --git a/src/box.c b/src/box.c
index e02685d..00e3edb 100644
--- a/src/box.c
+++ b/src/box.c
@@ -246,7 +246,7 @@
     return 0;
 }
 
-void do_nms_sort(box *boxes, float **probs, int total, int classes, float thresh)
+void do_nms_sort_v2(box *boxes, float **probs, int total, int classes, float thresh)
 {
     int i, j, k;
     sortable_bbox *s = calloc(total, sizeof(sortable_bbox));
@@ -292,8 +292,9 @@
 	return 0;
 }
 
-void do_nms_obj_v3(detection *dets, int total, int classes, float thresh)
+void do_nms_obj(detection *dets, int total, int classes, float thresh)
 {
+	printf(" total = %d, classes = %d, thresh = %f \n", total, classes, thresh);
 	int i, j, k;
 	k = total - 1;
 	for (i = 0; i <= k; ++i) {
@@ -328,7 +329,7 @@
 	}
 }
 
-void do_nms_sort_v3(detection *dets, int total, int classes, float thresh)
+void do_nms_sort(detection *dets, int total, int classes, float thresh)
 {
 	int i, j, k;
 	k = total - 1;
diff --git a/src/box.h b/src/box.h
index c023e20..31dd22c 100644
--- a/src/box.h
+++ b/src/box.h
@@ -1,6 +1,20 @@
 #ifndef BOX_H
 #define BOX_H
 
+#ifdef YOLODLL_EXPORTS
+#if defined(_MSC_VER)
+#define YOLODLL_API __declspec(dllexport) 
+#else
+#define YOLODLL_API __attribute__((visibility("default")))
+#endif
+#else
+#if defined(_MSC_VER)
+#define YOLODLL_API
+#else
+#define YOLODLL_API
+#endif
+#endif
+
 typedef struct{
     float x, y, w, h;
 } box;
@@ -23,9 +37,9 @@
 float box_rmse(box a, box b);
 dbox diou(box a, box b);
 void do_nms(box *boxes, float **probs, int total, int classes, float thresh);
-void do_nms_sort(box *boxes, float **probs, int total, int classes, float thresh);
-void do_nms_sort_v3(detection *dets, int total, int classes, float thresh);
-void do_nms_obj_v3(detection *dets, int total, int classes, float thresh);
+void do_nms_sort_v2(box *boxes, float **probs, int total, int classes, float thresh);
+YOLODLL_API void do_nms_sort(detection *dets, int total, int classes, float thresh);
+YOLODLL_API void do_nms_obj(detection *dets, int total, int classes, float thresh);
 box decode_box(box b, box anchor);
 box encode_box(box b, box anchor);
 
diff --git a/src/coco.c b/src/coco.c
index 814b34c..c95e30d 100644
--- a/src/coco.c
+++ b/src/coco.c
@@ -216,7 +216,7 @@
             int w = val[t].w;
             int h = val[t].h;
             get_detection_boxes(l, w, h, thresh, probs, boxes, 0);
-            if (nms) do_nms_sort(boxes, probs, side*side*l.n, classes, iou_thresh);
+            if (nms) do_nms_sort_v2(boxes, probs, side*side*l.n, classes, iou_thresh);
             print_cocos(fp, image_id, boxes, probs, side*side*l.n, classes, w, h);
             free_image(val[t]);
             free_image(val_resized[t]);
@@ -351,7 +351,7 @@
         network_predict(net, X);
         printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time));
         get_detection_boxes(l, 1, 1, thresh, probs, boxes, 0);
-        if (nms) do_nms_sort(boxes, probs, l.side*l.side*l.n, l.classes, nms);
+        if (nms) do_nms_sort_v2(boxes, probs, l.side*l.side*l.n, l.classes, nms);
         draw_detections(im, l.side*l.side*l.n, thresh, boxes, probs, coco_classes, alphabet, 80);
         save_image(im, "prediction");
         show_image(im, "predictions");
diff --git a/src/cuda.h b/src/cuda.h
index c328fce..9308031 100644
--- a/src/cuda.h
+++ b/src/cuda.h
@@ -5,6 +5,20 @@
 	#define inline __inline
 #endif
 
+#ifdef YOLODLL_EXPORTS
+#if defined(_MSC_VER)
+#define YOLODLL_API __declspec(dllexport) 
+#else
+#define YOLODLL_API __attribute__((visibility("default")))
+#endif
+#else
+#if defined(_MSC_VER)
+#define YOLODLL_API
+#else
+#define YOLODLL_API
+#endif
+#endif
+
 extern int gpu_index;
 
 #ifdef GPU
@@ -28,7 +42,7 @@
 	int *cuda_make_int_array(size_t n);
 	void cuda_push_array(float *x_gpu, float *x, size_t n);
 	void cuda_pull_array(float *x_gpu, float *x, size_t n);
-	void cuda_set_device(int n);
+	YOLODLL_API void cuda_set_device(int n);
 	int cuda_get_device();
 	void cuda_free(float *x_gpu);
 	void cuda_random(float *x_gpu, size_t n);
diff --git a/src/demo.c b/src/demo.c
index 027ca4d..65f451f 100644
--- a/src/demo.c
+++ b/src/demo.c
@@ -103,7 +103,7 @@
 	int letter = 0;
 	int nboxes = 0;
 	detection *dets = get_network_boxes(&net, det.w, det.h, demo_thresh, demo_thresh, 0, 1, &nboxes, letter);
-	if (nms) do_nms_obj_v3(dets, nboxes, l.classes, nms);
+	if (nms) do_nms_obj(dets, nboxes, l.classes, nms);
 
     printf("\033[2J");
     printf("\033[1;1H");
diff --git a/src/detector.c b/src/detector.c
index 06709c1..81cd616 100644
--- a/src/detector.c
+++ b/src/detector.c
@@ -385,7 +385,7 @@
 			int nboxes = 0;
 			int letterbox = (args.type == LETTERBOX_DATA);
 			detection *dets = get_network_boxes(&net, w, h, thresh, .5, map, 0, &nboxes, letterbox);
-			if (nms) do_nms_sort_v3(dets, nboxes, classes, nms);
+			if (nms) do_nms_sort(dets, nboxes, classes, nms);
 			if (coco) {
 				print_cocos(fp, path, dets, nboxes, classes, w, h);
 			}
@@ -453,7 +453,7 @@
 		int nboxes = 0;
 		int letterbox = 0;
 		detection *dets = get_network_boxes(&net, sized.w, sized.h, thresh, .5, 0, 1, &nboxes, letterbox);
-		if (nms) do_nms_obj_v3(dets, nboxes, 1, nms);
+		if (nms) do_nms_obj(dets, nboxes, 1, nms);
 
 		char labelpath[4096];
 		find_replace(path, "images", "labels", labelpath);
@@ -607,7 +607,7 @@
 			float hier_thresh = 0;
 			detection *dets = get_network_boxes(&net, 1, 1, thresh, hier_thresh, 0, 0, &nboxes, letterbox);
 			//detection *dets = get_network_boxes(&net, val[t].w, val[t].h, thresh, hier_thresh, 0, 1, &nboxes, letterbox); // for letterbox=1
-			if (nms) do_nms_sort_v3(dets, nboxes, l.classes, nms);
+			if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
 
 			char labelpath[4096];
 			find_replace(path, "images", "labels", labelpath);
@@ -1056,13 +1056,14 @@
         float *X = sized.data;
         time=clock();
         network_predict(net, X);
+		//network_predict_image(&net, im);
         printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time));
         //get_region_boxes(l, 1, 1, thresh, probs, boxes, 0, 0);
-		// if (nms) do_nms_sort(boxes, probs, l.w*l.h*l.n, l.classes, nms);
+		// if (nms) do_nms_sort_v2(boxes, probs, l.w*l.h*l.n, l.classes, nms);
 		//draw_detections(im, l.w*l.h*l.n, thresh, boxes, probs, names, alphabet, l.classes);
 		int nboxes = 0;
 		detection *dets = get_network_boxes(&net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes, letterbox);
-		if (nms) do_nms_sort_v3(dets, nboxes, l.classes, nms);
+		if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
 		draw_detections_v3(im, dets, nboxes, thresh, names, alphabet, l.classes);
 		free_detections(dets, nboxes);
         save_image(im, "predictions");
diff --git a/src/image.h b/src/image.h
index b88cb4b..7145997 100644
--- a/src/image.h
+++ b/src/image.h
@@ -33,7 +33,7 @@
 image resize_image(image im, int w, int h);
 void fill_image(image m, float s);
 void letterbox_image_into(image im, int w, int h, image boxed);
-image letterbox_image(image im, int w, int h);
+YOLODLL_API image letterbox_image(image im, int w, int h);
 image resize_min(image im, int min);
 image resize_max(image im, int max);
 void translate_image(image m, float s);
@@ -46,7 +46,7 @@
 void distort_image(image im, float hue, float sat, float val);
 void saturate_exposure_image(image im, float sat, float exposure);
 void hsv_to_rgb(image im);
-void rgbgr_image(image im);
+YOLODLL_API void rgbgr_image(image im);
 void constrain_image(image im);
 void composite_3d(char *f1, char *f2, char *out, int delta);
 int best_3d_shift_r(image a, image b, int min, int max);
@@ -68,13 +68,13 @@
 
 void print_image(image m);
 
-image make_image(int w, int h, int c);
+YOLODLL_API image make_image(int w, int h, int c);
 image make_random_image(int w, int h, int c);
 image make_empty_image(int w, int h, int c);
 image float_to_image(int w, int h, int c, float *data);
 image copy_image(image p);
 image load_image(char *filename, int w, int h, int c);
-image load_image_color(char *filename, int w, int h);
+YOLODLL_API image load_image_color(char *filename, int w, int h);
 image **load_alphabet();
 
 float get_pixel(image m, int x, int y, int c);
@@ -85,7 +85,7 @@
 
 image get_image_layer(image m, int l);
 
-void free_image(image m);
+YOLODLL_API void free_image(image m);
 void test_resize(char *filename);
 #endif
 
diff --git a/src/network.c b/src/network.c
index 8c713fb..03ad5eb 100644
--- a/src/network.c
+++ b/src/network.c
@@ -28,6 +28,19 @@
 #include "route_layer.h"
 #include "shortcut_layer.h"
 #include "yolo_layer.h"
+#include "parser.h"
+
+network *load_network(char *cfg, char *weights, int clear)
+{
+	printf(" Try to load cfg: %s, weights: %s, clear = %d \n", cfg, weights, clear);
+	network *net = calloc(1, sizeof(network));
+	*net = parse_network_cfg(cfg);
+	if (weights && weights[0] != 0) {
+		load_weights(net, weights);
+	}
+	if (clear) (*net->seen) = 0;
+	return net;
+}
 
 int get_current_batch(network net)
 {
@@ -46,6 +59,27 @@
     #endif
 }
 
+void reset_network_state(network *net, int b)
+{
+	int i;
+	for (i = 0; i < net->n; ++i) {
+#ifdef GPU
+		layer l = net->layers[i];
+		if (l.state_gpu) {
+			fill_ongpu(l.outputs, 0, l.state_gpu + l.outputs*b, 1);
+		}
+		if (l.h_gpu) {
+			fill_ongpu(l.outputs, 0, l.h_gpu + l.outputs*b, 1);
+		}
+#endif
+	}
+}
+
+void reset_rnn(network *net)
+{
+	reset_network_state(net, 0);
+}
+
 float get_current_rate(network net)
 {
     int batch_num = get_current_batch(net);
diff --git a/src/network.h b/src/network.h
index 965693a..b609546 100644
--- a/src/network.h
+++ b/src/network.h
@@ -113,7 +113,7 @@
 float train_network_datum(network net, float *x, float *y);
 
 matrix network_predict_data(network net, data test);
-float *network_predict(network net, float *input);
+YOLODLL_API float *network_predict(network net, float *input);
 float network_accuracy(network net, data d);
 float *network_accuracies(network net, data d, int n);
 float network_accuracy_multi(network net, data d, int n);
@@ -133,8 +133,15 @@
 void set_batch_network(network *net, int b);
 int get_network_input_size(network net);
 float get_network_cost(network net);
-detection *get_network_boxes(network *net, int w, int h, float thresh, float hier, int *map, int relative, int *num, int letter);
-void free_detections(detection *dets, int n);
+YOLODLL_API detection *get_network_boxes(network *net, int w, int h, float thresh, float hier, int *map, int relative, int *num, int letter);
+YOLODLL_API detection *make_network_boxes(network *net, float thresh, int *num);
+YOLODLL_API void free_detections(detection *dets, int n);
+YOLODLL_API void reset_rnn(network *net);
+YOLODLL_API network *load_network(char *cfg, char *weights, int clear);
+YOLODLL_API float *network_predict_image(network *net, image im);
+YOLODLL_API void train_detector(char *datacfg, char *cfgfile, char *weightfile, int *gpus, int ngpus, int clear, int dont_show);
+YOLODLL_API int network_width(network *net);
+YOLODLL_API int network_height(network *net);
 
 int get_network_nuisance(network net);
 int get_network_background(network net);
diff --git a/src/option_list.c b/src/option_list.c
index f935af3..9411be3 100644
--- a/src/option_list.c
+++ b/src/option_list.c
@@ -32,6 +32,25 @@
     return options;
 }
 
+metadata get_metadata(char *file)
+{
+	metadata m = { 0 };
+	list *options = read_data_cfg(file);
+
+	char *name_list = option_find_str(options, "names", 0);
+	if (!name_list) name_list = option_find_str(options, "labels", 0);
+	if (!name_list) {
+		fprintf(stderr, "No names or labels found\n");
+	}
+	else {
+		m.names = get_labels(name_list);
+	}
+	m.classes = option_find_int(options, "classes", 2);
+	free_list(options);
+	printf("Loaded - names_list: %s, classes = %d \n", name_list, m.classes);
+	return m;
+}
+
 int read_option(char *s, list *options)
 {
     size_t i;
diff --git a/src/option_list.h b/src/option_list.h
index 054b3fd..29ac943 100644
--- a/src/option_list.h
+++ b/src/option_list.h
@@ -2,6 +2,20 @@
 #define OPTION_LIST_H
 #include "list.h"
 
+#ifdef YOLODLL_EXPORTS
+#if defined(_MSC_VER)
+#define YOLODLL_API __declspec(dllexport) 
+#else
+#define YOLODLL_API __attribute__((visibility("default")))
+#endif
+#else
+#if defined(_MSC_VER)
+#define YOLODLL_API
+#else
+#define YOLODLL_API
+#endif
+#endif
+
 typedef struct{
     char *key;
     char *val;
@@ -20,4 +34,11 @@
 float option_find_float_quiet(list *l, char *key, float def);
 void option_unused(list *l);
 
+typedef struct {
+	int classes;
+	char **names;
+} metadata;
+
+YOLODLL_API metadata get_metadata(char *file);
+
 #endif
diff --git a/src/utils.h b/src/utils.h
index eab2622..d56931c 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -11,10 +11,24 @@
 #define SECRET_NUM -1234
 #define TWO_PI 6.2831853071795864769252866
 
+#ifdef YOLODLL_EXPORTS
+#if defined(_MSC_VER)
+#define YOLODLL_API __declspec(dllexport) 
+#else
+#define YOLODLL_API __attribute__((visibility("default")))
+#endif
+#else
+#if defined(_MSC_VER)
+#define YOLODLL_API
+#else
+#define YOLODLL_API
+#endif
+#endif
+
 int *read_map(char *filename);
 void shuffle(void *arr, size_t n, size_t size);
 void sorta_shuffle(void *arr, size_t n, size_t size, size_t sections);
-void free_ptrs(void **ptrs, int n);
+YOLODLL_API void free_ptrs(void **ptrs, int n);
 char *basecfg(char *cfgfile);
 int alphanum_to_int(char c);
 char int_to_alphanum(int i);
diff --git a/src/yolo.c b/src/yolo.c
index 4bbdf44..238454e 100644
--- a/src/yolo.c
+++ b/src/yolo.c
@@ -191,7 +191,7 @@
             int w = val[t].w;
             int h = val[t].h;
             get_detection_boxes(l, w, h, thresh, probs, boxes, 0);
-            if (nms) do_nms_sort(boxes, probs, l.side*l.side*l.n, classes, iou_thresh);
+            if (nms) do_nms_sort_v2(boxes, probs, l.side*l.side*l.n, classes, iou_thresh);
             print_yolo_detections(fps, id, boxes, probs, l.side*l.side*l.n, classes, w, h);
             free(id);
             free_image(val[t]);
@@ -322,7 +322,7 @@
         network_predict(net, X);
         printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time));
         get_detection_boxes(l, 1, 1, thresh, probs, boxes, 0);
-        if (nms) do_nms_sort(boxes, probs, l.side*l.side*l.n, l.classes, nms);
+        if (nms) do_nms_sort_v2(boxes, probs, l.side*l.side*l.n, l.classes, nms);
         //draw_detections(im, l.side*l.side*l.n, thresh, boxes, probs, voc_names, alphabet, 20);
         draw_detections(im, l.side*l.side*l.n, thresh, boxes, probs, voc_names, alphabet, 20);
         save_image(im, "predictions");
diff --git a/src/yolo_v2_class.cpp b/src/yolo_v2_class.cpp
index 6cc0252..03d581a 100644
--- a/src/yolo_v2_class.cpp
+++ b/src/yolo_v2_class.cpp
@@ -222,7 +222,7 @@
 	int letterbox = 0;
 	float hier_thresh = 0.5;
 	detection *dets = get_network_boxes(&net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes, letterbox);
-	if (nms) do_nms_sort_v3(dets, nboxes, l.classes, nms);
+	if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
 
 	std::vector<bbox_t> bbox_vec;
 

--
Gitblit v1.10.0