我们从Python开源项目中,提取了以下8个代码示例,用于说明如何使用cv2.convexityDefects()。
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
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