From 4c680b2b09cbc5cc228a58a2c3689df568619f5d Mon Sep 17 00:00:00 2001 From: Michael Pivato Date: Mon, 14 Jan 2019 12:25:26 +1030 Subject: [PATCH] Add code to for hand detection using CNN --- GestureRecognition/SimpleHandRecogniser.py | 79 +++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/GestureRecognition/SimpleHandRecogniser.py b/GestureRecognition/SimpleHandRecogniser.py index d81171a..3548a87 100644 --- a/GestureRecognition/SimpleHandRecogniser.py +++ b/GestureRecognition/SimpleHandRecogniser.py @@ -119,4 +119,81 @@ class SimpleHandRecogniser(HandRecogniser): prev_x = x prev_y = y - return num_change / 2 - 1 \ No newline at end of file + return num_change / 2 - 1 + + def detect_hand(self, weights_path, config_path, conf_thresh = 0.5, nms_thresh = 0.4): + ''' + Detects if there is a hand in the image. If there is (above a significant confidence threshold) + then the function will set the img property to the location of the hand according to its bounding box. + ''' + # Most of this code is from here: www.arunponnusamy.com/yolo-object-detection-opencv-python.html + # Also https://github.com/opencv/opencv/blob/3.4/samples/dnn/object_detection.py + if self.img is None: + return 0 + + height = self.img.shape[0] + width = self.img.shape[1] + scale = 0.5 + + classes = None # Stores classes used for classification + + net = cv2.dnn.readNet(weights_path, config_path) + + net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV) + + outNames = net.getUnconnectedOutLayersNames() + + blob = cv2.dnn.blobFromImage(self.img, scale, (416,416), (0,0,0), True, False) + + net.setInput(blob) + + outs = net.forward(outNames) + + # Getting the output layer. + layerNames = net.getLayerNames() + lastLayerId = net.getLayerId(layerNames[-1]) + lastLayer = net.getLayer(lastLayerId) + + classIds = [] + confidences = [] + boxes = [] + if lastLayer.type == 'DetectionOutput': + # Check we are using an actual detection module. + # Will return a 1x1xnx7 blob, where n is number of detections. + # Tuple for each detection: [batchId, classId, confidence, left, top, right, bottom] + + for out in outs: + for detection in out[0,0]: + confidence = detection[2] + if confidence > conf_thresh: + # WIll need to verify this first, but given code said this is needed. + left = int(detection[3] * width) + top = int(detection[4] * height) + right = int(detection[5] * width) + bottom = int(detection[6] * height) + classIds.append(int(detection[1]) - 1) + confidences.append(float(confidence)) + boxes.append((left, top, right, bottom)) + + + # Remove duplicate/overlapping boxes -> makes sure only detect one hand in an area. + indices = cv2.dnn.NMSBoxes(boxes, confidences, conf_thresh, nms_thresh) + + for i in indices: + i = i[0] + box = boxes[i] + left = box[0] + top = box[1] + right = box[2] + bottom = box[3] + # Now draw the box if we want to. + + # OR can just get the box that is a hand with the maximum confidence/maximum box area -> this implies closest hand... + max_conf = 0 + max_index = 0 + for conf in confidences: + if conf > max_conf: + max_conf = conf + max_index = i + +