From a055821b732f748524680d08ffbcef5cbef25713 Mon Sep 17 00:00:00 2001
From: Edmond Yoo <hj3yoo@uwaterloo.ca>
Date: Mon, 17 Sep 2018 06:43:16 +0000
Subject: [PATCH] Fine-tuning opencv
---
darknet.py | 143 +++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 129 insertions(+), 14 deletions(-)
diff --git a/darknet.py b/darknet.py
index 2f77bad..f00356d 100644
--- a/darknet.py
+++ b/darknet.py
@@ -31,6 +31,8 @@
import math
import random
import os
+import cv2
+import numpy as np
def sample(probs):
s = sum(probs)
@@ -78,13 +80,14 @@
#lib = CDLL("darknet.so", RTLD_GLOBAL)
hasGPU = True
if os.name == "nt":
- winGPUdll = "yolo_cpp_dll.dll"
- winNoGPUdll = "yolo_cpp_dll_nogpu.dll"
+ cwd = os.path.dirname(__file__)
+ os.environ['PATH'] = cwd + ';' + os.environ['PATH']
+ winGPUdll = os.path.join(cwd, "yolo_cpp_dll.dll")
+ winNoGPUdll = os.path.join(cwd, "yolo_cpp_dll_nogpu.dll")
envKeys = list()
for k, v in os.environ.items():
envKeys.append(k)
try:
- tmp = os.environ["CUDA_HOME"]
try:
tmp = os.environ["FORCE_CPU"].lower()
if tmp in ["1", "true", "yes", "on"]:
@@ -97,28 +100,28 @@
if int(os.environ['CUDA_VISIBLE_DEVICES']) < 0:
raise ValueError("ForceCPU")
try:
- # Check a global
global DARKNET_FORCE_CPU
if DARKNET_FORCE_CPU:
raise ValueError("ForceCPU")
except NameError:
pass
- print(os.environ.keys())
- print("FORCE_CPU flag undefined, proceeding with GPU")
+ # print(os.environ.keys())
+ # print("FORCE_CPU flag undefined, proceeding with GPU")
if not os.path.exists(winGPUdll):
raise ValueError("NoDLL")
lib = CDLL(winGPUdll, RTLD_GLOBAL)
except (KeyError, ValueError):
- print("Notice: GPU-free mode")
hasGPU = False
if os.path.exists(winNoGPUdll):
lib = CDLL(winNoGPUdll, RTLD_GLOBAL)
+ print("Notice: CPU-only mode")
else:
# Try the other way, in case no_gpu was
# compile but not renamed
lib = CDLL(winGPUdll, RTLD_GLOBAL)
+ print("Environment variables indicated a CPU run, but we didn't find `"+winNoGPUdll+"`. Trying a GPU run anyway.")
else:
- lib = CDLL("./libdarknet.so", RTLD_GLOBAL)
+ lib = CDLL("./darknet.so", RTLD_GLOBAL)
lib.network_width.argtypes = [c_void_p]
lib.network_width.restype = c_int
lib.network_height.argtypes = [c_void_p]
@@ -160,6 +163,10 @@
load_net.argtypes = [c_char_p, c_char_p, c_int]
load_net.restype = c_void_p
+load_net_custom = lib.load_network_custom
+load_net_custom.argtypes = [c_char_p, c_char_p, c_int, c_int]
+load_net_custom.restype = c_void_p
+
do_nms_obj = lib.do_nms_obj
do_nms_obj.argtypes = [POINTER(DETECTION), c_int, c_int, c_float]
@@ -188,6 +195,18 @@
predict_image.argtypes = [c_void_p, IMAGE]
predict_image.restype = POINTER(c_float)
+def array_to_image(arr):
+ import numpy as np
+ # need to return old values to avoid python freeing memory
+ arr = arr.transpose(2,0,1)
+ c = arr.shape[0]
+ h = arr.shape[1]
+ w = arr.shape[2]
+ arr = np.ascontiguousarray(arr.flat, dtype=np.float32) / 255.0
+ data = arr.ctypes.data_as(POINTER(c_float))
+ im = IMAGE(w,h,c,data)
+ return im, arr
+
def classify(net, meta, im):
out = predict_image(net, im)
res = []
@@ -205,7 +224,17 @@
Performs the meat of the detection
"""
#pylint: disable= C0321
- im = load_image(image, 0, 0)
+ if isinstance(image, np.ndarray):
+ im = array_to_image(image)[0]
+ else:
+ im = load_image(image, 0, 0)
+ #import cv2
+ #custom_image_bgr = cv2.imread(image) # use: detect(,,imagePath,)
+ #custom_image = cv2.cvtColor(custom_image_bgr, cv2.COLOR_BGR2RGB)
+ #custom_image = cv2.resize(custom_image,(lib.network_width(net), lib.network_height(net)), interpolation = cv2.INTER_LINEAR)
+ #import scipy.misc
+ #custom_image = scipy.misc.imread(image)
+ #im, arr = array_to_image(custom_image) # you should comment line below: free_image(im)
if debug: print("Loaded image")
num = c_int(0)
if debug: print("Assigned num")
@@ -213,7 +242,8 @@
if debug: print("Assigned pnum")
predict_image(net, im)
if debug: print("did prediction")
- dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, None, 0, pnum, 1)
+ #dets = get_network_boxes(net, custom_image_bgr.shape[1], custom_image_bgr.shape[0], thresh, hier_thresh, None, 0, pnum, 0) # OpenCV
+ dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, None, 0, pnum, 0)
if debug: print("Got dets")
num = pnum[0]
if debug: print("got zeroth index of pnum")
@@ -253,7 +283,7 @@
metaMain = None
altNames = None
-def performDetect(imagePath="data/dog.jpg", thresh= 0.25, configPath = "./yolov3.cfg", weightPath = "yolov3.weights", metaPath= "./data/coco.data", showImage= True, makeImageOnly = False, initOnly= False):
+def performDetect(imagePath="data/dog.jpg", thresh= 0.25, configPath = "./cfg/yolov3.cfg", weightPath = "yolov3.weights", metaPath= "./data/coco.data", showImage= True, makeImageOnly = False, initOnly= False):
"""
Convenience function to handle the detection and returns of objects.
@@ -310,7 +340,7 @@
if not os.path.exists(metaPath):
raise ValueError("Invalid data file path `"+os.path.abspath(metaPath)+"`")
if netMain is None:
- netMain = load_net(configPath.encode("ascii"), weightPath.encode("ascii"), 0)
+ netMain = load_net_custom(configPath.encode("ascii"), weightPath.encode("ascii"), 0, 1) # batch size = 1
if metaMain is None:
metaMain = load_meta(metaPath.encode("ascii"))
if altNames is None:
@@ -340,7 +370,9 @@
if not os.path.exists(imagePath):
raise ValueError("Invalid image path `"+os.path.abspath(imagePath)+"`")
# Do the detection
- detections = detect(netMain, metaMain, imagePath.encode("ascii"), thresh)
+ #detections = detect(netMain, metaMain, imagePath, thresh) # if is used cv2.imread(image)
+ #detections = detect(netMain, metaMain, imagePath.encode("ascii"), thresh)
+ detections = detect(netMain, metaMain, cv2.imread(imagePath), thresh, debug=True)
if showImage:
try:
from skimage import io, draw
@@ -395,5 +427,88 @@
print("Unable to show image: "+str(e))
return detections
+
+def capture(thresh=.25, hier_thresh=.5, nms=.45, configPath="./cfg/yolov3.cfg", weightPath="yolov3.weights",
+ metaPath="./data/coco.data", showImage=True, makeImageOnly=False, initOnly=False):
+ global metaMain, netMain, altNames # pylint: disable=W0603
+ netMain = load_net_custom(configPath.encode("ascii"), weightPath.encode("ascii"), 0, 1) # batch size = 1
+ metaMain = load_meta(metaPath.encode("ascii"))
+
+ num = c_int(0)
+ pnum = pointer(num)
+ num = pnum[0]
+
+ capture = cv2.VideoCapture('../data/test1.mp4')
+ print(capture.get(cv2.CAP_PROP_FPS))
+
+ capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1024)
+ capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 768)
+
+ while True:
+ ret, frame = capture.read()
+ detections = detect(netMain, metaMain, frame, thresh, debug=True)
+ '''
+ im, arr = array_to_image(frame)
+ predict_image(netMain, im)
+ dets = get_network_boxes(netMain, im.w, im.h, thresh, hier_thresh, None, 0, pnum, 1)
+ if nms:
+ do_nms_sort(dets, num, metaMain.classes, nms)
+ res = []
+ for j in range(num):
+ for i in range(metaMain.classes):
+ if dets[j].prob[i] > 0:
+ b = dets[j].bbox
+ nameTag = metaMain.names[i]
+ res.append((nameTag, dets[j].prob[i], (b.x, b.y, b.w, b.h)))
+ '''
+ for detection in detections:
+ label = detection[0]
+ confidence = detection[1]
+ pstring = label + ": " + str(np.rint(100 * confidence)) + "%"
+ imcaption.append(pstring)
+ print(pstring)
+ bounds = detection[2]
+ shape = image.shape
+ # x = shape[1]
+ # xExtent = int(x * bounds[2] / 100)
+ # y = shape[0]
+ # yExtent = int(y * bounds[3] / 100)
+ yExtent = int(bounds[3])
+ xEntent = int(bounds[2])
+ # Coordinates are around the center
+ xCoord = int(bounds[0] - bounds[2] / 2)
+ yCoord = int(bounds[1] - bounds[3] / 2)
+ boundingBox = [
+ [xCoord, yCoord],
+ [xCoord, yCoord + yExtent],
+ [xCoord + xEntent, yCoord + yExtent],
+ [xCoord + xEntent, yCoord]
+ ]
+ # Wiggle it around to make a 3px border
+ rr, cc = draw.polygon_perimeter([x[1] for x in boundingBox], [x[0] for x in boundingBox], shape=shape)
+ rr2, cc2 = draw.polygon_perimeter([x[1] + 1 for x in boundingBox], [x[0] for x in boundingBox], shape=shape)
+ rr3, cc3 = draw.polygon_perimeter([x[1] - 1 for x in boundingBox], [x[0] for x in boundingBox], shape=shape)
+ rr4, cc4 = draw.polygon_perimeter([x[1] for x in boundingBox], [x[0] + 1 for x in boundingBox], shape=shape)
+ rr5, cc5 = draw.polygon_perimeter([x[1] for x in boundingBox], [x[0] - 1 for x in boundingBox], shape=shape)
+ boxColor = (int(255 * (1 - (confidence ** 2))), int(255 * (confidence ** 2)), 0)
+ draw.set_color(image, (rr, cc), boxColor, alpha=0.8)
+ draw.set_color(image, (rr2, cc2), boxColor, alpha=0.8)
+ draw.set_color(image, (rr3, cc3), boxColor, alpha=0.8)
+ draw.set_color(image, (rr4, cc4), boxColor, alpha=0.8)
+ draw.set_color(image, (rr5, cc5), boxColor, alpha=0.8)
+ print(res)
+ cv2.imshow('frame', frame)
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+
+ capture.release()
+ cv2.destroyAllWindows()
+
+
if __name__ == "__main__":
- print(performDetect())
+ performDetect(imagePath='data/scream.jpg')
+ #performDetect(imagePath="../data/test1.jpg", thresh=0.25, configPath="./cfg/tiny_yolo.cfg",
+ # weightPath="./weights/second_general/tiny_yolo_17000.weights",
+ # metaPath="./data/obj.data", showImage=True, makeImageOnly=False, initOnly=False)
+ #print(performDetect(showImage=False))
+ #capture()
--
Gitblit v1.10.0