def camera_gesture_trigger():
# Capture frame-by-frame
ret, frame = cap.read()
# Our operations on the frame come here
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),0)
ret,thresh1 = cv2.threshold(blur,70,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(thresh1,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
max_area=0
for i in range(len(contours)):
cnt=contours[i]
area = cv2.contourArea(cnt)
if(area>max_area):
max_area=area
ci=i
cnt=contours[ci]
hull = cv2.convexHull(cnt)
moments = cv2.moments(cnt)
cnt = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)
hull = cv2.convexHull(cnt,returnPoints = False)
defects = cv2.convexityDefects(cnt,hull)
if defects is not None:
if defects.shape[0] >= 5:
return 1
return 0
python类convexityDefects()的实例源码
def drawConvexHull(img, contours):
cnt = contours[0]
mask = np.zeros(img.shape, np.uint8)
hull = cv2.convexHull(cnt,returnPoints = False)
defects = cv2.convexityDefects(cnt,hull)
for i in range(defects.shape[0]):
s,e,f,d = defects[i,0]
start = tuple(cnt[s][0])
end = tuple(cnt[e][0])
far = tuple(cnt[f][0])
cv2.line(mask,start,end,[255,255,255],5)
cv2.circle(mask,far,5,[255,255,255],-1)
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
cv2.circle(mask,center,radius,(255,255,255),-1)
return mask
def calculateFingers(res,drawing): # -> finished bool, cnt: finger count
# convexity defect
hull = cv2.convexHull(res, returnPoints=False)
if len(hull) > 3:
defects = cv2.convexityDefects(res, hull)
if type(defects) != type(None): # avoid crashing. (BUG not found)
cnt = 0
for i in range(defects.shape[0]): # calculate the angle
s, e, f, d = defects[i][0]
start = tuple(res[s][0])
end = tuple(res[e][0])
far = tuple(res[f][0])
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)) # cosine theorem
if angle <= math.pi / 2: # angle less than 90 degree, treat as fingers
cnt += 1
cv2.circle(drawing, far, 8, [211, 84, 0], -1)
return True, cnt
return False, 0
# Camera
def get_defects(self, cnt, drawing):
defects = None
hull = cv2.convexHull(cnt)
cv2.drawContours(drawing, [cnt], 0, (0, 255, 0), 0)
cv2.drawContours(drawing, [hull], 0, (0, 0, 255), 0)
hull = cv2.convexHull(cnt, returnPoints=False) # For finding defects
if hull.size > 2:
defects = cv2.convexityDefects(cnt, hull)
return defects
# Gesture Recognition
def _find_hull_defects(self, segment):
# Use cv2 findContours function to find all the contours in segmented img
contours, hierarchy = cv2.findContours(segment, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# assume largest contour is the one of interest
max_contour = max(contours, key=cv2.contourArea)
epsilon = 0.01*cv2.arcLength(max_contour, True)
max_contour = cv2.approxPolyDP(max_contour, epsilon, True)
# determine convex hull & convexity defects of the hull
hull = cv2.convexHull(max_contour, returnPoints=False)
defects = cv2.convexityDefects(max_contour, hull)
return (max_contour, defects)
def count_fingers(img):
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Otsu's thresholding after Gaussian filtering
img = cv2.GaussianBlur(img, (5, 5), 0)
ret, mask = cv2.threshold(img, 0, 255,
cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
cv2.imshow("Threshold", mask)
(_, cnts, _) = cv2.findContours(mask,
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
list_far = []
list_end = []
if cnts:
areas = [cv2.contourArea(c) for c in cnts]
max_index = np.argmax(areas)
cnt = cnts[max_index]
M = cv2.moments(cnt)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
hull1 = cv2.convexHull(cnt)
hull2 = cv2.convexHull(cnt, returnPoints=False)
try:
defects = cv2.convexityDefects(cnt, hull2)
except Exception, e:
defects = None
print e
counter = 0
if defects is not None:
for i in range(defects.shape[0]):
s, e, f, d = defects[i, 0]
# start = tuple(cnt[s][0])
end = tuple(cnt[e][0])
far = tuple(cnt[f][0])
if d < 20000:
continue
if far[1] >= (cy+40):
continue
diff1 = abs(end[0]-far[0])
if diff1 > 100:
continue
cv2.line(img, end, far, (0, 0, 0), 2, 8)
cv2.imshow("hand", img)
cv2.waitKey(1)
list_far.append(far)
list_end.append(end)
counter += 1
return mask, counter, hull1, (cx, cy), list_far, list_end
def count_fingers(hand_frame):
hand_frame = cv2.cvtColor(hand_frame,cv2.COLOR_BGR2GRAY)
# Otsu's thresholding after Gaussian filtering
hand_frame = cv2.GaussianBlur(hand_frame,(5,5),0)
ret,mask = cv2.threshold(hand_frame,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
(cnts,_)=cv2.findContours(mask.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
list_far=[]
list_end=[]
if cnts:
areas = [cv2.contourArea(c) for c in cnts]
max_index = np.argmax(areas)
cnt=cnts[max_index]
M = cv2.moments(cnt)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
hull1 = cv2.convexHull(cnt)
hull2 = cv2.convexHull(cnt,returnPoints = False)
try:
defects = cv2.convexityDefects(cnt,hull2)
except Exception, e:
defects = None
print e
counter = 0
if defects is not None:
for i in range(defects.shape[0]):
s,e,f,d = defects[i,0]
start = tuple(cnt[s][0])
end = tuple(cnt[e][0])
far = tuple(cnt[f][0])
if d<20000:
continue
if far[1] >= (cy+40):
continue
else:
pass
list_far.append(far)
list_end.append(end)
counter +=1
return mask,counter,hull1,(cx,cy),list_far,list_end
def detect(array, verbose = False):
event = Event(Event.NONE)
copy = array.copy()
gray = _to_grayscale(array)
blur = cv2.GaussianBlur(gray, ksize = _DEFAULT_GAUSSIAN_BLUR_KERNEL, sigmaX = 0)
_, thresh = cv2.threshold(blur, 127, 255, _DEFAULT_THRESHOLD_TYPE)
if verbose:
cv2.imshow('spockpy.HoverPad.roi.threshold', thresh)
contours = _get_contours(thresh.copy())
largecont = max(contours, key = lambda contour: cv2.contourArea(contour))
if verbose:
roi = cv2.boundingRect(largecont)
copy = _mount_roi(copy, roi, color = _COLOR_RED)
convexHull = cv2.convexHull(largecont)
if verbose:
_draw_contours(copy, contours ,-1, _COLOR_RED , 0)
_draw_contours(copy, [largecont] , 0, _COLOR_GREEN, 0)
_draw_contours(copy, [convexHull], 0, _COLOR_GREEN, 0)
hull = cv2.convexHull(largecont, returnPoints = False)
defects = cv2.convexityDefects(largecont, hull)
if defects is not None:
copy, ndefects = _get_defects_count(copy, largecont, defects, verbose = verbose)
if ndefects == 0:
copy, tip = _get_tip_position(copy, largecont, verbose = verbose)
event.setTip(tip)
# TODO: check for a single finger.
event.setType(Event.ROCK)
elif ndefects == 1:
# TODO: check for an Event.LIZARD
event.setType(Event.SCISSOR)
elif ndefects == 2:
event.setType(Event.SPOCK)
elif ndefects == 4:
event.setType(Event.PAPER)
if verbose:
cv2.imshow('spockpy.HoverPad.roi', copy)
if verbose:
return copy, event
else:
return event