Add code to for hand detection using CNN
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user