Question: I would like to make my code in PARALLEL and DISTRIBUTED programming. This is python3. Here is code. import math import cv2 import numpy as
I would like to make my code in PARALLEL and DISTRIBUTED programming.
This is python3. Here is code.
import math
import cv2
import numpy as np
def get_fingers(frame):
"""
+public
@param frame -> an unprocessed video frame of the 'region of interest'
for the hand
@return -> the number of fingers being held up in the frame or 'None'
if less than two fingers are held up
This function gets an unprocessed frame, and returns the number of
convexity defects that are part of the hand
"""
num_defects = 0
processed = __process_frame(frame)
contour = __get_hand_contour(processed)
defects = __get_hand_defects(contour)
try:
for defect in range(defects.shape[0]):
if __is_true_defect(contour, defects[defect, 0]):
num_defects += 1
# The number of fingers being held up is the number of defects + 1
if num_defects > 0:
return num_defects + 1
except AttributeError:
return None
def __process_frame(frame):
"""
-private
@param frame -> an unprocessed video frame capture from the camera
@return -> a processed video frame
This function processes the frame so that we can work with it.
First, we grayscale the frame because RGB colors are irrelevant to us.
Then, we use a bilateral filter to blur the frame, which makes finding
the hand easier. Lastly, we threshold the frame to distinguish the hand
from anything else in the background and return the processed frame.
"""
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
bilat = cv2.bilateralFilter(gray, 10, 75, 75)
"""
If the walls in the room are brighter than the hand use 'cv2.THRESH_BINARY_INV'
Otherwise use 'cv2.THRESH_BINARY'
"""
ret, thresh = cv2.threshold(bilat, 80, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
return thresh
def __get_hand_contour(frame):
"""
-private
@param frame -> a processed video frame
@return -> the contour with the greatest area in the frame (the hand)
This function finds all the contours in the provided frame and returns
the one with the greatest area, which happens to be the hand in our case
"""
ret, contours, hierarchy = cv2.findContours(frame, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
return max(contours, key = lambda c: cv2.contourArea(c))
def __get_hand_defects(contour):
"""
-private
@param contour -> the contour of the hand to get defects from
@return -> the convexity defects between the hand contour and
the convex hull
This function gets all the contours within the processed video frame,
finds the contour with the greatest area (which is the hand), generates
the convex hull around the hand, and returns the convexity defects between
the hand contour and the convex hull
"""
hull = cv2.convexHull(contour, returnPoints=False)
return cv2.convexityDefects(contour, hull)
def __is_true_defect(contour, defect):
"""
-private
@param defect -> a convexity defect
@return -> True if a true defect is found, otherwise False
This functions goes through each defect in the video frame and
constructs a triangle with the starting, ending, and far points.
It then calculates the angle between the start-to-far and end-to-far
sides and if that angle is less than pi/2, it's a defect wer're
interested in (a valley between two fingers).
"""
s, e, f, d = defect
# Get points to calculate sides of the triangle
start = tuple(contour[s][0])
end = tuple(contour[e][0])
far = tuple(contour[f][0])
# Calculate sides of the triangle
side_a = __get_distance(end[0], end[1], start[0], start[1])
side_b = __get_distance(far[0], far[1], start[0], start[1])
side_c = __get_distance(end[0], end[1], far[0], far[1])
angle = __get_angle(side_a, side_b, side_c)
# If the angle is obtuse, it's invalid
if angle <= math.pi / 2:
return True
else:
return False
def __get_distance(x1, y1, x2, y2):
"""
-private
@param x1 -> x coordinate of first point
@param y1 -> y coordinate of first point
@param x2 -> x coordinate of second point
@param y2 -> y coordinate of second point
@return -> the cartesian distance between the two points
This function returns the cartesian distance between two points
given their x and y coordinates
"""
return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
def __get_angle(side_a, side_b, side_c):
"""
-private
@param side_a -> side of the triangle opposite the angle to be calculated
@param side_b -> one side of the triangle used to calculate the angle
@param side_c -> other side of the triangle used to calculate the angle
@return -> the angle between side_b and side_c in radians
This function uses the law of cosines to find the angle between
sides B and C of a triangle
"""
return math.acos((side_b ** 2 + side_c ** 2 - side_a ** 2) / (2 * side_b * side_c))
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
