Tuesday, March 2, 2021
  • Setup menu at Appearance » Menus and assign menu to Top Bar Navigation
Advertisement
  • AI Development
    • Artificial Intelligence
    • Machine Learning
    • Neural Networks
    • Learn to Code
  • Data
    • Blockchain
    • Big Data
    • Data Science
  • IT Security
    • Internet Privacy
    • Internet Security
  • Marketing
    • Digital Marketing
    • Marketing Technology
  • Technology Companies
  • Crypto News
No Result
View All Result
NikolaNews
  • AI Development
    • Artificial Intelligence
    • Machine Learning
    • Neural Networks
    • Learn to Code
  • Data
    • Blockchain
    • Big Data
    • Data Science
  • IT Security
    • Internet Privacy
    • Internet Security
  • Marketing
    • Digital Marketing
    • Marketing Technology
  • Technology Companies
  • Crypto News
No Result
View All Result
NikolaNews
No Result
View All Result
Home Neural Networks

Real-time Finger Detection – Becoming Human: Artificial Intelligence Magazine

February 20, 2019
in Neural Networks
Real-time Finger Detection – Becoming Human: Artificial Intelligence Magazine
587
SHARES
3.3k
VIEWS
Share on FacebookShare on Twitter

Credit: BecomingHuman

Introduction

Finger detection is an interesting topic to explore in image processing, especially when it is applied in human-computer interaction. In this article, I’m going to explain the way to detect the number of fingers in the video captured by a laptop camera.

You might also like

Data Annotation Service: a Potential and Problematic Industry Behind AI | by ByteBridge

Can India beat the global AI challenge? Can we avoid huge job extinction here? | by Yogesh Chauhan | Jan, 2021

Google’s Tensorflow Certification & What I’ve Learned Since

Overview

Basically, the first task is to detect hand in the video frame. This is the most challenging part. The proposed way is to use Background Subtraction and HSV Segmentation together to create a mask. After the hand is segmented, we will detect the number of fingers raised. There are 2 proposed methods. The first is to find the largest contour in the image which is assumed to be the hand. Then, we will find the convex hull and convexity defects which are most probably the space between fingers. This is a manual way of finding the number of fingers. The second way is to use a convolutional neural network with the mask as input to determine the number of fingers. Here is the link to the source code.

Trending AI Articles:

1. Google will beat Apple at its own game with superior AI

2. Face recognition: realtime masks development

3. How to build a deep learning server based on Docker

4. How ethical is Artificial Intelligence?

Hand detection

The most challenging part is to detect the hand in an image. There are many approaches published. For example, Background Subtraction by lzane, HSV Segmentation by Amar Prakash Pandey, detecting using Haar Cascade and neural network. However, we will only talk about background subtraction and HSV segmentation in this article.

Background subtraction

For the background subtraction to work, we need to have a background image (without the hand) first. To find the hand, we can subtract the image with hand from the background. By using OpenCV, this is quite easy to implement.

Note that the code is partially given here for explanation. For the fully functional program, go to the source code here.
First, we create a background subtractor when the background is clear (without hand).

bgSubtractor = cv2.createBackgroundSubtractorMOG2(history=10, varThreshold=30, detectShadows=False)

After the background subtractor is created, we can apply the background subtraction to every video frame to create a mask.

def bgSubMasking(self, frame):
"""Create a foreground (hand) mask
@param frame: The video frame
@return: A masked frame
"""
fgmask = bgSubtractor.apply(frame, learningRate=0)

kernel = np.ones((4, 4), np.uint8)

# The effect is to remove the noise in the background
fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel, iterations=2)

    # To close the holes in the objects
fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_CLOSE, kernel, iterations=2)

# Apply the mask on the frame and return
return cv2.bitwise_and(frame, frame, mask=fgmask)

Here is the result after the background subtraction is applied.

Note that the background is masked away.

However, there is a major problem here. The background subtraction alone will capture other moving objects in the video frames. Hence, we introduce another method.

HSV segmentation

In HSV (Hue, Saturation, Value) segmentation, the idea is to segment the hand based on the color. At first, we will sample the color of the hand. Then, we detect. Usually, a pixel in a frame or an image is represented as RGB (Red, Green, Blue). The reason we use HSV rather than RGB because RGB contains the information on the brightness of the color. Therefore, when we sample the color of the hand, we sample the brightness as well. This is an issue when we detect the hand because the hand has to be under the same brightness in order to be detected. The brightness of a color is encoded in the Value (V) in the HSV. Hence, when we sample the color of the hand, we sample only the Hue (H) and Saturation (S).

Based on the technique by Amar, we will place our hand at a location to take some samples of the hand color. By using the pixels, we form a histogram to represent the frequency of each color appears in the sample. This forms a probability distribution of the colors. By normalizing the histogram, we can find the probability of each color being a part of the hand.

handHist = cv2.calcHist([roi], [0, 1], None, [180, 256], [0, 180, 0, 256])
handHist = cv2.normalize(handHist, handHist, 0, 255, cv2.NORM_MINMAX)

