def component_detection(msk, prev, area_min=None, visualize=False): # Extract connected components comp = cv2.connectedComponentsWithStatsWithAlgorithm( msk, 8, cv2.CV_16U, cv2.CCL_DEFAULT) if comp[0] > 1: # if there are some component + BG # Search for the biggest component (except BG) if area_min is not None: # Filterby minimal area c = comp[2][1:, -1] c[c < area_min] = 0 if c.max() == 0: return (0, 0, -1, 0) else: bigger_comp = np.argmax(c, axis=-1) # Avoid BG else: bigger_comp = np.argmax(comp[2][1:, -1], axis=-1) # Avoid BG msk[comp[1] != (bigger_comp + 1)] = 0 (x, y) = comp[-1][bigger_comp + 1] area = comp[2][1:, -1][bigger_comp] (x_grade_cam, y_grade_cam) = angles_camera(x, y) x_grade_fw = angle_frontwheels(x_grade_cam, prev) if visualize: # only for debug msk = cv2.rectangle(msk, (int(x) - 5, int(y) - 5), (int(x) + 5, int(y) + 5), (255, 255, 255), -1) cv2.imwrite( './images/X_{}_{}-Y_{}_{}-Area_{}.png'.format( x_grade_cam, x, y_grade_cam, y, area), msk) return (x_grade_cam, y_grade_cam, area, x_grade_fw) else: return (0, 0, -1, 0)
def detecterbord(img, minp=850): #une image niveau de gris que je mets en tresh _, imseuil = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) #une ouverture de l'image seuillee pour reduire les possibilites noyeau = np.ones((3, 3), np.uint8) resultat = cv2.morphologyEx(imseuil, cv2.MORPH_OPEN, noyeau) #On cherche les composants connexes retval, labels, stats, centroids = cv2.connectedComponentsWithStatsWithAlgorithm( resultat, 4, cv2.CV_32S, cv2.CCL_WU) #minp peu varier(de 50) en fonction du nombre de contour trouvé(une amelioration) pliste = [] for i in range(1, retval): #On sait que les carrés du bord sont remplis en pixels(etudier le retour de stats) if (stats[i, 4] > minp): if (stats[i, 2] in range(20, 50) and stats[i, 3] in range(20, 50)): tr = (stats[i, 0] + stats[i, 2], stats[i, 1]) pliste.append(tr) nb = 0 #pour eviter la boucle en montant et en descandant,on fixe à 7(arbitraire) # le max d'iterration while nb < 7: if (len(pliste) == 5): break #ici on veut garantir que avant de sortir on # s'en sort avec des points eleves(c'est mieux que bas) if (nb == 6): nb += 1 minp -= 100 elif (len(pliste) < 5): #on diminue minp minp -= 100 nb += 1 elif (len(pliste) > 5): #on augmente minp minp += 100 nb += 1 #On refait le traitement (c'est nécessaire pour avoir les 5 carrés pour la rotation) pliste = [] for i in range(1, retval): if (stats[i, 2] in range(20, 50) and stats[i, 3] in range(20, 50)): if (stats[i, 4] > minp): tr = (stats[i, 0] + stats[i, 2], stats[i, 1]) pliste.append(tr) return pliste
def calculate_cropped_component_average(img): ccs = cv2.connectedComponentsWithStatsWithAlgorithm( img, 4, cv2.CV_32S, cv2.CCL_GRANA) cc_number = ccs[0] - 1 cc_stats = ccs[2] a_sum, w_sum, h_sum = 0, 0, 0 for i in range(len(cc_stats)): if i == 0: continue a_sum = a_sum + cc_stats[i][cv2.CC_STAT_AREA] w_sum = w_sum + cc_stats[i][cv2.CC_STAT_WIDTH] h_sum = h_sum + cc_stats[i][cv2.CC_STAT_HEIGHT] a_avg = a_sum / cc_number h_avg = h_sum / cc_number w_avg = w_sum / cc_number return a_avg, h_avg, w_avg
def connected_components_segmentation(intermediate_global_mask): """ :param intermediate_global_mask: black and white image :return: components """ _, labeled_img = cv2.connectedComponentsWithAlgorithm( intermediate_global_mask, 8, cv2.CV_32S, cv2.CCL_GRANA) labels = np.unique(labeled_img) labels = labels[labels != 0] components = [] for label in labels: mask = np.zeros_like(labeled_img, dtype=np.uint8) mask[labeled_img == label] = 255 # Compute the convex hull if get_opencv_major_version(cv2.__version__) in ['2', '3']: mask, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) else: contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) hull = [] for cnt in contours: hull.append(cv2.convexHull(cnt, False)) hull_mask = np.zeros((mask.shape[0], mask.shape[1]), dtype=np.uint8) for i in range(len(contours)): hull_mask = cv2.drawContours(hull_mask, hull, i, 255, -1, 8) single_component, flag = draw_border_for_picture_parts(hull_mask) _, connected_component, stats, _ = cv2.connectedComponentsWithStatsWithAlgorithm( single_component, 8, cv2.CV_32S, cv2.CCL_GRANA) valid_labels = np.argwhere( stats[:, cv2.CC_STAT_AREA] >= LABEL_AREA_THRESHOLD) if valid_labels[0] == 0: valid_labels = valid_labels[1:] for valid_label in valid_labels: component = Component(valid_label, connected_component, stats[valid_label], flag) components.append(component) components.sort(key=lambda x: x.area, reverse=True) return components
def image_segmentation_with_stats(img): """ """ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, ksize=(5, 5), sigmaX=10) gray = cv2.bilateralFilter(gray, d=7, sigmaColor=75, sigmaSpace=75) gray = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, (7, 7), iterations=2) gray = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 13, 3) # 11,2 at the beginning cv2.imshow("Thresh", gray) # gray = erosion_dilation(gray) num_labels, labeled_img, stats, centroids = cv2.connectedComponentsWithStatsWithAlgorithm( gray, connectivity=8, ltype=cv2.CV_32S, ccltype=cv2.CCL_GRANA) return labeled_img, stats
def post0(path): imwr = cv2.imread('./nivel0/' + path, 0) imwr = 255 - imwr output = cv2.connectedComponentsWithStatsWithAlgorithm( imwr, 4, ltype=cv2.CV_16U, ccltype=cv2.CCL_DEFAULT) num_labels = output[0] labels = output[1] stats = output[2] centroids = output[3] length = len(imwr) height = len(imwr[0]) area = length * height dispose = list() #Se recorren borde superior e inferior for num in range(length): if labels[num, 0] != 0: if stats[labels[num, 0], cv2.CC_STAT_AREA] < area * 0.1: dispose.append(labels[num, 0]) elif labels[num, height - 1] != 0: if stats[labels[num, height - 1], cv2.CC_STAT_AREA] < area * 0.1: dispose.append(labels[num, height - 1]) for num in range(height): if labels[0, num] != 0: if stats[labels[0, num], cv2.CC_STAT_AREA] < area * 0.1: dispose.append(labels[0, num]) elif labels[length - 1, num] != 0: if stats[labels[length - 1, num], cv2.CC_STAT_AREA] < area * 0.1: dispose.append(labels[length - 1, num]) dispose = set(dispose) tmp = imwr print(dispose) for v in range(length): for b in range(height): if labels[v, b] in dispose: tmp[v, b] = 0 tmp = 255 - tmp cv2.imshow("image", tmp) cv2.waitKey(0)
def get_bounding_boxes(original_frame, edge_detection_image): """ Given an image it looks for the paintings and returns a list of bounding boxes. Each Bounding Boxes contains four points: upper_left, upper_right, down_left, down_right :param original_frame: ndarray (H, W, C) :param edge_detection_image: ndarray (H, W) :return: list of bounding boxes """ list_bounding_boxes = [] padding_image = cv2.copyMakeBorder(edge_detection_image, 1, 1, 1, 1, cv2.BORDER_CONSTANT, None, 0) ret_val, labels, stats, centroids = cv2.connectedComponentsWithStatsWithAlgorithm(padding_image, connectivity=8, ltype=cv2.CV_16U, ccltype=cv2.CCL_GRANA) # Remove more small num_paintings = 1 for num_label in range(1, stats.shape[0]): if stats[num_label, cv2.CC_STAT_AREA] < np.mean(stats[1:, cv2.CC_STAT_AREA]): labels[labels == num_label] = 0 else: labels[labels == num_label] = num_paintings num_paintings += 1 for num_label in range(1, num_paintings): # Label equals zero is the background label_image = (labels == num_label) * 255 label_image = label_image.astype('uint8') contours, hierarchy = cv2.findContours(label_image, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE) cv2.drawContours(label_image, contours, -1, color=(0, 0, 0), thickness=10) sorted_approx = find_paintings(contours[0]) if sorted_approx is not None and not (0, 0) in sorted_approx: # upper_left, upper_right, lower_left, lower_right = sorted_approx # upper_width = abs(upper_right[1] - upper_left[1]) # lower_width = abs(lower_right[1] - lower_left[1]) # right_height = abs(lower_left[0] - upper_left[0]) # left_height = abs(lower_right[0] - upper_right[0]) # print(upper_width, lower_width, right_height, left_height) list_bounding_boxes.append(sorted_approx) return list_bounding_boxes
def get_same_patches(img, thresh): patch_size = 70 epsilon = 0.0001 ccs = cv2.connectedComponentsWithStatsWithAlgorithm( thresh, 4, cv2.CV_32S, cv2.CCL_GRANA) cc_number = ccs[0] cc_labels = ccs[1] cc_stats = ccs[2] i_x, i_y = 0, 0 x_margin, y_margin = 5, 5 while True: p1_pos = [ np.random.randint( 2 * x_margin + (i_x + 1) * patch_size, img.shape[1] - (i_x + 2) * patch_size - 2 * x_margin), np.random.randint( (i_y + 1) * patch_size + 2 * y_margin, img.shape[0] - (i_y + 2) * patch_size - 2 * y_margin) ] p2_pos = [ np.random.randint( 2 * x_margin + (i_x + 1) * patch_size, img.shape[1] - (i_x + 2) * patch_size - 2 * x_margin), np.random.randint( (i_y + 1) * patch_size + 2 * y_margin, img.shape[0] - (i_y + 2) * patch_size - 2 * y_margin) ] p1 = img[p1_pos[1]:p1_pos[1] + patch_size, p1_pos[0]:p1_pos[0] + patch_size] p1_thresh = thresh[p1_pos[1]:p1_pos[1] + patch_size, p1_pos[0]:p1_pos[0] + patch_size] p2 = img[p2_pos[1]:p2_pos[1] + patch_size, p2_pos[0]:p2_pos[0] + patch_size] p2_thresh = thresh[p2_pos[1]:p2_pos[1] + patch_size, p2_pos[0]:p2_pos[0] + patch_size] if cv2.countNonZero(p1_thresh) < 10 or cv2.countNonZero( p2_thresh) < 10: continue a1, h1, w1 = calculate_cropped_component_average(p1_thresh) a2, h2, w2 = calculate_cropped_component_average(p2_thresh) a1, a2, w1, w2, h1, h2 = a1 + epsilon, a2 + epsilon, w1 + epsilon, w2 + epsilon, h1 + epsilon, h2 + epsilon if min(a1, a2) / max(a1, a2) > 0.7: # todo: improve on this condition label = 0 break else: continue if SHOW_RESULTS: global counter disp_img = cv2.cvtColor(thresh.copy(), cv2.COLOR_GRAY2BGR) for cc_i in range(1, cc_number): x, y, w, h = cc_stats[cc_i][cv2.CC_STAT_LEFT], cc_stats[cc_i][ cv2.CC_STAT_TOP], cc_stats[cc_i][ cv2.CC_STAT_WIDTH], cc_stats[cc_i][cv2.CC_STAT_HEIGHT] cv2.rectangle(disp_img, (int(x), int(y)), (int(x + w), int(y + h)), (60, 200, 200), 1, lineType=cv2.LINE_AA) cv2.rectangle( disp_img, (int(p1_pos[0]), int(p1_pos[1])), (int(p1_pos[0] + patch_size), int(p1_pos[1] + patch_size)), (255, 0, 0), 5, lineType=cv2.LINE_AA) cv2.rectangle( disp_img, (int(p2_pos[0]), int(p2_pos[1])), (int(p2_pos[0] + patch_size), int(p2_pos[1] + patch_size)), (0, 0, 255), 5, lineType=cv2.LINE_AA) cv2.imwrite( 'sample_pairs/' + str(counter) + 'page' + str(label) + '.png', disp_img) cv2.imwrite( 'sample_pairs/' + str(counter) + 'firstpair' + str(label) + '.png', p1) cv2.imwrite( 'sample_pairs/' + str(counter) + 'secondpair' + str(label) + '.png', p2) counter = counter + 1 return p1, p2, label
sys.exit('Image file do not exist') model_path = sys.argv[2] try: mean, std = int(sys.argv[3]), int(sys.argv[4]) except: sys.exit('Mean and std must be Integers') if image is None: sys.exit('Image file do not exist') image = cv2.copyMakeBorder(image, 14, 14, 14, 14, cv2.BORDER_CONSTANT, None, 0) # Find connected components etval, labels, stats, centroid = \ cv2.connectedComponentsWithStatsWithAlgorithm(image, 4, cv2.CV_16U, cv2.CCL_WU) # If find less then 4 digits - print that nComponents = labels.max() #if nComponents < 4: #print("Numbers in " + sys.argv[1] + " are too close, program will not find all digits") model_param = [] # for plotting result of testing models # Download model model = LeNetBN() try: model.load_state_dict( torch.load(model_path, map_location=torch.device('cpu'))) except: sys.exit('Model file do not exist')