def func(ImgNo, defThr=127): img = cv2.imread(impDef.select_img(ImgNo)) img1 = img.copy() imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thr = cv2.threshold(imgray, defThr, 255, 0) contours, _ = cv2.findContours(thr, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnt = contours[0] # Convex Hull만을 찾기 위해 contours 1개만을 인자로 입력 hull = cv2.convexHull(cnt) cv2.drawContours(img, [hull], 0, (0, 0, 255), 2) # Convexity Defects를 찾기위해 2번째 인자로 returnPoints = False를 지정해야 함 # (cnt, returnPoints = False) 인자로 주어진 cnt를 분석하여 Convex Hull을 이루는 모든 좌표를 리턴하는 것이 아니라, # 원래 Contour와 Convex Hull이 만나는 부부의 Contour 인덱스를 리턴함. # 즉 별의 꼭지점에 해당하는 5군데를 리턴함. hull = cv2.convexHull(cnt, returnPoints=False) defects = cv2.convexityDefects(cnt, hull) for i in range(defects.shape[0]): sp, ep, fp, dist = defects[i, 0] start = tuple(cnt[sp][0]) end = tuple(cnt[ep][0]) farthest = tuple(cnt[fp][0]) cv2.circle(img, farthest, 5, (0, 255, 0), -1) cv2.imshow('defects', img) impDef.close_window()
def contour_points(largest_contour, image): hull = cv2.convexHull(largest_contour) drawing = np.zeros(image.shape, np.uint8) cv2.drawContours(drawing, [largest_contour], 0, (0, 255, 0), 2) #cv2.drawContours(drawing, [hull], 0, (0, 0, 255), 3) hull = cv2.convexHull(largest_contour, returnPoints=False) defects = cv2.convexityDefects(largest_contour, hull) # draw furthest left,top and right point point_list = [] # detect fingers middle defects k = 1 for i in range(defects.shape[0]): s, e, f, d = defects[i, 0] start = tuple(largest_contour[s][0]) end = tuple(largest_contour[e][0]) far = tuple(largest_contour[f][0]) angle = calculateAngle(far, start, end) if d > 10000 and angle <= math.pi / 2: if (k == 1): cv2.circle(drawing, start, 8, (147, 20, 255), -1) point_list.append(start) cv2.circle(drawing, end, 8, (147, 20, 255), -1) point_list.append(far) point_list.append(end) cv2.circle(drawing, far, 5, [255, 0, 0], -1) k += 1 return drawing, point_list
def convexityDetectionImg(self): try: img = cv2.imread(self.filename) img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(img_gray, 127, 255, 0) contours, hierarchy = cv2.findContours(thresh, 2, 1) cnt = contours[0] 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(img, start, end, [0, 255, 0], 2) cv2.circle(img, far, 5, [0, 0, 255], -1) cv2.imwrite('img/dist/disbukey.png', img, [cv2.IMWRITE_JPEG_QUALITY, 100]) cv2.waitKey(0) cv2.destroyAllWindows() except: pass
def replace_ht_a(anns, output, in_shape, num_cls=15, a_method=1): new_h = output['hm'].shape[2] new_w = output['hm'].shape[3] down_ratio_h = in_shape[0] / new_h down_ratio_w = in_shape[1] / new_w hm = torch.zeros((1, num_cls, new_h, new_w), dtype=torch.float32).cuda() angle = output['a'] offset = output['reg'] for ann in anns: cls = int(ann['category_id']) - 1 segm = np.array(ann['segmentation'][0]) segm_hull = cv.convexHull( segm.reshape(-1, 2).astype(np.float32), clockwise=False) xy, (w, h), a = cv.minAreaRect(segm_hull) a, w, h = convert_angle(a, w, h, a_method) ct = xy[0] / down_ratio_w, xy[1] / down_ratio_h ct_int = int(ct[0]), int(ct[1]) try: offset[0][0][ct_int[1]][ct_int[0]] = ct[0] - ct_int[0] offset[0][1][ct_int[1]][ct_int[0]] = ct[1] - ct_int[1] hm[0][cls][ct_int[1]][ct_int[0]] = 1. angle[0][0][ct_int[1]][ct_int[0]] = a / 90. except IndexError: print(ann) output['hm'] = hm
def deal_edged_boxes(self, cropToObjs): newCropToObjs = defaultdict() for img_box, objs in cropToObjs.items(): # min_x, max_x = img_box[0], img_box[2] # min_y, max_y = img_box[1], img_box[3] img_x1y1wh = cvtools.x1y1x2y2_to_x1y1wh(img_box) img_poly = np.array( x1y1wh_to_x1y1x2y2x3y3x4y4(img_x1y1wh) ).reshape(-1, 2) img_poly = Polygon(img_poly).convex_hull new_objs = [] for obj in objs: new_obj = copy.deepcopy(obj) # box_x1y1x2y2 = cvtools.x1y1wh_to_x1y1x2y2(obj['bbox']) # bbox = np.array(box_x1y1x2y2).reshape(-1, 2) # bbox[..., 0] = np.clip(bbox[..., 0], min_x, max_x-1) # bbox[..., 1] = np.clip(bbox[..., 1], min_y, max_y-1) # obj['bbox'] = cvtools.x1y1x2y2_to_x1y1wh(bbox.reshape(-1).tolist()) segm = np.array(obj['segmentation']).reshape(-1, 2) segm_poly = Polygon(segm).convex_hull segm_poly = img_poly.intersection(segm_poly) # 注意不能原位修改obj,否则会影响到其它crop_img的obj new_obj['bbox'] = cvtools.x1y1x2y2_to_x1y1wh(segm_poly.bounds) # segm[..., 0] = np.clip(segm[..., 0], min_x, max_x) # segm[..., 1] = np.clip(segm[..., 1], min_y, max_y) a = np.array(list(segm_poly.exterior.coords)).reshape(-1, 2) segm_hull = cv.convexHull(a.astype(np.float32), clockwise=False) new_obj['segmentation'] = [np.array(segm_hull).reshape(-1).tolist()] new_objs.append(new_obj) newCropToObjs[img_box] = new_objs return newCropToObjs
def find_second_contours(base_out, output): contours = cv2.findContours(base_out, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_TC89_KCOS) contours_map = {} for idx in range(0, len(contours[1])): area = cv2.contourArea(contours[1][idx]) contours_map[idx] = {'area': area, 'contour': contours[1][idx]} pass contours_map = sorted(contours_map.items(), key=lambda d: d[1]['area']) for idx in range(1, 3): id = -idx max_contours = contours_map[id][1]['contour'] hulls = cv2.convexHull(max_contours, returnPoints=False) pts_index = cv2.convexityDefects(contour=max_contours, convexhull=hulls) pts = [] for v in pts_index: pts.append(max_contours[v[0][0]]) pts.append(max_contours[v[0][1]]) ndpts = np.zeros((len(pts), 1, 2), np.int32) for idx in range(0, len(pts)): ndpts[idx] = pts[idx] cv2.drawContours(output, ndpts, -1, (0, 255, 0), cv2.FILLED, cv2.LINE_AA) return output
def getBoxPoint(contour): """ 多边形拟合凸包 """ hull = cv2.convexHull(contour) epsilon = 0.02 * cv2.arcLength(contour, True) approx = cv2.approxPolyDP(hull, epsilon, True) approx = approx.reshape((len(approx), 2)) return approx
def get_corners(contour, max_iter=200): corners = None accuracy = 1 while max_iter > 0 and accuracy >= 0: max_iter = max_iter - 1 epsilon = accuracy * cv2.arcLength(contour, True) poly_approx = cv2.approxPolyDP(contour, epsilon, True) hull = cv2.convexHull(poly_approx) # we found 4 corners, return these if len(hull) == 4: corners = hull break else: # if there are more corners, decrease accuracy if len(hull) > 4: accuracy += .01 # else, increase accuracy else: accuracy -= .01 if corners is None: return None return corners.reshape(4, 2)
def count(thresholded, segmented): # find the convex hull of the segmented hand region hull = cv2.convexHull(segmented, returnPoints=False) defects = cv2.convexityDefects(segmented, hull) # Bascially indicates how much finger is visible in screen countDefects = 0 for i in range(defects.shape[0]): # Returns start point, end point, farthest point, approximate distance to farthest point s, e, f, d = defects[i, 0] start = tuple(segmented[s][0]) end = tuple(segmented[e][0]) far = tuple(segmented[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) # This angle is used while hand is moving around angle = (math.acos((b**2 + c**2 - a**2) / (2 * b * c)) * 180) / 3.14 # If angle < 90 degree then treat as a finger if angle <= 90: countDefects += 1 return (countDefects + 1)
def calculateAreas(contours): hand = max(contours, key=lambda x: cv.contourArea(x)) handArea = cv.contourArea(hand) handHull = cv.convexHull(hand) hhArea = cv.contourArea(handHull) ratio = handArea / hhArea return hhArea, ratio
def get_minAreaRect(cnt): """返回:(中心(x,y), (宽,高), 旋转角度)""" assert isinstance(cnt, np.ndarray) cnt = cnt.reshape(-1, 2) # the clockwise output convex hull in the Cartesian coordinate system cnt_hull = cv.convexHull(cnt.astype(np.float32), clockwise=False) xywha = cv.minAreaRect(cnt_hull) return xywha
def dibujar(mask, color): contornos, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for c in contornos: area = cv2.contourArea(c) if area < 1000 and area > 500: nuevoContorno = cv2.convexHull(c) cv2.drawContours(frame, [nuevoContorno], 0, color, 3)
def ConvexHull_Cal(contour): IsTriangle = lambda a, b, c: a + b > c and a + c > b and b + c > a #任意两边和必须大于第三边 point_list = [] convex_angle_ls = [] concave_angle_ls = [] epsilon = 0.003 * cv2.arcLength(contour, True) contour = cv2.approxPolyDP(contour, epsilon, True) #轮廓近似,Douglas-Peucker算法 hull = cv2.convexHull(contour, returnPoints=False) defects = cv2.convexityDefects(contour, hull) _, radius = cv2.minEnclosingCircle(contour) if defects is not None: for i in range(defects.shape[0]): s, e, f, _ = defects[i, 0] sta = tuple(contour[s][0]) end = tuple(contour[e][0]) far = tuple(contour[f][0]) point_list.append([sta, far, end]) #下面的角边标示含义见文件夹里的图片说明 if len(point_list) >= 2: for it_1, it_2 in zip(point_list, point_list[1:] + point_list[:1]): CA = scfun.Eucledian_Distance(it_1[1], it_1[2]) #far to end AB = scfun.Eucledian_Distance(it_1[2], it_2[1]) #end to next far #凸包的角度 if radius <= CA + AB < 2 * radius: BC = scfun.Eucledian_Distance(it_1[1], it_2[1]) #far to 2nd far,为底边 if IsTriangle(CA, AB, BC): angle = acos((CA**2 + AB**2 - BC**2) / (2 * CA * AB)) convex_angle_ls.append(angle) #凹陷的角度 DC = scfun.Eucledian_Distance(it_1[0], it_1[1]) #sta to far if radius <= DC + CA < 2 * radius: DA = scfun.Eucledian_Distance(it_1[0], it_1[2]) #sta to end,为底边 if IsTriangle(DC, CA, DA): angle = acos((CA**2 + DC**2 - DA**2) / (2 * CA * DC)) concave_angle_ls.append(angle) convex_angle = [x for x in convex_angle_ls if pi / 18 <= x <= pi / 6] #凸包角度:10度至30度 convex_len = len(convex_angle) concave_angle = [ x for x in concave_angle_ls if pi / 18 <= x <= pi / 3.5 ] concave_len = len(concave_angle) result = [convex_len, concave_len] else: result = [0, 0] return result
def contour_points(largest_contour, image): hull = cv2.convexHull(largest_contour) drawing = image cv2.drawContours(drawing, [hull], 0, (0, 0, 255), 3) hull = cv2.convexHull(largest_contour, returnPoints=False) defects = cv2.convexityDefects(largest_contour, hull) # draw furthest left,top and right point point_list = [] # detect fingers middle defects k = 1 deffect_count = 0 if defects is not None: for i in range(defects.shape[0]): s, e, f, d = defects[i, 0] start = tuple(largest_contour[s][0]) end = tuple(largest_contour[e][0]) far = tuple(largest_contour[f][0]) angle = calculateAngle(far, start, end) if d > 20000 and angle <= math.pi / 2: #if d > 70000 and angle <= math.pi/2: #print(d) if (k == 1): ''' cv2.circle(drawing, start, 30, (147, 20, 255), -1) point_list.append(start) cv2.circle(drawing, end, 30, (147, 20, 255), -1) cv2.circle(drawing,far,30,[255,0,0],-1) ''' cv2.circle(drawing, start, 10, (147, 20, 255), -1) point_list.append(start) cv2.circle(drawing, end, 10, (147, 20, 255), -1) cv2.circle(drawing, far, 10, [255, 0, 0], -1) k += 1 deffect_count += 1 #drawing = cv2.putText(drawing, str(deffect_count), (1800, 200), cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, 5 ,(0,0,255), 10, cv2.LINE_AA) #AVS drawing = cv2.putText(drawing, str(deffect_count), (650, 150), cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, 5, (0, 0, 255), 10, cv2.LINE_AA) return drawing, point_list, deffect_count
def compute_convex_hull(contours, max_contour_index, PATH): # Convex Hull for subdir, dirs, files in os.walk(PATH): i = 0 for file in files: file_path = subdir + os.sep + file img = cv2.imread(file_path, 1) blurred_img = apply_gaussian_blurring(img, 9, 9) grayscale_img = cv2.cvtColor(blurred_img, cv2.COLOR_BGR2GRAY) _, binary_img = cv2.threshold(src=grayscale_img, thresh=50, maxval=255, type=cv2.THRESH_BINARY) contours, hierachy = cv2.findContours(image=binary_img, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_NONE) max_contour_index = get_max_contour(contours=contours) hull = cv2.convexHull(contours[max_contour_index], returnPoints=True) if (i < 5): cv2.drawContours(img, [hull], 0, (255, 0, 0), 1) # cv2.imshow('Convex Hull_{}'.format(i), img) i += 1 # Convexity defects hull_ints = cv2.convexHull(contours[max_contour_index], returnPoints=False) hull_points = cv2.convexHull(contours[max_contour_index], returnPoints=True) defects = cv2.convexityDefects(contours[max_contour_index], hull_ints) for i in range(defects.shape[0]): s, e, f, d = defects[i, 0] start = tuple(contours[max_contour_index][s][0]) end = tuple(contours[max_contour_index][e][0]) far = tuple(contours[max_contour_index][f][0]) cv2.line(img, start, end, [0, 255, 0], 2) cv2.circle(img, far, 2, [0, 0, 255], -1) cv2.imshow('Convexity defects', img)
def trans_polygon_to_rbox(polygon): """求polygon的最小外接旋转矩形 Args: polygon: 一维数组,或(K, 2)数组 """ if not isinstance(polygon, np.ndarray): polygon = np.array(polygon) polygon = polygon.reshape(-1, 2).astype(np.float32) segm_hull = cv.convexHull(polygon, clockwise=False) xywha = cv.minAreaRect(segm_hull) rbox = cv.boxPoints(xywha).reshape(-1).tolist() return rbox
def __filter_contours(input_contours, intput_contors_hierarchy, min_area, min_perimeter, min_width, max_width, min_height, max_height, solidity, max_vertex_count, min_vertex_count, min_ratio, max_ratio): """Filters out contours that do not meet certain criteria. Args: input_contours: Contours as a list of numpy.ndarray. min_area: The minimum area of a contour that will be kept. min_perimeter: The minimum perimeter of a contour that will be kept. min_width: Minimum width of a contour. max_width: MaxWidth maximum width. min_height: Minimum height. max_height: Maximimum height. solidity: The minimum and maximum solidity of a contour. min_vertex_count: Minimum vertex Count of the contours. max_vertex_count: Maximum vertex Count. min_ratio: Minimum ratio of width to height. max_ratio: Maximum ratio of width to height. Returns: Contours as a list of numpy.ndarray. """ output = [] for i in range(len(input_contours)): x, y, w, h = cv2.boundingRect(input_contours[i]) if (w < min_width or w > max_width): continue if (h < min_height or h > max_height): continue area = cv2.contourArea(input_contours[i]) if (area < min_area): continue if (cv2.arcLength(input_contours[i], True) < min_perimeter): continue hull = cv2.convexHull(input_contours[i]) if cv2.contourArea(hull) > 0: solid = 100 * area / cv2.contourArea(hull) else: solid = -1 if (solid < solidity[0] or solid > solidity[1]): continue if (len(input_contours[i]) < min_vertex_count or len(input_contours[i]) > max_vertex_count): continue ratio = (float)(w) / h if (ratio < min_ratio or ratio > max_ratio): continue if intput_contors_hierarchy[ 0, i, 2] < 0 or intput_contors_hierarchy[0, i, 3] < 0: output.append(input_contours[i]) return output
def detect_table(img): """ :param img: :return: """ # non-maxima suppression ret, thresh = cv2.threshold(img, 250, 255, 0) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) if len(contours) > 0: largest_contour = sorted(contours, key=cv2.contourArea)[-1:] table_contour = cv2.convexHull(largest_contour[0]) return table_contour else: return []
def Gestures_Detect(hand, sample_list, fourier_des_ls): ndefects = 0 sign, large_cout = Find_Contour(hand, sample_list, fourier_des_ls) if sign == False: ndefects = 11 #返回contours为空的信息,只作调试用 center = tuple([a // 2 for a in reversed(hand.shape)]) #返回图像的中心坐标 return hand, ndefects, center black2 = np.ones(hand.shape, np.uint8) #创建黑色幕布 cv2.drawContours(black2, large_cout, -1, (255, 255, 255), 2) #绘制白色轮廓 cv2.imshow('large_cout', black2) hull = cv2.convexHull(large_cout, returnPoints=False) defects = cv2.convexityDefects(large_cout, hull) _, radius = cv2.minEnclosingCircle(large_cout) if defects is not None: for i in range(defects.shape[0]): s, e, f, _ = defects[i, 0] sta = tuple(large_cout[s][0]) end = tuple(large_cout[e][0]) far = tuple(large_cout[f][0]) B = scfun.Eucledian_Distance(sta, far) C = scfun.Eucledian_Distance(end, far) #过滤掉角边太短的角 if B + C > radius: A = scfun.Eucledian_Distance(sta, end) #底边 angle = acos((B**2 + C**2 - A**2) / (2 * B * C)) if angle <= pi / 2.5: ndefects += 1 else: ndefects = 12 ''' test=scfun.Fourier_Descriptor(large_cout[:,0,:],Normalize=True) similar=scfun.Eucledian_Distance(test,fourier_des_ls[0]) print('{:.5f} {:.5f}'.format(similar,log(similar))) ''' M = cv2.moments(large_cout) center = (int(M['m10'] / M['m00']), int(M['m01'] / M['m00'])) #手部的质心坐标 x, y, w, h = cv2.boundingRect(large_cout) hand = cv2.cvtColor(hand, cv2.COLOR_GRAY2BGR) #将灰度图像转换为BGR以显示绿色方框 hand = cv2.rectangle(hand, (x, y), (x + w, y + h), (0, 255, 0), 2) return hand, ndefects, center
def handle_ann(self, ann): """如果想自定义ann处理方式,继承此类,然后重新实现此方法""" if self.num_coors == 4: bboxes = cvtools.x1y1wh_to_x1y1x2y2(ann['bbox']) elif self.num_coors == 8: segm = ann['segmentation'][0] if len(segm) != 8: segm_hull = cv.convexHull( np.array(segm).reshape(-1, 2).astype(np.float32), clockwise=False) xywha = cv.minAreaRect(segm_hull) segm = cv.boxPoints(xywha).reshape(-1).tolist() bboxes = segm else: raise RuntimeError('不支持的坐标数!') return bboxes + [1.]
def get_min_area_rect(cnt): """包装cv.minAreaRect Args: cnt: (np.ndarray): [x1, y1, x2, y2, x3, y3, x4, y4, ...] Returns: xywha:((x,y), (w,h), a), (x,y) is Oriented Bounding Box(OBB)'s center point, a is orientation, which range is [-90, 0) """ assert isinstance(cnt, np.ndarray) cnt = cnt.reshape(-1, 2) # the clockwise output convex hull in the Cartesian coordinate system cnt_hull = cv.convexHull(cnt.astype(np.float32), clockwise=False) xywha = cv.minAreaRect(cnt_hull) return xywha
def convex(ImgNo, defThr=127): img = cv2.imread(impDef.select_img(ImgNo)) img1 = img.copy() imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thr = cv2.threshold(imgray, defThr, 255, 0) cv2.imshow('thr', thr) impDef.close_window() contours, _ = cv2.findContours(thr, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnt = contours[1] ## 코드영역 따기 cntI = 0 for i in contours: cnt0 = contours[cntI] area = cv2.contourArea(cnt0) print('면적 : ', area) #영역의 크기가 45000 보다 크고 50000보다 작은경우만 출력 if area >= 45000 and area < 50000: cv2.drawContours(img1, [cnt0], 0, (0, 0, 255), 2) cv2.imshow('contour', img1) impDef.close_window() cntI = cntI + 1 ## cv2.drawContours(img, [cnt], 0, (0, 255, 0), 3) check = cv2.isContourConvex(cnt) # cv2.isContourConvex() 함수는 인자로 입력된 Contour가 Convex Hull 인지 체크합니다. # 만만 Convex Hull이라면 True를 리턴하고 그렇지 않으면 False를 리턴합니다. if not check: hull = cv2.convexHull(cnt) cv2.drawContours(img1, [hull], 0, (0, 255, 0), 3) cv2.imshow('convexhull', img1) # check 값이 False인 경우, 다시 말하면 우리가 주목하는 Contour가 Convex Hull이 # 아니라면 cv2.convexHull() 함수를 이용해 원본이미지의 contours[1]에 대한 # convex hull 곡선을 구합니다. cv2.imshow('contour', img) impDef.close_window()
def calculateFingers(max_contour, drawing, img): hull = cv2.convexHull(max_contour, returnPoints=False) if len(hull) > 3: defects = cv2.convexityDefects(max_contour, hull) if type(defects) != type(None): cnt = 0 for i in range(defects.shape[0]): # calculate the angle s, e, f, _ = defects[i][0] start = tuple(max_contour[s][0]) end = tuple(max_contour[e][0]) far = tuple(max_contour[f][0]) angle = calculateAngle(far, start, end) if angle <= math.pi / 2: cnt += 1 cv2.circle(drawing, far, 8, [211, 84, 0], -1) return cnt return 0
def contour(frame): # Remove face using cascades def blackout(frame,gray): face_cascade = cv2.CascadeClassifier('hand_detection/haarcascade_frontalface_default.xml') faces = face_cascade.detectMultiScale(gray,1.2,1) for (x,y,w,h) in faces: #Blacking out the face frame[y:y+h+50,x:x+w] = 0 return frame frame_wof = np.copy(frame) gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) # print(gray.shape) # Removing the face frame_wof = blackout(frame_wof,gray) #Converting the color scheme hsv = cv2.cvtColor(cv2.medianBlur(frame_wof,15),cv2.COLOR_BGR2HSV) lower = np.array([0, 10, 60]) #Lower range of HSV color upper = np.array([40, 165, 255]) #Upper range of HSV color #Creating the mask mask = cv2.inRange(hsv,lower,upper) #Removing noise form the mask mask = cv2.dilate(mask,None,iterations=2) #Extracting contours from the mask cnts,_ = cv2.findContours(mask.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) if len(cnts) > 0: for c in cnts: #To prevent the detection of the noise if cv2.contourArea(c) > 8000: #Fixing covex defect hull = cv2.convexHull(c) #Drawing the contours cv2.drawContours(frame,[hull],0,(0,0,255),2) #Creating the bounding rectangel x,y,w,h = cv2.boundingRect(hull) cv2.rectangle(frame,(x-10,y-10),(x+w+10,y+h+10),(0,255,0),2) #Showing the mask cv2.imshow("Image",frame) cv2.waitKey(0) cv2.imshow("Mask",mask) cv2.waitKey(0)
def find_max_contour(contours, img): maxArea = 0 maxIndex = 0 if len(contours) > 0: for i in range(len(contours)): curr = contours[i] area = cv2.contourArea(curr) if area > maxArea: maxArea = area maxIndex = i max_contour = contours[maxIndex] hull = cv2.convexHull(max_contour) drawing = np.zeros(img.shape, np.uint8) cv2.drawContours(drawing, [max_contour], 0, (0, 255, 0), 2) cv2.drawContours(drawing, [hull], 0, (0, 0, 255), 3) cnt = calculateFingers(max_contour, drawing, img) return cnt
def get_contour_corners(contours, corner_amt=4, max_iter=200): coeff = 1 while max_iter > 0 and coeff >= 0: max_iter = max_iter - 1 # Maximum distance from contour to approximated contour epsilon = coeff * cv2.arcLength(contours, True) # Approximation of a contour shape, True means curve is closed approx = cv2.approxPolyDP(contours, epsilon, True) # Checks curves for convexity defects hull = cv2.convexHull(approx) if len(hull) == corner_amt: return hull else: if len(hull) > corner_amt: coeff += .01 else: coeff -= .01 return None
def extract_contour(path_to_images): for image_path in glob.glob(os.path.join(path_to_images, '*.png')): image = cv2.imread(image_path) ret, thresh = cv2.threshold(image[:, :, 2], 251, 255, 0) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) vertices = [] for contour in contours: vertex = np.mean(contour, axis=0).astype(int) vertices.append(vertex) table_contour = np.array(vertices) table_contour = cv2.convexHull(table_contour) image_mask = create_segmentation_mask(image, table_contour) visualize(image, image_mask, table_contour) # save masks cv2.imwrite(image_path[:-4] + '_mask.png', image_mask)
def crop_for_small_intensive(img, ann, small_prop=0.5, max_objs=100): # 1 是否小目标数量超过50% areas = [] for obj in ann: # prepare for Polygon class input a = np.array(obj['segmentation'][0]).reshape(4, 2) # 注意坐标系与笛卡尔坐标系方向相反, # 所以clockwise=False表示为真实世界的顺时针输出凸包, a_hull = cv.convexHull(a.astype(np.float32), clockwise=False) areas.append(cv.contourArea(a_hull)) small_areas = [area for area in areas if area <= 32 * 32] if len(small_areas) > small_prop * len(areas): size = random.randint(200, 600) return sliding_crop(img, size, size, overlap=0.1) # 1 是否目标数量超过100 if len(ann) > max_objs: h, w, _ = img.shape size = random.randint(400, 800) if h < 1333 or w < 1333: size = 1333 return sliding_crop(img, size, size, overlap=0.1) return None
def calculateFingers(res, drawing): # count fingers and draw hull = cv2.convexHull( res, returnPoints=False) # find the convex hull, and get the angular point if len(hull) > 3: defects = cv2.convexityDefects(res, hull) # convexity defect if type(defects) != type(None): # avoid crashing 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)) # compute the angle of each hull side if angle <= math.pi / 2: # if angle less than 90 degree, treat as fingers and draw cnt += 1 cv2.circle(drawing, far, 8, [211, 84, 0], -1) return True, cnt return False, 0
def display(im, decodedObjects): # Loop over all decoded objects for decodedObject in decodedObjects: points = decodedObject.polygon # If the points do not form a quad, find convex hull if len(points) > 4: hull = cv2.convexHull( np.array([point for point in points], dtype=np.float32)) hull = list(map(tuple, np.squeeze(hull))) else: hull = points # Number of points in the convex hull n = len(hull) # Draw the convext hull for j in range(0, n): cv2.line(im, hull[j], hull[(j + 1) % n], (255, 0, 0), 3) # Display results cv2.imshow("Results", im) cv2.waitKey(0)