def wobbling_test(self, location): """ Test checking the wobbling shape of the tire. Return 0 or 1, 1 for defective. """ frame = cv2.imread(location) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(gray, 150, 200, 0) contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(frame, contours, -1, (0, 255, 0), 3) height = np.size(frame, 0) width = np.size(frame, 1) img_area = height * width i = 0 for contour in contours: if i > 0: area = cv2.contourArea(contour) img_area = area elif i > 1: area = cv2.contourArea(contour) img_area = img_area - area i = i + 1 height = np.size(frame, 0) width = np.size(frame, 1) if img_area > 60000 and img_area < 50000: flag = 0 else: flag = 1 return flag
def Find_Contour(img): ndefect_ls = [] MIN_AREA = 2000 #检测的轮廓的最小面积 depth = 3 contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) #当len为0时表示没有找到轮廓,当len大于60时表示受到的干扰过大 # #避免当contours为空时引发max函数错误而退出程序的情况 length = len(contours) if 0 < length <= 60: contours.sort(key=lambda x: cv2.contourArea(x), reverse=True) for i in range(depth): if length > i and cv2.contourArea(contours[i]) >= MIN_AREA: ndefect = ConvexHull_Cal(contours[i]) ndefect_ls.append(ndefect) else: break if ndefect_ls: index_list = [ ndefect_ls.index(x) for x in ndefect_ls if 0 < x <= 5 ] #去除算出凸包数为0和大于5的结果 if index_list: if len(index_list) >= 2: right_ls = [ndefect_ls[i] for i in index_list] m_index = ndefect_ls.index(max(right_ls)) elif len(index_list) == 1: m_index = index_list[0] return ndefect_ls[m_index], contours[m_index] return 0, 0
def zoom_number(image, cont): inverted_threshold = filter_squares(image) contours = contours_numbers(inverted_threshold) largest_area = 0 x = 0 y = 0 w = 0 h = 0 curve = 0 for i, c in enumerate(contours): xTemp, yTemp, wTemp, hTemp = cv2.boundingRect(c) if( cv2.contourArea(c) > largest_area and \ (hTemp < image.shape[0]*.9 and wTemp < image.shape[1]*.9)\ and hTemp > 10 and wTemp > 10): #limites definidos, numero no es menor a 10 ni debe largest_area = cv2.contourArea(c) # medir el 90% de la imagen curve = cv2.arcLength(c, True) x, y, w, h = cv2.boundingRect(c) # print("contourArea for",cont," is: ",curve,"image h:",image.shape[0],"image w:",image.shape[1]) # print("contour h:",h," and w: ",w) # cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2) if (curve != 0): top_left_point = (x, y) top_right_point = (x + w, y) bottom_left_point = (x, y + h) bottom_right_point = (x + w, y + h) corners = np.float32([ top_left_point, top_right_point, bottom_left_point, bottom_right_point ]) result = transform(image, corners, 50, 50) else: result = image return result
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 Find_Contour(img_list): depth = 3 convexHull = [] Hu_list = [] contour_ls = [] MIN_AREA = 2000 #检测的轮廓的最小面积 for img in img_list: contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) #当len为0时表示没有找到轮廓,当len大于60时表示受到的干扰过大 # #避免当contours为空时引发max函数错误而退出程序的情况 length = len(contours) if 0 < length <= 60: contours.sort(key=lambda x: cv2.contourArea(x), reverse=True) for i in range(depth): if length > i and cv2.contourArea(contours[i]) >= MIN_AREA: contour_ls.append(contours[i]) convexHull.append(ConvexHull_Cal(contours[i])) M = cv2.moments(contours[i]) Hu_list.append(cv2.HuMoments(M)) else: break if Hu_list: Hu_array = np.array(Hu_list) Hu_array = np.squeeze(Hu_array) return contour_ls, convexHull, Hu_array
def Find_Contour(img, sample_list, fourier_des_ls): def Similarity_cal(contour): descriptor = scfun.Fourier_Descriptor(contour[:, 0, :], Normalize=True) sim_cout = [ cv2.matchShapes(contour, sample, cv2.CONTOURS_MATCH_I1, 0) for sample in sample_list ] sim_four = [ scfun.Eucledian_Distance(descriptor, des) for des in fourier_des_ls ] return sim_cout, sim_four sign = False sign_2 = False sim_cout_0 = [] sim_four_0 = [] sim_cout_1 = [] sim_four_1 = [] contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) #当len为0时表示没有找到轮廓,当len大于60时表示受到的干扰过大 # #避免当contours为空时引发max函数错误而退出程序的情况 length = len(contours) if 0 < length <= 60: contours.sort(key=lambda x: cv2.contourArea(x), reverse=True) if cv2.contourArea(contours[0]) >= 3000: #检测物体的最小面积 sim_cout_0, sim_four_0 = Similarity_cal(contours[0]) if length >= 2 and cv2.contourArea(contours[1]) >= 3000: sign_2 = True sim_cout_1, sim_four_1 = Similarity_cal(contours[1]) sum_cout = sim_cout_0 + sim_cout_1 index_list = [sum_cout.index(x) for x in sum_cout if x <= 0.24] #相似度阈值 if index_list: if sign_2 and len(index_list) > 1: sum_four = scfun.Normalization(sim_four_0 + sim_four_1) result = [sum_cout[x] * sum_four[x] for x in index_list] min_index = index_list[result.index(min(result))] else: min_index = index_list[0] if sign_2 and min_index >= 5: large_cout = contours[1] else: large_cout = contours[0] sign = True return sign, large_cout return sign, 0
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 find_biggest_contour(image, contours, max_area=None, min_area=100 ** 2, max_border=(100, 100, 100, 100)): """ Get biggest area contour in list of contours @param image: image contours processed on @param contours: list of contours (from cv2.findContours()) @param max_area: Upper limit of contour area @param min_area: Lower limit of contour area @param max_border: Border around image where contour can exist @return: contour """ if max_area is None: max_area = max(image.shape) ** 2 ''' Contour searching algorithm ''' # find initial contour data # noinspection PyPep8Naming M = cv2.moments(contours[-1]) area = cv2.contourArea(contours[-1]) cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) image_x, image_y, _ = image.shape center_image_x, center_image_y = (image_x // 2, image_y // 2) best_area = area best_center = (cx, cy) best_contour = contours[-1] border_x_min = max_border[0] border_x_max = image_x + max_border[2] border_y_min = max_border[1] border_y_max = image_y + max_border[3] for i in range(len(contours)): # find area of contour area = cv2.contourArea(contours[i]) # find moments of contour # noinspection PyPep8Naming M = cv2.moments(contours[i]) # find center of mass of contour cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) center = (cx, cy) if min_area < area < max_area: if border_x_min < cx < border_x_max and border_y_min < cy < border_y_max: best_area = area best_center = center best_contour = contours[i] return best_contour
def getContour(img, imgContour): contour, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) global h for cnt in contour: area = cv2.contourArea(cnt) peri = cv2.arcLength(cnt, True) # True shows that the shape is closed approx = cv2.approxPolyDP(cnt, 0.02 * peri, True) area = cv2.contourArea(cnt) if 4 <= len(approx) <= 7 and area > area_min: cv2.drawContours(imgContour, cnt, -1, (255, 0, 255), 3) x, y, w, h = cv2.boundingRect(approx) cv2.rectangle( imgContour, (x, y), (x + w, y + h), (0, 255, 0), 3 ) # rectangle must match with the contour for knowing the standard in parallel
def getContour(img, imgContour): contour, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) found = False for cnt in contour: area = cv2.contourArea(cnt) peri = cv2.arcLength(cnt, True) # True shows that the shape is closed approx = cv2.approxPolyDP(cnt, 0.02 * peri, True) area = cv2.contourArea(cnt) if 4 <= len(approx) <= 7 and area > area_min: found = True cv2.drawContours(imgContour, cnt, -1, (255, 0, 255), 7) x, y, w, h = cv2.boundingRect(approx) cv2.rectangle(imgContour, (x, y), (x + w, y + h), (0, 255, 0), 5) return found
def searchRect(img, contours, e=0.02): max_area = 0 max_approx = 0 for cnt in contours: epsilon = e * cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, epsilon, True) if len(approx) == 4: print(f'{cv2.contourArea(cnt)}') if max_area < cv2.contourArea(cnt): max_approx = approx max_area = cv2.contourArea(cnt) return max_approx
def _preprocess(self, warped_img): ''' Preprocess the warped and rotated image. @warped_img: np.array, it should be the output of self._polar_warp_and_rotate(). @return: (s_mask, output_img), saturation mask and image after preprocessing. ''' warped_img = cv.GaussianBlur(warped_img, (3, 3), 1.5) hsv = cv.cvtColor(warped_img, cv.COLOR_BGR2HSV) warped_img = cv.cvtColor(warped_img, cv.COLOR_BGR2GRAY) warped_img = cv.equalizeHist(warped_img) # Enhance contrast _, s, _ = cv.split(hsv) _, s = cv.threshold(s, 0, 255, cv.THRESH_OTSU) s = cv.morphologyEx(s, cv.MORPH_ERODE, np.ones((5, 5))) _, contours, _ = cv.findContours(s, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) contours = sorted(contours, key=lambda ctr: cv.contourArea(ctr) ) # Sort to choose the largest area mask = cv.drawContours(np.zeros((warped_img.shape), np.uint8), contours, len(contours) - 1, (255, 255, 255), thickness=1) box = cv.boundingRect(get_points(mask)) # Largest area box-bouding mask = cv.rectangle(mask, (box[0], box[1]), (box[0] + box[2], box[1] + box[3]), (255, 255, 255), cv.FILLED) # Fill the area that is to be removed mask = cv.bitwise_not(mask) # Ensure tooth existing area return mask, warped_img
def getContours(img,cThr=[100,100],showCanny=False,minArea=1000,filter=0,draw =False): imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) imgBlur = cv2.GaussianBlur(imgGray,(5,5),1) imgCanny = cv2.Canny(imgBlur,cThr[0],cThr[1]) kernel = np.ones((5,5)) imgDial = cv2.dilate(imgCanny,kernel,iterations=3) imgThre = cv2.erode(imgDial,kernel,iterations=2) if showCanny:cv2.imshow('Canny',imgThre) contours,hiearchy = cv2.findContours(imgThre,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) finalCountours = [] for i in contours: area = cv2.contourArea(i) if area > minArea: peri = cv2.arcLength(i,True) approx = cv2.approxPolyDP(i,0.02*peri,True) bbox = cv2.boundingRect(approx) if filter > 0: if len(approx) == filter: finalCountours.append([len(approx),area,approx,bbox,i]) else: finalCountours.append([len(approx),area,approx,bbox,i]) finalCountours = sorted(finalCountours,key = lambda x:x[1] ,reverse= True) if draw: for con in finalCountours: cv2.drawContours(img,con[4],-1,(0,0,255),3) return img, finalCountours
def extract_section_coordinates_from_image(self, image, threshold_breakpoint): # Takes an raw image with a white bright background and looks for the contour of # a rectangular object and returns the coordinates representing a polygon shape of that object. # A threshold needs to be provided representing an acceptable breaking point at which the coordinates will be returned # The width of the border to wrap the image in case the object overflows the image BORDER_WIDTH = 100 image = cv2.copyMakeBorder(image, BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH, cv2.BORDER_CONSTANT, value=[255, 255, 255]) image_grayscale = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Calculate the image area image_height, image_width = image.shape[:2] image_area = image_height * image_width # Repeat to find the right threshold value for finding a rectangle found = False # Increment the threshold until a contour is found threshold_current = threshold_breakpoint while found is False: if threshold_breakpoint < 200: threshold_breakpoint = threshold_current + 5 threshold_current = threshold_breakpoint # Extract contours using threshold _, threshold = cv2.threshold(image_grayscale, threshold_breakpoint, 255, cv2.THRESH_BINARY) contours, _ = cv2.findContours(threshold, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) # Go through each contour that could be extracted from the image for contour in contours: contour_area = cv2.contourArea(contour) if contour_area > (image_area / 6) and contour_area < (image_area / 1.01): epsilon = 0.1 * cv2.arcLength(contour, True) # Close open lines into a complete wrapped shade approx = cv2.approxPolyDP(contour, epsilon, True) # When the shape can be wrapped the contour rectangle has been found if len(approx) == 4: found = True # Otherwise keep decrementing the threshold value until it's found else: threshold_breakpoint = threshold_breakpoint - 1 break # Set and return coordinates from approximate coordinates = numpy.empty((4, 2), dtype="float32") # Top-left coordinates[0] = approx[0] - BORDER_WIDTH # Top-right coordinates[1] = approx[1] - BORDER_WIDTH # Bottom-right coordinates[2] = approx[2] - BORDER_WIDTH # Bottom-left coordinates[3] = approx[3] - BORDER_WIDTH return coordinates
def detect_centrode(self,res): # Adapted from # https://stackoverflow.com/questions/54425093/ # /how-can-i-find-the-center-of-the-pattern-and-the-distribution-of-a-color-around) contours, hierarchy = cv2.findContours(res, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) areas = [] centersX = [] centersY = [] for cnt in contours: areas.append(cv2.contourArea(cnt)) M = cv2.moments(cnt) try: centersX.append(int(M["m10"] / M["m00"])) centersY.append(int(M["m01"] / M["m00"])) except ZeroDivisionError as error: # Output expected ZeroDivisionErrors. centersX.append(int(M["m10"])) centersY.append(int(M["m01"])) pass full_areas = np.sum(areas) acc_X = 0 acc_Y = 0 for i in range(len(areas)): acc_X += centersX[i] * (areas[i]/full_areas) acc_Y += centersY[i] * (areas[i]/full_areas) return acc_X,acc_Y, full_areas
def areaCal(contour): area = 0 for i in range(len(contour)): area += cv2.contourArea(contour[i]) return area
def detect_motion(self, frame, firstFrame): # find contours in the frame (changes from the firstFrame) contours = self.detect_contours(frame, firstFrame) motion = False # for each contour, check if it is larger than specified for c in contours: # contour too small, discard if cv2.contourArea(c) < 15000: continue # motion detected!!! motion = True # draw boundingRectangle (x, y, w, h) = cv2.boundingRect(c) # skip jitters fh, fw, _ = frame.shape if w == fw and h == fh: print("Grey out") continue cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) return motion
def Create_Hand_Sample_Contour(): #加载手部素材图 name_list = [ 'hand_one.png', 'hand_two.png', 'hand_three.png', 'hand_four.png', 'hand_five.png' ] hand_img_ls = [] for name in name_list: hand_img_ls.append(cv2.imread('images/' + name, 0)) #生成手部轮廓 contour_ls = [] fourdestor_ls = [] for hd in hand_img_ls: cout, _ = cv2.findContours(hd, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) max_cout = max(cout, key=lambda x: cv2.contourArea(x)) contour_ls.append(max_cout) descriptor = scfun.Fourier_Descriptor(max_cout[:, 0, :], Normalize=True) fourdestor_ls.append(descriptor) black2 = np.ones((480, 640), np.uint8) #创建黑色幕布 cv2.drawContours(black2, max_cout, -1, (255, 255, 255), 3) #绘制白色轮廓 cv2.imshow('black2', hand_img_ls[1]) cv2.waitKey(0) return contour_ls, fourdestor_ls
def detect( self, frame : numpy.ndarray ): # Convert to foreground mask, close gaps, remove noise. fg_mask = self.back_sub.apply( frame ) fg_mask = cv2.morphologyEx( fg_mask, cv2.MORPH_CLOSE, self.kernel ) fg_mask = cv2.medianBlur( fg_mask, self.blur ) # Flatten mask to B&W. ret, fg_mask = cv2.threshold( fg_mask, self.threshold, 255, cv2.THRESH_BINARY ) # Find object contours/areas. contours, hierarchy = cv2.findContours( fg_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE )[-2:] areas = [cv2.contourArea(c) for c in contours] if 0 < len( areas ): max_idx = numpy.argmax( areas ) cnt_iter = contours[max_idx] rect_x, rect_y, rect_w, rect_h = cv2.boundingRect( cnt_iter ) return self.handle_movement( frame, rect_x, rect_y, rect_w, rect_h ) return None
def getContours(img): contours, hierachy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) for cnt in contours: area = cv2.contourArea(cnt) #print('Area: ', area) if area > 500: # this check will confirm the area greater than threshold value to avoid noise cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 3) peri = cv2.arcLength(cnt, True) #print('Perimeter:', peri) approx = cv2.approxPolyDP(cnt, 0.02 * peri, True) print('Approximate Corners: ', len(approx)) objCorner = len(approx) x, y, w, h = cv2.boundingRect(approx) if objCorner == 3: objType = 'Triangle' elif objCorner == 4: aspRatio = w / float(h) if aspRatio > 0.95 and aspRatio < 1.05: objType = 'Square' else: objType = 'Rectangle' elif objCorner > 4: objType = 'Circle' else: objType = 'Other' cv2.rectangle(imgContour, (x, y), (x + w, y + h), (0, 255, 0), 2) cv2.putText(imgContour, objType, (x + (w // 2) - 10, y + (h // 2) - 10), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0, 0, 0), 2)
def drawContours(img_rgb, contours): for cnt in contours: area = cv.contourArea(cnt) print(f'area of contours: {area}') cv.drawContours(img_rgb, [cnt], 0, (255,0,0), 1) # cv.drawContours(img_rgb, contours, 0, (255,0,0), 2) return img_rgb
def getContours(img, img_rgb): contours, hierarchy = cv.findContours(img, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE) for cnt in contours: area = cv.contourArea(cnt) if area > 500: cv.drawContours(imgContour, cnt, -1, (255, 0, 0), 3) peri = cv.arcLength(cnt, True) approx = cv.approxPolyDP(cnt, 0.02*peri, True) cv.drawContours(img_rgb, [approx], 0, (255,0,0),5) cv.imshow('tmp', img_rgb) # cv.waitKey() objCor = len(approx) x, y, w, h = cv.boundingRect(approx) objectType = None if objCor == 4: objectType = "Rectangle" elif w == h: objectType = "Square" if objCor == 8: objectType = "Circle" if objectType: cv.rectangle(imgContour, (x, y), (x+w, y+h), (0, 255, 0), 2) cv.putText(imgContour, objectType, (x+(w//2)-10, y+(h//2)-10), cv.FONT_HERSHEY_COMPLEX, 0.7, (0, 0, 0), 2)
def contour(img): contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) for cnt in contours: area = cv2.contourArea(cnt) print(area) if area > 10: cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 3) peri = cv2.arcLength(cnt, True) print(peri) approx = cv2.approxPolyDP(cnt, 0.02 * peri, True) print(len(approx)) objCor = len(approx) x, y, w, h = cv2.boundingRect(approx) if objCor == 3: objectType = "Tri" elif objCor == 4: aspRatio = w / float(h) if aspRatio > 0.95 and aspRatio < 1.05: objectType = "Square" else: objectType = "Rectangle" elif objCor > 4: objectType = "Circle" else: objectType = "None" cv2.rectangle(imgContour, (x, y), (x + w, y + h), (0, 255, 0), 2) cv2.putText(imgContour, objectType, (x + (w // 2) - 10, y + (h // 2) - 10), cv2.FONT_HERSHEY_COMPLEX, 0.5, (10, 50, 20), 2)
def GetRightPos(image): # 边缘检测 canny = cv2.Canny(image, 200, 400) # 轮廓提取 img, contours, _ = cv2.findContours(canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) rightRectangles = [] for i, contour in enumerate(contours): M = cv2.moments(contour) if M['m00'] == 0: cx, cy = 0, 0 else: cx, cy = M['m10'] / M['m00'], M['m01'] / M['m00'] if 1000 < cv2.contourArea(contour) < 1300 and 120 < cv2.arcLength( contour, True) < 400: if cx > 100: x, y, w, h = cv2.boundingRect(contour) # 外接矩形 rightRectangles.append((x, y, w, h)) if len(rightRectangles) > 0: # 内侧方块 current = min(rightRectangles, key=lambda s: s[2] * s[3]) x, y, w, h = current[0], current[1], current[2], current[3] return x, y, w, h return 0, 0, 0, 0
def measure_object(image): gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) print("threshold value:%s" % ret) cv.imshow("binary image", binary) dst = cv.cvtColor(binary, cv.COLOR_GRAY2BGR) contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) for i, contour in enumerate(contours): area = cv.contourArea(contour) x, y, w, h = cv.boundingRect(contour) mm = cv.moments(contour) if mm['m00']: cx = mm['m10'] / mm['m00'] cy = mm['m01'] / mm['m00'] else: continue cv.circle(dst, (np.int(cx), np.int(cy)), 3, (0, 0, 255), -1) cv.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2) #绘制矩形边界 """ print("area",area) approxCurve = cv.approxPolyDP(contour,4,True)#多边形逼近 if approxCurve.shape[0] > 6:#边数大于6条的 cv.drawContours(dst,contours,i,(0,0,255),2) if approxCurve.shape[0] == 4:#矩形 cv.drawContours(dst,contours,i,(0,255,0),2) if approxCurve.shape[0] == 3:#三角形 cv.drawContours(dst,contours,i,(255,0,0),2) """ cv.imshow("image", dst) cv.imshow("souce", image)
def getCropMask(color, depth, hue): ''' 拿到掩模 ''' ### H-[65 98] S-[33 255] V-[117 255] ### ## 原 [30,100,40] ## [100,255,255] hsv = cv2.cvtColor(color, cv2.COLOR_BGR2HSV) lower_g = np.array([hue-20,33,30]) upper_g = np.array([hue+20,255,255]) mask = cv2.inRange(hsv, lower_g, upper_g) mask = cv2.medianBlur(mask, 5) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5)) mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) ''' 去除掩模小的连通域 ''' if(cv2.__version__[0] == '4'): contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) else: _, contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) boundaries = [] for con in contours: if(cv2.contourArea(con) > 1000): boundaries.append(con) cv2.drawContours(mask, [con], 0, 255, -1) else: cv2.drawContours(mask, [con], 0, 0, -1) ''' 将掩模与深度做与运算 ''' depth_bin = np.uint8(depth>0)*255 mask = cv2.bitwise_and(mask, depth_bin) return(mask)
def to_counters(self, _img=None): # # 检测轮廓 边缘分割 _img = _img if _img is not None else self.img # # 灰度和二值 _gray = cv2.cvtColor(_img, cv2.COLOR_BGR2GRAY) _, _binary = cv2.threshold(_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) # cv_show(_binary, "binary test") # # Canny边缘检测 # edges = cv2.Canny(_img, 50, 150, ) # cv_show(edges) # # 轮廓检测, 画出轮廓 _contours, _ = cv2.findContours(_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) _draw_img = _img.copy() # # 计算轮廓的大小, 选定阈值 对轮廓进行选择 _greatest_contour_idx = np.argmax([cv2.contourArea(_contour) for _contour in _contours]) # # 求轮廓的外接矩形 _greatest_contour = _contours[_greatest_contour_idx] _x, _y, _w, _h = cv2.boundingRect(_greatest_contour) _ret = cv2.rectangle(_img, (_x, _y), (_x + _w, _y + _h), color=(0, 255, 255), thickness=1) # # 上下 _ret[0: _y, :] = (0, 0, 0) _ret[_y + _h: -1, :] = (0, 0, 0) # # 左右 _ret[:, 0: _x] = (0, 0, 0) _ret[:, _x + _w: -1] = (0, 0, 0) # _ret = cv2.drawContours(_draw_img, _contours, _greatest_contour_idx, (255, 0, 255), 2) cv_show(_ret)
def find_sudoku(image): # preprocessing gray_sudoku = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blurred_sudoku = cv2.GaussianBlur(gray_sudoku, (7, 7), 0) thresh = cv2.adaptiveThreshold(blurred_sudoku, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # find contours contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # get the sudoku contour sudoku_area = 0 sudoku_contour = contours[0] for cnt in contours: area = cv2.contourArea(cnt) x, y, w, h = cv2.boundingRect(cnt) if (0.7 < float(w) / h < 1.3 # aspect ratio and area > 150 * 150 # minimal area and area > sudoku_area # biggest area on screen and area > .5 * w * h): # fills bounding rect sudoku_area = area sudoku_contour = cnt perimeter = cv2.arcLength(sudoku_contour, True) # define the accuracy here epsilon = 0.05 * perimeter approx = cv2.approxPolyDP(sudoku_contour, epsilon, True) # if it is not a sudoku board, just return the frame without doing anything if len(approx) != 4: return None return sudoku_contour
def red_detect(frame): # オレンジ色を検出し、画像加工を施す。 hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) lower = (0, 230, 150) upper = (30, 255, 255) red = cv2.inRange(hsv, lower, upper) kernal = np.ones((5, 5), "uint8") red = cv2.dilate(red, kernal) res = cv2.bitwise_and(frame, frame, mask=red) (ret, contours, hierarchy) = cv2.findContours( red, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) x = 0 y = 0 w = 0 h = 0 for pic, contour in enumerate(contours): area = cv2.contourArea(contour) if (area > 100): x, y, w, h = cv2.boundingRect(contour) frame = cv2.rectangle( frame, (x, y), (x + w, y + h), (0, 0, 255), 2) cv2.putText(frame, "RED color", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255)) cv2.drawMarker(frame, (480, 350), (255, 255, 0), markerType=cv2.MARKER_SQUARE, markerSize=5, thickness=10) cv2.drawMarker(frame, ((x + w//2), (y + h//2)), (255, 255, 0), markerType=cv2.MARKER_SQUARE, markerSize=5, thickness=10) cv2.arrowedLine(frame, (480, 350), ((x + w//2), (y + h//2)), (255, 0, 0), 5) cv2.rectangle(frame, (330, 200), (630, 500), (0, 255, 0), 1) return frame, x, y, w, h # 動画データとピクセル(x,y,z,h)を返す
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