The argument [0,1] means to take the channels, Hue and Saturation, ignoring the third channel, Value.
Argument [0, 180, 0, 256] specifies the range of values of Hue and Saturation. Hue ranges from 0 to 179 whereas the range of values of Saturation is from 0 to 255.

After we have created the normalized histogram of colors of the hand. We can now create the HSV mask. The mask is actually a map of probability. Each pixel contains the probability of that pixel being a part of the hand.

def histMasking(frame, handHist):
"""Create the HSV masking
@param frame: The video frame
@param handHist: The histogram generated
@return: A masked frame
"""
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
dst = cv2.calcBackProject([hsv], [0, 1], handHist, [0, 180, 0, 256], 1)
    disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (21, 21))
cv2.filter2D(dst, -1, disc, dst)
# dst is now a probability map
    # Use binary thresholding to create a map of 0s and 1s
# 1 means the pixel is part of the hand and 0 means not
ret, thresh = cv2.threshold(dst, 150, 255, cv2.THRESH_BINARY)
    kernel = np.ones((5, 5), np.uint8)
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=7)
    thresh = cv2.merge((thresh, thresh, thresh))
return cv2.bitwise_and(frame, thresh)

Below is the result after the HSV segmentation.

The downside of this segmentation is that the skin color will be detected but we want only the hand. Therefore, we will use “bitwise and” operation on the foreground mask and the HSV mask. The result will be our final mask.

histMask = histMasking(roi, handHist)
bgSubMask = bgSubMasking(roi)
mask = cv2.bitwise_and(histMask, bgSubMask)

Fingers counting

After we have gotten the mask, we can now count the number of fingers. We have 2 methods. One is to do it manually by finding convexity defects. Another one is using a convolutional neural network.

Manual method

Green: Contour
Red: Convex hull
Blue: Convexity defect

After the hand segmentation, the mask should contain only the hand. Therefore, in the manual method, we will start by finding the largest contour which is assumed to be the hand.

def threshold(mask):
"""Thresholding into a binary mask"""
grayMask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(grayMask, 0, 255, 0)
return thresh
def getMaxContours(contours):
"""Find the largest contour"""
maxIndex = 0
maxArea = 0
for i in range(len(contours)):
cnt = contours[i]
area = cv2.contourArea(cnt)
if area > maxArea:
maxArea = area
maxIndex = i
return contours[maxIndex]
thresh = threshold(mask)
_, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# There might be no contour when hand is not inside the frame
if len(contours) > 0:
maxContour = getMaxContours(contours)

After finding the largest contour, we will find its convex hull. The convex hull is simply a curve covering the contour. From the convex hull, we can find the convexity defects. Convexity defects are the place where the curve are bulged inside. These are assumed to be the spaces between the fingers. We will use this to determine the number of fingers.

def countFingers(contour):
hull = cv2.convexHull(contour, returnPoints=False)
if len(hull) > 3:
defects = cv2.convexityDefects(contour, hull)
cnt = 0
if type(defects) != type(None):
for i in range(defects.shape[0]):
s, e, f, d = defects[i, 0]
start = tuple(contour[s, 0])
end = tuple(contour[e, 0])
far = tuple(contour[f, 0])
angle = calculateAngle(far, start, end)

# Ignore the defects which are small and wide
# Probably not fingers
if d > 10000 and angle <= math.pi/2:
cnt += 1
return True, cnt
return False, 0

def calculateAngle(far, start, end):
"""Cosine rule"""
a = math.sqrt((end[0] - start[0])**2 + (end[1] - start[1])**2)
b = math.sqrt((far[0] - start[0])**2 + (far[1] - start[1])**2)
c = math.sqrt((end[0] - far[0])**2 + (end[1] - far[1])**2)
angle = math.acos((b**2 + c**2 - a**2) / (2*b*c))
return angle

When counting the convexity defects, we have to impose some limitations. We do not want to take all the convexity defects especially when there is a distortion on the contour. The limitations include the depth of the defects has to be larger than a certain value (10000 in the example above). We exclude small defects which are probably not the fingers. Besides, we exclude the defects which are wider than 90 degrees. We calculate the angle by using cosine rule.

The output will be the number of convexity defects. For example, if the number of convexity defects is two, then the number of fingers raised is three. However, using only these, we cannot differentiate between no finger raised and one finger raised. This can be solved by calculating the distance between the centroid of the contour and the highest point of the contour. If it is larger than a certain distance, the number of fingers raised is one, else no finger raised.

Convolutional neural network

Using a Convolutional Neural Network (CNN) actually simplifies a lot of work. Keras in python is a good option. It is relatively simple. Due to limited GPU memory, I have resized the video frame from 260*260 to 28*28. Feel free to try giving the original size as the input to the CNN. Below is how I construct my CNN model.

