├── Blink Detection ├── README.md └── Real Time Blink detection.py ├── Delaunay Triangulation and Voronoi Diagram └── README.md ├── Detecting and Extracting Facial Regions ├── Facial Landmarking seperately.py ├── Facial Region Extractor.py └── README.md ├── Eye-tracking keyboard └── README.md ├── Facial Landmarking ├── Face Landmarking.py └── README.md ├── Finger-Segmentation ├── Hand Segmentation and Finger Detection.ipynb └── README.md └── README.md /Blink Detection/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Demo 👀 : 3 | 4 | ![Demo](https://github.com/Prathyusha-Guduru/Data/blob/master/Blink%20Detection.gif) 5 | -------------------------------------------------------------------------------- /Blink Detection/Real Time Blink detection.py: -------------------------------------------------------------------------------- 1 | # Importing necessary libraries 2 | 3 | 4 | from scipy.spatial import distance 5 | import cv2 6 | import numpy as np 7 | import dlib 8 | 9 | # Creating face detection and landmark predictor objects using dlib 10 | face_detect = dlib.get_frontal_face_detector() 11 | landmark_predict = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat') 12 | 13 | 14 | # Returning a tuple for bounding box 15 | def rect_to_bb(face_rect): 16 | x = face_rect.left() 17 | y = face_rect.top() 18 | w = face_rect.right() - x 19 | h = face_rect.bottom() - y 20 | return (x, y, w, h) 21 | 22 | def get_right_eye(landmarks, dtype = "int"): 23 | 24 | cords = np.zeros((6,2),dtype = dtype) 25 | for i in range(36,42): 26 | cords[i-36] = (landmarks.part(i).x , landmarks.part(i).y) 27 | return cords 28 | 29 | 30 | def get_left_eye(landmarks, dtype = "int"): 31 | 32 | cords = np.zeros((6,2),dtype = dtype) 33 | for i in range(42,48): 34 | cords[i-42] = (landmarks.part(i).x , landmarks.part(i).y) 35 | return cords 36 | 37 | def calc_ear(eye): 38 | a = distance.euclidean(eye[1],eye[5]) 39 | b = distance.euclidean(eye[2],eye[4]) 40 | 41 | c = distance.euclidean(eye[0],eye[3]) 42 | 43 | ear = (a+b)/(2.0*c) 44 | 45 | return ear 46 | 47 | 48 | # Creating a video capture object 49 | cap = cv2.VideoCapture(0) 50 | 51 | 52 | EAR_Tresh = 0.25 53 | 54 | 55 | EYE_Consec_frames = 4 56 | counter = 0 57 | total = 0 58 | 59 | while True: 60 | # Reading from the webcam 61 | ret, frame = cap.read() 62 | 63 | 64 | if ret == True: 65 | # Flipping the camera view horizontally to avoid mirror view 66 | frame = cv2.flip(frame, 1) 67 | # Converting the color image to grayscale for faster computation 68 | gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 69 | frame_copy = frame.copy() 70 | # Detecting the faces on the grayscale image and getting the co-ordinates 71 | faces = face_detect(gray) 72 | for (i, face) in enumerate(faces): 73 | # Getting landmark co-ordinates over the detected faces 74 | landmarks = landmark_predict(gray, face) 75 | right_eye = get_right_eye(landmarks) 76 | left_eye = get_left_eye(landmarks) 77 | 78 | for(x,y) in right_eye: 79 | cv2.circle(frame, (x, y), 2, (0,0,255), -1) 80 | hull = cv2.convexHull(right_eye) 81 | cv2.drawContours(frame, [hull], -1, (255,255,255), 1) 82 | for(x,y) in left_eye: 83 | cv2.circle(frame, (x, y), 2, (0,0,255), -1) 84 | hull = cv2.convexHull(left_eye) 85 | cv2.drawContours(frame, [hull], -1, (255,255,255), 1) 86 | right_ear = calc_ear(right_eye) 87 | left_ear = calc_ear(left_eye) 88 | ear =(right_ear + left_ear) / 2.0 89 | 90 | 91 | if ear < EAR_Tresh: 92 | counter+=1 93 | 94 | else: 95 | if counter >= EYE_Consec_frames: 96 | total +=1 97 | counter = 0 98 | cv2.putText(frame, "Blinks: {}".format(total), (10, 30), 99 | cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,255), 2) 100 | cv2.putText(frame, "EAR: {:.2f}".format(ear), (300, 30), 101 | cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) 102 | 103 | 104 | 105 | 106 | cv2.imshow('Face-Landmarking', frame) 107 | 108 | k = cv2.waitKey(1) & 0xff 109 | # Pressing escape to end the program 110 | if k == 27: 111 | break 112 | cap.release() 113 | cv2.destroyAllWindows() 114 | -------------------------------------------------------------------------------- /Delaunay Triangulation and Voronoi Diagram/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Detecting and Extracting Facial Regions/Facial Landmarking seperately.py: -------------------------------------------------------------------------------- 1 | 2 | import cv2 3 | import numpy as np 4 | from collections import OrderedDict 5 | import dlib 6 | 7 | 8 | 9 | face_landmark = OrderedDict([ 10 | ("mouth", (48, 68)), 11 | ("right_eyebrow", (17, 22)), 12 | ("left_eyebrow", (22, 27)), 13 | ("right_eye", (36, 42)), 14 | ("left_eye", (42, 48)), 15 | ("nose", (27, 35)), 16 | ("jaw", (0, 17)) 17 | ]) 18 | 19 | 20 | def to_np_arr(landmarks, dtype="int"): 21 | 22 | coords = np.zeros((68, 2), dtype=dtype) 23 | 24 | for i in range(0, 68): 25 | 26 | coords[i] = (landmarks.part(i).x, landmarks.part(i).y) 27 | 28 | return coords 29 | 30 | def rect_to_bb(face_rect): 31 | x = face_rect.left() 32 | y = face_rect.top() 33 | w = face_rect.right() - x 34 | h = face_rect.bottom() - y 35 | return (x,y,w,h) 36 | 37 | 38 | def get_facial_regions(frame, landmarks, colors=None, alpha=0.75): 39 | global face_landmark 40 | overlay = frame.copy() 41 | output = frame.copy() 42 | 43 | if colors is None: 44 | colors = [(19, 199, 109), (79, 76, 240), (230, 159, 23), 45 | (168, 100, 168), (158, 163, 32), 46 | (163, 38, 32), (180, 42, 220)] 47 | for (i, name) in enumerate(face_landmark.keys()): 48 | (j,k) = face_landmark[name] 49 | pts = landmarks[j:k] 50 | 51 | if name == 'jaw' : 52 | for l in range(1,len(pts)): 53 | pt_prev = tuple(pts[l-1]) 54 | pt_next = tuple(pts[l]) 55 | cv2.line(overlay,pt_prev,pt_next,colors[i],2) 56 | else: 57 | hull = cv2.convexHull(pts) 58 | cv2.drawContours(overlay,[hull],-1,colors[i],-1) 59 | cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0, output) 60 | return output 61 | 62 | image = cv2.imread('Hans-solo.jpg') 63 | gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) 64 | image_copy = image.copy() 65 | 66 | 67 | 68 | face_detect = dlib.get_frontal_face_detector() 69 | landmark_predict = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat') 70 | # image = cv2.cvtColor(image, cv2.COLOR_) 71 | 72 | faces = face_detect(gray) 73 | for (i, face) in enumerate(faces): 74 | (x, y, w, h) = rect_to_bb(face) 75 | cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2) 76 | cv2.putText(image, "Face #{}".format(i + 1), (x - 10, y - 10), cv2.FONT_HERSHEY_PLAIN, 0.5, (0, 255, 0), 2) 77 | landmarks = landmark_predict(gray, face) 78 | landmarks = to_np_arr(landmarks) 79 | for (X, Y) in landmarks: 80 | cv2.circle(image, (X, Y), 2, (255, 255, 255), -1) 81 | 82 | while True: 83 | cv2.namedWindow('Frame', cv2.WINDOW_NORMAL) 84 | cv2.resizeWindow('Frame', 500,500) 85 | cv2.namedWindow('Regions', cv2.WINDOW_NORMAL) 86 | cv2.resizeWindow('Regions', 500, 500) 87 | cv2.imshow('Frame',image) 88 | cv2.imshow('Regions',get_facial_regions(image_copy,landmarks)) 89 | 90 | k = cv2.waitKey(1) & 0xff 91 | if k == 27: 92 | break 93 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /Detecting and Extracting Facial Regions/Facial Region Extractor.py: -------------------------------------------------------------------------------- 1 | 2 | import cv2 3 | import numpy as np 4 | from collections import OrderedDict 5 | import dlib 6 | 7 | 8 | 9 | face_landmark = OrderedDict([ 10 | ("mouth", (48, 68)), 11 | ("right_eyebrow", (17, 22)), 12 | ("left_eyebrow", (22, 27)), 13 | ("right_eye", (36, 42)), 14 | ("left_eye", (42, 48)), 15 | ("nose", (27, 36)), 16 | ("jaw", (0, 17)) 17 | ]) 18 | 19 | 20 | def to_np_arr(landmarks, dtype="int"): 21 | 22 | coords = np.zeros((68, 2), dtype=dtype) 23 | 24 | for i in range(0, 68): 25 | 26 | coords[i] = (landmarks.part(i).x, landmarks.part(i).y) 27 | 28 | return coords 29 | 30 | def rect_to_bb(face_rect): 31 | x = face_rect.left() 32 | y = face_rect.top() 33 | w = face_rect.right() - x 34 | h = face_rect.bottom() - y 35 | return (x,y,w,h) 36 | 37 | 38 | def get_facial_regions(frame, landmarks, colors=None, alpha=0.75): 39 | global face_landmark 40 | overlay = frame.copy() 41 | output = frame.copy() 42 | 43 | if colors is None: 44 | colors = [(19, 199, 109), (79, 76, 240), (230, 159, 23), 45 | (168, 100, 168), (158, 163, 32), 46 | (163, 38, 32), (180, 42, 220)] 47 | for (i, name) in enumerate(face_landmark.keys()): 48 | (j,k) = face_landmark[name] 49 | pts = landmarks[j:k] 50 | 51 | if name == 'jaw' : 52 | for l in range(1,len(pts)): 53 | pt_prev = tuple(pts[l-1]) 54 | pt_next = tuple(pts[l]) 55 | cv2.line(overlay,pt_prev,pt_next,colors[i],2) 56 | else: 57 | hull = cv2.convexHull(pts) 58 | cv2.drawContours(overlay,[hull],-1,colors[i],-1) 59 | cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0, output) 60 | return output 61 | 62 | image = cv2.imread('Hans-solo.jpg') 63 | gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) 64 | image_copy = image.copy() 65 | 66 | 67 | 68 | face_detect = dlib.get_frontal_face_detector() 69 | landmark_predict = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat') 70 | # image = cv2.cvtColor(image, cv2.COLOR_) 71 | 72 | faces = face_detect(gray) 73 | for (i, face) in enumerate(faces): 74 | 75 | landmarks = landmark_predict(gray, face) 76 | landmarks = to_np_arr(landmarks) 77 | 78 | 79 | for (name, (i,j)) in face_landmark.items(): 80 | copy = image.copy() 81 | cv2.putText(copy, name,(10,30),cv2.FONT_HERSHEY_SIMPLEX,0.7,(0,255,0),2) 82 | 83 | for(x,y) in landmarks[i:j]: 84 | cv2.circle(copy, (x, y), 1, (0, 0, 255), -1) 85 | (x,y,w,h) = cv2.boundingRect(np.array([landmarks[i:j]])) 86 | roi = image[y:y+h, x:x+w] 87 | cv2.namedWindow('ROI', cv2.WINDOW_NORMAL) 88 | cv2.resizeWindow('ROI', 250,100) 89 | cv2.imshow('ROI', roi) 90 | 91 | 92 | cv2.imshow('Image',copy) 93 | cv2.waitKey(0) 94 | 95 | Result = get_facial_regions(image, landmarks) 96 | cv2.imshow('Facial Regions', Result) 97 | cv2.waitKey(0) 98 | 99 | 100 | -------------------------------------------------------------------------------- /Detecting and Extracting Facial Regions/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ![Demonstratiion](https://github.com/Prathyusha-Guduru/Data/blob/master/Facial%20Region%20Extractor.gif) 5 | -------------------------------------------------------------------------------- /Eye-tracking keyboard/README.md: -------------------------------------------------------------------------------- 1 | 2 | # ~~~ Work In Progress ~~~ 3 | -------------------------------------------------------------------------------- /Facial Landmarking/Face Landmarking.py: -------------------------------------------------------------------------------- 1 | #Importing necessary libraries 2 | 3 | import cv2 4 | import numpy as np 5 | import dlib 6 | 7 | #Creating face detection and landmark predictor objects using dlib 8 | face_detect = dlib.get_frontal_face_detector() 9 | landmark_predict = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat') 10 | 11 | #Function to convert co-ordinates of landmarks into a numpy array 12 | def to_np_arr(landmarks, dtype="int"): 13 | 14 | coords = np.zeros((68, 2), dtype=dtype) 15 | 16 | for i in range(0, 68): 17 | coords[i] = (landmarks.part(i).x, landmarks.part(i).y) 18 | 19 | return coords 20 | 21 | #Returning a tuple for bounding box 22 | def rect_to_bb(face_rect): 23 | x = face_rect.left() 24 | y = face_rect.top() 25 | w = face_rect.right() - x 26 | h = face_rect.bottom() - y 27 | return (x,y,w,h) 28 | 29 | #Creating a video capture object 30 | cap = cv2.VideoCapture(0) 31 | 32 | while True: 33 | #Reading from the webcam 34 | ret,frame = cap.read() 35 | if ret == True: 36 | #Flipping the camera view horizontally to avoid mirror view 37 | frame = cv2.flip(frame,1) 38 | #Converting the color image to grayscale for faster computation 39 | gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) 40 | #Detecting the faces on the grayscale image and getting the co-ordinates 41 | faces = face_detect(gray) 42 | for (i,face) in enumerate(faces): 43 | #Getting landmark co-ordinates over the detected faces 44 | landmarks = landmark_predict(gray,face) 45 | 46 | landmarks = to_np_arr(landmarks) 47 | (x,y,w,h) = rect_to_bb(face) 48 | #Drawing rectangle over the detected faces 49 | cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2) 50 | cv2.putText(frame,"Face #{}" .format(i+1),(x-10,y-10),cv2.FONT_HERSHEY_PLAIN,0.5,(0,255,0),2) 51 | #Drawing circles at all the co-ordinates of the landmarked region 52 | for (X,Y) in landmarks: 53 | cv2.circle(frame,(X,Y),2,(255,255,255),-1) 54 | cv2.imshow('Face-Landmarking',frame) 55 | k = cv2.waitKey(1) & 0xff 56 | #Pressing escape to end the program 57 | if k == 27: 58 | break 59 | cap.release() 60 | cv2.destroyAllWindows() 61 | -------------------------------------------------------------------------------- /Facial Landmarking/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Demo : 3 | 4 | ![Demons](https://github.com/Prathyusha-Guduru/Data/blob/master/Facial%20Landmarking.gif) 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Finger-Segmentation/Hand Segmentation and Finger Detection.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "DETECTING FINGERS :\n", 8 | "\n", 9 | "1.Defining an ROI where fingers will be detected.\n", 10 | "\n", 11 | "2.Running background analysis(Getting average background value) to study the background so that elements in the backgrounds would not be mistook as fingers.\n", 12 | "\n", 13 | "3.Finding the largest contour in the ROI assuming it to be the hand.\n", 14 | "\n", 15 | "4.Obtaining the topmost , rightend and leftend (extreme points) and finding the co-ordinates of the center of the hand by using convexHull() method.\n", 16 | "\n", 17 | "5.Finding the euclidean distances between the center and the extreme points and storing the maximum one.\n", 18 | "\n", 19 | "5.Creating a circular ROI with radius being 90% of the maximum euclidean distance and masking it on the thresholded version.\n", 20 | "\n", 21 | "6.All the external contours are then detected in the imaginary circular ROI and contours which lie in the limit_points(circumference of the circular ROI) and out_of_wrist (Height greater than wrist points) are detected as fingers and no.of finger counters are counted hence giving the no.of fingers." 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 1, 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "#Importing all the necessary libraries\n", 31 | "import cv2\n", 32 | "import numpy as np\n", 33 | "from sklearn.metrics import pairwise #For calculating the size of the palm and the fingers\n" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 2, 39 | "metadata": {}, 40 | "outputs": [], 41 | "source": [ 42 | "# GLOBAL VARIABLES TO BE USED\n", 43 | "\n", 44 | "bg = None\n", 45 | "\n", 46 | "accum_wt = 0.5 #Default value\n", 47 | "\n", 48 | "#Setting the boundaries for region of interest\n", 49 | "roi_top = 20\n", 50 | "roi_bottom = 300\n", 51 | "roi_right = 300\n", 52 | "roi_left = 600" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 3, 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "def calc_bg_accum_avg(frame,accum_wt):\n", 62 | " global bg\n", 63 | " if bg is None:\n", 64 | " bg = frame.copy().astype('float')\n", 65 | " return None\n", 66 | " cv2.accumulateWeighted(frame,bg,accum_wt)" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 4, 72 | "metadata": {}, 73 | "outputs": [], 74 | "source": [ 75 | "def segment_hand(frame,threshold = 25):\n", 76 | " global bg\n", 77 | " \n", 78 | " #Calculating absolute difference between frame and backgorund\n", 79 | " diff = cv2.absdiff(bg.astype('uint8'),frame)\n", 80 | " #Applying threshold to grab the foreground \n", 81 | " \n", 82 | " ret,threshold_img = cv2.threshold(diff,threshold,255,cv2.THRESH_BINARY)\n", 83 | " \n", 84 | " #Getting the external contours\n", 85 | " contours,_ = cv2.findContours(threshold_img.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)\n", 86 | " \n", 87 | " if len(contours) == 0:\n", 88 | " return None\n", 89 | " else:\n", 90 | " hand_segment = max(contours,key = cv2.contourArea)\n", 91 | " \n", 92 | " return (threshold_img,hand_segment)" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 5, 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "def counting_fingers(threshold_img,hand_segment):\n", 102 | " conv_hull = cv2.convexHull(hand_segment)\n", 103 | " \n", 104 | " #Grabbing the outermost corner points of the convex hull\n", 105 | " top = tuple(conv_hull[conv_hull[:, :, 1].argmin()][0])\n", 106 | " bottom = tuple(conv_hull[conv_hull[:, :, 1].argmax()][0])\n", 107 | " left = tuple(conv_hull[conv_hull[:, :, 0].argmin()][0])\n", 108 | " right = tuple(conv_hull[conv_hull[:, :, 0].argmax()][0])\n", 109 | " \n", 110 | " #Getting the co-ordinates center of the palm\n", 111 | " cX = (left[0] + right[0]) // 2\n", 112 | " cY = (top[1] + bottom[1]) // 2\n", 113 | " \n", 114 | " #Finding the euclidean distance between center of the palm\n", 115 | " #and the extreme points of the convex hull\n", 116 | " \n", 117 | " distance = pairwise.euclidean_distances([(cX,cY)],Y = [left,right,top,bottom])[0]\n", 118 | " \n", 119 | " #Grabbing the largest distance\n", 120 | " max_distance = distance.max()\n", 121 | " \n", 122 | " #Creating a circle with 80 to 90% radius of the largest euclidean distance\n", 123 | " radius = int(0.8 * max_distance)\n", 124 | " circumference = (2*np.pi * radius)\n", 125 | " \n", 126 | " circular_roi = np.zeros(threshold_img.shape[:2],dtype = 'uint8')\n", 127 | " \n", 128 | " #Drawing the circular roi\n", 129 | " cv2.circle(circular_roi,(cX,cY),radius,255,10)\n", 130 | " \n", 131 | " circular_roi = cv2.bitwise_and(threshold_img,threshold_img,mask = circular_roi)\n", 132 | " \n", 133 | " contours,_ = cv2.findContours(circular_roi.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)\n", 134 | " \n", 135 | " count = 0\n", 136 | " \n", 137 | " for cnt in contours :\n", 138 | " \n", 139 | " #Bounding box for contours\n", 140 | " \n", 141 | " (x,y,w,h) = cv2.boundingRect(cnt)\n", 142 | " \n", 143 | " #Counting the fingers (incrementing the count variable)\n", 144 | " #Based on 2 factors\n", 145 | " \n", 146 | " #1.Contour region is not the wrist area\n", 147 | " out_of_wrist = ((cY + (cY * 0.25)) > (y + h))\n", 148 | " \n", 149 | " #2.Points along the contour should not exceed 25% of the circumference of the circualar roi\n", 150 | " #(else we would be counting points of hand)\n", 151 | " \n", 152 | " limit_boundary_points = ((circumference * 0.25) > cnt.shape[0])\n", 153 | "\n", 154 | " if out_of_wrist and limit_boundary_points:\n", 155 | " count+=1\n", 156 | " return count" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": null, 162 | "metadata": {}, 163 | "outputs": [], 164 | "source": [ 165 | "#Putting everything together\n", 166 | "\n", 167 | "cap = cv2.VideoCapture(0)\n", 168 | "\n", 169 | "#Initializing the frame count\n", 170 | "num_frames = 0\n", 171 | "\n", 172 | "while True:\n", 173 | " #Get the current frame\n", 174 | " ret,frame = cap.read()\n", 175 | " \n", 176 | " if ret == True:\n", 177 | " \n", 178 | " #Flipping the camera to avoid the mirror view\n", 179 | " frame = cv2.flip(frame,1)\n", 180 | " \n", 181 | " #Cloning the frame \n", 182 | " frame_copy = frame.copy()\n", 183 | " \n", 184 | " #Grab the ROI from the frame\n", 185 | " roi = frame[roi_top : roi_bottom,roi_right:roi_left]\n", 186 | " \n", 187 | " #Apply grayscale and blur to ROI \n", 188 | " gray = cv2.cvtColor(roi,cv2.COLOR_BGR2GRAY)\n", 189 | " gray = cv2.GaussianBlur(gray,(7,7),0)\n", 190 | " \n", 191 | " #Letting the user know while the background weights are being averaged \n", 192 | " \n", 193 | " if num_frames < 60 : \n", 194 | " calc_bg_accum_avg(gray,accum_wt)\n", 195 | " if num_frames <= 59:\n", 196 | " cv2.putText(frame_copy,\"WAIT ! WORK IN PROGRESS\",(200,400),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),2)\n", 197 | " cv2.imshow(\"Finger_count\",frame_copy)\n", 198 | " \n", 199 | " else:\n", 200 | " #Segmenting the hand region\n", 201 | " hand = segment_hand(gray)\n", 202 | " \n", 203 | " if hand is not None:\n", 204 | " \n", 205 | " #unpack \n", 206 | " threhsold_img,hand_segment = hand\n", 207 | " \n", 208 | " #Draw contours arounf hand segment \n", 209 | " cv2.drawContours(frame_copy,[hand_segment + (roi_right,roi_top)],-1,(255,0,0),1)\n", 210 | " \n", 211 | " #Counting the fingers\n", 212 | " \n", 213 | " fingers = counting_fingers(threshold_img,hand_segment)\n", 214 | " \n", 215 | " #Displaying the count\n", 216 | " cv2.putText(frame_copy,str(finger),(70,45),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),2)\n", 217 | " \n", 218 | " #Displaying the thresholded image\n", 219 | " cv2.imshow(\"Threshold_img\",threshold_img)\n", 220 | " \n", 221 | " #Drawing the ROI\n", 222 | " cv2.rectangle(frame_copy,(roi_left,roi_top),(roi_right,roi_bottom),(0,0,255),5)\n", 223 | " \n", 224 | " #increment the number of framees based\n", 225 | " \n", 226 | " \n", 227 | " num_frames += 1\n", 228 | " \n", 229 | " cv2.imshow(\"Finger_count\",frame_copy)\n", 230 | " \n", 231 | " key = cv2.waitKey(1) & 0xff\n", 232 | " \n", 233 | " if key == 27:\n", 234 | " break\n", 235 | " else:\n", 236 | " break\n", 237 | "cap.release()\n", 238 | "cv2.destroyAllWindows()\n", 239 | " \n", 240 | " " 241 | ] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "execution_count": null, 246 | "metadata": {}, 247 | "outputs": [], 248 | "source": [] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": 38, 253 | "metadata": {}, 254 | "outputs": [], 255 | "source": [ 256 | "cam = cv2.VideoCapture(0)\n", 257 | "\n", 258 | "# Intialize a frame count\n", 259 | "num_frames = 0\n", 260 | "\n", 261 | "# keep looping, until interrupted\n", 262 | "while True:\n", 263 | " # get the current frame\n", 264 | " ret, frame = cam.read()\n", 265 | " \n", 266 | " if ret == True:\n", 267 | "\n", 268 | " # flip the frame so that it is not the mirror view\n", 269 | " frame = cv2.flip(frame, 1)\n", 270 | "\n", 271 | " # clone the frame\n", 272 | " frame_copy = frame.copy()\n", 273 | "\n", 274 | " # Grab the ROI from the frame\n", 275 | " roi = frame[roi_top:roi_bottom, roi_right:roi_left]\n", 276 | "\n", 277 | " # Apply grayscale and blur to ROI\n", 278 | " gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)\n", 279 | " gray = cv2.GaussianBlur(gray, (7, 7), 0)\n", 280 | "\n", 281 | " # For the first 30 frames we will calculate the average of the background.\n", 282 | " # We will tell the user while this is happening\n", 283 | " if num_frames < 60:\n", 284 | " calc_bg_accum_avg(gray, accum_wt)\n", 285 | " if num_frames <= 59:\n", 286 | " cv2.putText(frame_copy, \"WAIT! WORK IN PROGRESS.\", (200, 400), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)\n", 287 | " cv2.imshow(\"Finger Count\",frame_copy)\n", 288 | "\n", 289 | " else:\n", 290 | " # now that we have the background, we can segment the hand.\n", 291 | "\n", 292 | " # segment the hand region\n", 293 | " hand = segment_hand(gray)\n", 294 | "\n", 295 | " # First check if we were able to actually detect a hand\n", 296 | " if hand is not None:\n", 297 | "\n", 298 | " # unpack\n", 299 | " thresholded, hand_segment = hand\n", 300 | "\n", 301 | " # Draw contours around hand segment\n", 302 | " cv2.drawContours(frame_copy, [hand_segment + (roi_right, roi_top)], -1, (255, 0, 0),1)\n", 303 | "\n", 304 | " # Count the fingers\n", 305 | " fingers = counting_fingers(thresholded, hand_segment)\n", 306 | "\n", 307 | " # Display count\n", 308 | " cv2.putText(frame_copy, str(fingers), (70, 45), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)\n", 309 | "\n", 310 | " # Also display the thresholded image\n", 311 | " cv2.imshow(\"Thesholded\", thresholded)\n", 312 | "\n", 313 | " # Draw ROI Rectangle on frame copy\n", 314 | " cv2.rectangle(frame_copy, (roi_left, roi_top), (roi_right, roi_bottom), (0,0,255), 5)\n", 315 | "\n", 316 | " # increment the number of frames for tracking\n", 317 | " num_frames += 1\n", 318 | "\n", 319 | " # Display the frame with segmented hand\n", 320 | " cv2.imshow(\"Finger Count\", frame_copy)\n", 321 | "\n", 322 | "\n", 323 | " # Close windows with Esc\n", 324 | " k = cv2.waitKey(1) & 0xFF\n", 325 | "\n", 326 | " if k == 27:\n", 327 | " break\n", 328 | " else:\n", 329 | " break\n", 330 | "\n", 331 | "# Release the camera and destroy all the windows\n", 332 | "cam.release()\n", 333 | "cv2.destroyAllWindows()" 334 | ] 335 | } 336 | ], 337 | "metadata": { 338 | "kernelspec": { 339 | "display_name": "Python 3", 340 | "language": "python", 341 | "name": "python3" 342 | }, 343 | "language_info": { 344 | "codemirror_mode": { 345 | "name": "ipython", 346 | "version": 3 347 | }, 348 | "file_extension": ".py", 349 | "mimetype": "text/x-python", 350 | "name": "python", 351 | "nbconvert_exporter": "python", 352 | "pygments_lexer": "ipython3", 353 | "version": "3.8.3" 354 | } 355 | }, 356 | "nbformat": 4, 357 | "nbformat_minor": 4 358 | } 359 | -------------------------------------------------------------------------------- /Finger-Segmentation/README.md: -------------------------------------------------------------------------------- 1 | 2 | DETECTING FINGERS : 3 | 4 | 1.Defining an ROI where fingers will be detected. 5 | 6 | 2.Running background analysis(Getting average background value) to study the background so that elements in the backgrounds would not be mistook as fingers. 7 | 8 | 3.Finding the largest contour in the ROI assuming it to be the hand. 9 | 10 | 4.Obtaining the topmost , rightend and leftend (extreme points) and finding the co-ordinates of the center of the hand by using convexHull() method. 11 | 12 | 5.Finding the euclidean distances between the center and the extreme points and storing the maximum one. 13 | 14 | 5.Creating a circular ROI with radius being 90% of the maximum euclidean distance and masking it on the thresholded version. 15 | 16 | 6.All the external contours are then detected in the imaginary circular ROI and contours which lie in the limit_points(circumference of the circular ROI) and out_of_wrist (Height greater than wrist points) are detected as fingers and no.of finger counters are counted hence giving the no.of fingers. 17 | 18 | 19 | # Demo 🤟: 20 | 21 | ![Demonsddtration](https://github.com/Prathyusha-Guduru/Data/blob/master/Finger%20Detection%20and%20Segmenting.gif) 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Computer-Vision-Projects : 2 | Fun random projects built using openCV and dlib with Python. 3 | * 4 | --------------------------------------------------------------------------------