Add code to for hand detection using CNN

This commit is contained in:
Michael Pivato
2019-01-14 12:25:26 +10:30
parent 85548b7cdd
commit 4c680b2b09

View File

@@ -119,4 +119,81 @@ class SimpleHandRecogniser(HandRecogniser):
prev_x = x prev_x = x
prev_y = y prev_y = y
return num_change / 2 - 1 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