model = Sequential()
model.add(Conv2D(32, (3,3), activation=’relu’, input_shape=(28, 28, 1)))
model.add(Conv2D(64, (3,3), activation=’relu’))
model.add(MaxPooling2D((2,2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation=’relu’))
model.add(Dropout(0.5))
model.add(Dense(6, activation=’softmax’))

I have trained my model using approximately 1000 images per class and 200 images for testing. I have done some rotation, shifting and flipping on the training images. For more details, check out the source code.

I try to balance the number of training images to prevent a bias in the model.

Here are the samples of my training data.

The result looks pretty good. It achieves validation accurracy of 99% at the fifth epoch. However, the model is trained and tested on my own hand. It might not generalize well to other people’s hand. Therefore, I’m not posting my model. I have implemented a functionality to capture the images of your own hand. Preparing your own training images should be quite simple.


Credit: BecomingHuman By: Chin Huan Tan

Previous Post

Congress wants Facebook to explain why closed groups leaked user data

Next Post

AI, Machine Learning, and Robotics Are Fundamentally Changing Healthcare, Says Johnson & Johnson CEO

Related Posts

Data Annotation Service: a Potential and Problematic Industry Behind AI | by ByteBridge
Neural Networks

Data Annotation Service: a Potential and Problematic Industry Behind AI | by ByteBridge

March 2, 2021
Can India beat the global AI challenge? Can we avoid huge job extinction here? | by Yogesh Chauhan | Jan, 2021
Neural Networks

Can India beat the global AI challenge? Can we avoid huge job extinction here? | by Yogesh Chauhan | Jan, 2021

March 2, 2021
Google’s Tensorflow Certification & What I’ve Learned Since
Neural Networks

Google’s Tensorflow Certification & What I’ve Learned Since

March 2, 2021
How AI Can Be Used in Agriculture Sector for Higher Productivity? | by ANOLYTICS
Neural Networks

How AI Can Be Used in Agriculture Sector for Higher Productivity? | by ANOLYTICS

February 27, 2021
Future Tech: Artificial Intelligence and the Singularity | by Jason Sherman | Feb, 2021
Neural Networks

Future Tech: Artificial Intelligence and the Singularity | by Jason Sherman | Feb, 2021

February 27, 2021
Next Post
AI, Machine Learning, and Robotics Are Fundamentally Changing Healthcare, Says Johnson & Johnson CEO

AI, Machine Learning, and Robotics Are Fundamentally Changing Healthcare, Says Johnson & Johnson CEO

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recommended

Plasticity in Deep Learning: Dynamic Adaptations for AI Self-Driving Cars

Plasticity in Deep Learning: Dynamic Adaptations for AI Self-Driving Cars

January 6, 2019
Microsoft, Google Use Artificial Intelligence to Fight Hackers

Microsoft, Google Use Artificial Intelligence to Fight Hackers

January 6, 2019

Categories

  • Artificial Intelligence
  • Big Data
  • Blockchain
  • Crypto News
  • Data Science
  • Digital Marketing
  • Internet Privacy
  • Internet Security
  • Learn to Code
  • Machine Learning
  • Marketing Technology
  • Neural Networks
  • Technology Companies

Don't miss it

DSC Weekly Digest 01 March 2021
Data Science

DSC Weekly Digest 01 March 2021

March 2, 2021
The case for Bayesian Learning in mining
Machine Learning

The case for Bayesian Learning in mining

March 2, 2021
Scientists have built this ultrafast laser-powered random number generator
Internet Security

Scientists have built this ultrafast laser-powered random number generator

March 2, 2021
Companies in the Global Data Science Platforms Resorting to Product Innovation to Stay Ahead in the Game
Data Science

Companies in the Global Data Science Platforms Resorting to Product Innovation to Stay Ahead in the Game

March 2, 2021
Aries becomes next Hyperledger project graduating to active status
Blockchain

Aries becomes next Hyperledger project graduating to active status

March 2, 2021
Government trialling machine learning tech to detect pests at shipping ports
Machine Learning

Government trialling machine learning tech to detect pests at shipping ports

March 2, 2021
NikolaNews

NikolaNews.com is an online News Portal which aims to share news about blockchain, AI, Big Data, and Data Privacy and more!

What’s New Here?

  • DSC Weekly Digest 01 March 2021 March 2, 2021
  • The case for Bayesian Learning in mining March 2, 2021
  • Scientists have built this ultrafast laser-powered random number generator March 2, 2021
  • Companies in the Global Data Science Platforms Resorting to Product Innovation to Stay Ahead in the Game March 2, 2021

Subscribe to get more!

© 2019 NikolaNews.com - Global Tech Updates

No Result
View All Result
  • AI Development
    • Artificial Intelligence
    • Machine Learning
    • Neural Networks
    • Learn to Code
  • Data
    • Blockchain
    • Big Data
    • Data Science
  • IT Security
    • Internet Privacy
    • Internet Security
  • Marketing
    • Digital Marketing
    • Marketing Technology
  • Technology Companies
  • Crypto News

© 2019 NikolaNews.com - Global Tech Updates