Python cv2.connectedComponentsWithStats() Examples
The following are 15
code examples of cv2.connectedComponentsWithStats().
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
You may also want to check out all available functions/classes of the module
cv2
, or try the search function
.
Example #1
Source File: filter.py From Walk-Assistant with GNU General Public License v3.0 | 8 votes |
def remove_small_objects(img, min_size=150): # find all your connected components (white blobs in your image) nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(img, connectivity=8) # connectedComponentswithStats yields every seperated component with information on each of them, such as size # the following part is just taking out the background which is also considered a component, but most of the time we don't want that. sizes = stats[1:, -1] nb_components = nb_components - 1 # your answer image img2 = img # for every component in the image, you keep it only if it's above min_size for i in range(0, nb_components): if sizes[i] < min_size: img2[output == i + 1] = 0 return img2
Example #2
Source File: main.py From Traffic-Sign-Detection with MIT License | 5 votes |
def removeSmallComponents(image, threshold): #find all your connected components (white blobs in your image) nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(image, connectivity=8) sizes = stats[1:, -1]; nb_components = nb_components - 1 img2 = np.zeros((output.shape),dtype = np.uint8) #for every component in the image, you keep it only if it's above threshold for i in range(0, nb_components): if sizes[i] >= threshold: img2[output == i + 1] = 255 return img2
Example #3
Source File: lanenet_postprocess.py From lanenet-lane-detection with Apache License 2.0 | 4 votes |
def _connect_components_analysis(image): """ connect components analysis to remove the small components :param image: :return: """ if len(image.shape) == 3: gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) else: gray_image = image return cv2.connectedComponentsWithStats(gray_image, connectivity=8, ltype=cv2.CV_32S)
Example #4
Source File: utility.py From hmd with MIT License | 4 votes |
def refine_sil(sil, min_pixel): if len(sil.shape)==3: sil = sil[:,:,0] c3 = True else: c3 = False sil[sil>0] = 255 nb_components, output, stats, centroids = \ cv2.connectedComponentsWithStats(sil, connectivity = 8) sizes = stats[1:, -1]; nb_components = nb_components - 1 refined_sil = np.zeros((output.shape)) #for every component in the image, you keep it only if it's above min_size for i in range(0, nb_components): if sizes[i] >= min_pixel: refined_sil[output == i + 1] = 255 if c3 is True: refined_sil = np.stack((refined_sil,)*3, -1) return refined_sil # subdivide mesh to 4 times faces
Example #5
Source File: plant_features.py From bonnet with GNU General Public License v3.0 | 4 votes |
def thresh(img, conservative=0, min_blob_size=50): ''' Get threshold to make mask using the otsus method, and apply a correction passed in conservative (-100;100) as a percentage of th. ''' # blur and get level using otsus blur = cv2.GaussianBlur(img, (13, 13), 0) level, _ = cv2.threshold( blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_TRIANGLE) # print("Otsus Level: ",level) # change with conservative level += conservative / 100.0 * level # check boundaries level = 255 if level > 255 else level level = 0 if level < 0 else level # mask image _, mask = cv2.threshold(blur, level, 255, cv2.THRESH_BINARY) # morph operators kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) # remove small connected blobs # find connected components n_components, output, stats, centroids = cv2.connectedComponentsWithStats( mask, connectivity=8) # remove background class sizes = stats[1:, -1] n_components = n_components - 1 # remove blobs mask_clean = np.zeros((output.shape)) # for every component in the image, keep it only if it's above min_blob_size for i in range(0, n_components): if sizes[i] >= min_blob_size: mask_clean[output == i + 1] = 255 return mask_clean
Example #6
Source File: craft_utils.py From CRAFT-pytorch with MIT License | 4 votes |
def getDetBoxes_core(textmap, linkmap, text_threshold, link_threshold, low_text): # prepare data linkmap = linkmap.copy() textmap = textmap.copy() img_h, img_w = textmap.shape """ labeling method """ ret, text_score = cv2.threshold(textmap, low_text, 1, 0) ret, link_score = cv2.threshold(linkmap, link_threshold, 1, 0) text_score_comb = np.clip(text_score + link_score, 0, 1) nLabels, labels, stats, centroids = cv2.connectedComponentsWithStats(text_score_comb.astype(np.uint8), connectivity=4) det = [] mapper = [] for k in range(1,nLabels): # size filtering size = stats[k, cv2.CC_STAT_AREA] if size < 10: continue # thresholding if np.max(textmap[labels==k]) < text_threshold: continue # make segmentation map segmap = np.zeros(textmap.shape, dtype=np.uint8) segmap[labels==k] = 255 segmap[np.logical_and(link_score==1, text_score==0)] = 0 # remove link area x, y = stats[k, cv2.CC_STAT_LEFT], stats[k, cv2.CC_STAT_TOP] w, h = stats[k, cv2.CC_STAT_WIDTH], stats[k, cv2.CC_STAT_HEIGHT] niter = int(math.sqrt(size * min(w, h) / (w * h)) * 2) sx, ex, sy, ey = x - niter, x + w + niter + 1, y - niter, y + h + niter + 1 # boundary check if sx < 0 : sx = 0 if sy < 0 : sy = 0 if ex >= img_w: ex = img_w if ey >= img_h: ey = img_h kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(1 + niter, 1 + niter)) segmap[sy:ey, sx:ex] = cv2.dilate(segmap[sy:ey, sx:ex], kernel) # make box np_contours = np.roll(np.array(np.where(segmap!=0)),1,axis=0).transpose().reshape(-1,2) rectangle = cv2.minAreaRect(np_contours) box = cv2.boxPoints(rectangle) # align diamond-shape w, h = np.linalg.norm(box[0] - box[1]), np.linalg.norm(box[1] - box[2]) box_ratio = max(w, h) / (min(w, h) + 1e-5) if abs(1 - box_ratio) <= 0.1: l, r = min(np_contours[:,0]), max(np_contours[:,0]) t, b = min(np_contours[:,1]), max(np_contours[:,1]) box = np.array([[l, t], [r, t], [r, b], [l, b]], dtype=np.float32) # make clock-wise order startidx = box.sum(axis=1).argmin() box = np.roll(box, 4-startidx, 0) box = np.array(box) det.append(box) mapper.append(k) return det, labels, mapper
Example #7
Source File: tools.py From ICPR_TextDection with GNU General Public License v3.0 | 4 votes |
def find_connected(score_map, threshold=0.7): binary_map = (score_map > threshold).astype(np.uint8) connectivity = 8 output = cv2.connectedComponentsWithStats(binary_map, connectivity=connectivity, ltype=cv2.CV_32S) label_map = output[1] # show_image(np.asarray(label_map * 100.0, np.uint8)) return np.max(label_map), label_map
Example #8
Source File: lanenet_postprocess.py From lanenet-enet-hnet with Apache License 2.0 | 4 votes |
def _connect_components_analysis(image): """ :param image: :return: """ if len(image.shape) == 3: gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) else: gray_image = image return cv2.connectedComponentsWithStats(gray_image, connectivity=8, ltype=cv2.CV_32S)
Example #9
Source File: visualizer.py From detectron2 with Apache License 2.0 | 4 votes |
def draw_binary_mask( self, binary_mask, color=None, *, edge_color=None, text=None, alpha=0.5, area_threshold=0 ): """ Args: binary_mask (ndarray): numpy array of shape (H, W), where H is the image height and W is the image width. Each value in the array is either a 0 or 1 value of uint8 type. color: color of the mask. Refer to `matplotlib.colors` for a full list of formats that are accepted. If None, will pick a random color. edge_color: color of the polygon edges. Refer to `matplotlib.colors` for a full list of formats that are accepted. text (str): if None, will be drawn in the object's center of mass. alpha (float): blending efficient. Smaller values lead to more transparent masks. area_threshold (float): a connected component small than this will not be shown. Returns: output (VisImage): image object with mask drawn. """ if color is None: color = random_color(rgb=True, maximum=1) color = mplc.to_rgb(color) has_valid_segment = False binary_mask = binary_mask.astype("uint8") # opencv needs uint8 mask = GenericMask(binary_mask, self.output.height, self.output.width) shape2d = (binary_mask.shape[0], binary_mask.shape[1]) if not mask.has_holes: # draw polygons for regular masks for segment in mask.polygons: area = mask_util.area(mask_util.frPyObjects([segment], shape2d[0], shape2d[1])) if area < (area_threshold or 0): continue has_valid_segment = True segment = segment.reshape(-1, 2) self.draw_polygon(segment, color=color, edge_color=edge_color, alpha=alpha) else: rgba = np.zeros(shape2d + (4,), dtype="float32") rgba[:, :, :3] = color rgba[:, :, 3] = (mask.mask == 1).astype("float32") * alpha has_valid_segment = True self.output.ax.imshow(rgba) if text is not None and has_valid_segment: # TODO sometimes drawn on wrong objects. the heuristics here can improve. lighter_color = self._change_color_brightness(color, brightness_factor=0.7) _num_cc, cc_labels, stats, centroids = cv2.connectedComponentsWithStats(binary_mask, 8) largest_component_id = np.argmax(stats[1:, -1]) + 1 # draw text on the largest component, as well as other very large components. for cid in range(1, _num_cc): if cid == largest_component_id or stats[cid, -1] > _LARGE_MASK_AREA_THRESH: # median is more stable than centroid # center = centroids[largest_component_id] center = np.median((cc_labels == cid).nonzero(), axis=1)[::-1] self.draw_text(text, center, color=lighter_color) return self.output
Example #10
Source File: visualizer.py From detectron2 with Apache License 2.0 | 4 votes |
def draw_binary_mask( self, binary_mask, color=None, *, edge_color=None, text=None, alpha=0.5, area_threshold=4096 ): """ Args: binary_mask (ndarray): numpy array of shape (H, W), where H is the image height and W is the image width. Each value in the array is either a 0 or 1 value of uint8 type. color: color of the mask. Refer to `matplotlib.colors` for a full list of formats that are accepted. If None, will pick a random color. edge_color: color of the polygon edges. Refer to `matplotlib.colors` for a full list of formats that are accepted. text (str): if None, will be drawn in the object's center of mass. alpha (float): blending efficient. Smaller values lead to more transparent masks. area_threshold (float): a connected component small than this will not be shown. Returns: output (VisImage): image object with mask drawn. """ if color is None: color = random_color(rgb=True, maximum=1) if area_threshold is None: area_threshold = 4096 has_valid_segment = False binary_mask = binary_mask.astype("uint8") # opencv needs uint8 mask = GenericMask(binary_mask, self.output.height, self.output.width) shape2d = (binary_mask.shape[0], binary_mask.shape[1]) if not mask.has_holes: # draw polygons for regular masks for segment in mask.polygons: area = mask_util.area(mask_util.frPyObjects([segment], shape2d[0], shape2d[1])) if area < area_threshold: continue has_valid_segment = True segment = segment.reshape(-1, 2) self.draw_polygon(segment, color=color, edge_color=edge_color, alpha=alpha) else: rgba = np.zeros(shape2d + (4,), dtype="float32") rgba[:, :, :3] = color rgba[:, :, 3] = (mask.mask == 1).astype("float32") * alpha has_valid_segment = True self.output.ax.imshow(rgba) if text is not None and has_valid_segment: # TODO sometimes drawn on wrong objects. the heuristics here can improve. lighter_color = self._change_color_brightness(color, brightness_factor=0.7) _num_cc, cc_labels, stats, centroids = cv2.connectedComponentsWithStats(binary_mask, 8) largest_component_id = np.argmax(stats[1:, -1]) + 1 # draw text on the largest component, as well as other very large components. for cid in range(1, _num_cc): if cid == largest_component_id or stats[cid, -1] > _LARGE_MASK_AREA_THRESH: # median is more stable than centroid # center = centroids[largest_component_id] center = np.median((cc_labels == cid).nonzero(), axis=1)[::-1] self.draw_text(text, center, color=lighter_color) return self.output
Example #11
Source File: mask_morphology.py From NucleiDetectron with Apache License 2.0 | 4 votes |
def split_mask_erode_dilate(mask, kernel=k_3x3, k=3): img_erosion = cv.erode(mask, kernel, iterations=k) output = cv.connectedComponentsWithStats(img_erosion, 4, cv.CV_32S) if output[0] < 2: return [mask], output[1] else: masks_res = [] for idx in range(1, output[0]): res_m = (output[1] == idx).astype(np.uint8) res_m = cv.dilate(res_m, kernel, iterations=k) if res_m.sum() > 5: masks_res.append(res_m) return masks_res, output[1]
Example #12
Source File: image_resize.py From kaggle-dsb2018 with Apache License 2.0 | 4 votes |
def get_mean_cell_size(mask_contours): nuclei_sizes = [] for mask_contour in mask_contours: mask = mask_contour[:,:,0] contour = mask_contour[:,:,1] new_mask = (mask*255).astype(np.uint8) new_contour = (contour*255).astype(np.uint8) true_foreground = cv2.subtract(new_mask, new_contour) output = cv2.connectedComponentsWithStats(true_foreground) nuclei_sizes.append(np.mean(output[2][1:,cv2.CC_STAT_AREA])) return nuclei_sizes
Example #13
Source File: abstract_net.py From bonnet with GNU General Public License v3.0 | 3 votes |
def obj_histogram(self, mask, label): # holders for predicted object and right object (easily calculate histogram) predicted = [] labeled = [] # get connected components in label for each class for i in range(self.num_classes): # get binary image for this class bin_lbl = np.zeros(label.shape) bin_lbl[label == i] = 1 bin_lbl[label != i] = 0 # util.im_gray_plt(bin_lbl,'class '+str(i)) connectivity = 4 output = cv2.connectedComponentsWithStats( bin_lbl.astype(np.uint8), connectivity, cv2.CV_32S) num_components = output[0] components = output[1] stats = output[2] centroids = output[3] for j in range(1, num_components): # 0 is background (useless) # only process if it has more than 50pix if stats[j][cv2.CC_STAT_AREA] > 50: # for each component in each class, see the class with the highest percentage of pixels # make mask with just this component of this class comp_mask = np.zeros(label.shape) comp_mask[components == j] = 0 comp_mask[components != j] = 1 # mask the prediction masked_prediction = np.ma.masked_array(mask, mask=comp_mask) # get histogram and get the argmax that is not zero class_hist, _ = np.histogram(masked_prediction.compressed(), bins=self.num_classes, range=[0, self.num_classes]) max_class = np.argmax(class_hist) # print("\nMax class: ",max_class," real: ",i) # util.im_gray_plt(comp_mask) # util.im_block() # sum an entry to the containers depending on right or wrong predicted.append(max_class) labeled.append(i) # for idx in range(len(predicted)): # print(predicted[idx],labeled[idx]) # histogram to count right and wrong objects histrange = np.array([[-0.5, self.num_classes - 0.5], [-0.5, self.num_classes - 0.5]], dtype='float64') h_now, _, _ = np.histogram2d(np.array(predicted), np.array(labeled), bins=self.num_classes, range=histrange) return h_now
Example #14
Source File: image_processing.py From kaggle-dsb2018 with Apache License 2.0 | 3 votes |
def post_process_image(image, mask, contour): """ Watershed on the markers generated on the sure foreground to find all disconnected objects The (mask - contour) is the true foreground. We set the contour to be unknown area. Index of contour = -1 Index of unkown area = 0 Index of background = 1 -> set back to 0 after watershed Index of found objects > 1 """ kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)) new_contour = (contour*255).astype(np.uint8) new_mask = (mask*255).astype(np.uint8) new_mask = cv2.morphologyEx(new_mask, cv2.MORPH_OPEN, kernel, iterations=1) _, thresh_mask = cv2.threshold(new_mask,0,255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) _, thresh_contour = cv2.threshold(new_contour,0,255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) sure_background = cv2.dilate(thresh_mask,kernel,iterations=3) sure_foreground = cv2.subtract(thresh_mask, thresh_contour) mask_plus_contour = cv2.add(thresh_mask, thresh_contour) mask_plus_contour = cv2.cvtColor(mask_plus_contour, cv2.COLOR_GRAY2RGB) unknown = cv2.subtract(sure_background, sure_foreground) # Marker labelling output = cv2.connectedComponentsWithStats(sure_foreground) labels = output[1] stats = output[2] # Add one to all labels so that sure background is not 0, 0 is considered unknown by watershed # this way, watershed can distinguish unknown from the background labels = labels + 1 labels[unknown==255] = 0 try: # random walker on thresh_mask leads a lot higher mean IoU but lower LB #labels = random_walker(thresh_mask, labels) # random walker on thresh_mask leads lower mean IoU but higher LB labels = random_walker(mask_plus_contour, labels, multichannel=True) except: labels = cv2.watershed(mask_plus_contour, labels) labels[labels==-1] = 0 labels[labels==1] = 0 labels = labels -1 labels[labels==-1] = 0 # discard nuclei which are too big or too small mean = np.mean(stats[1:,cv2.CC_STAT_AREA]) for i in range(1, labels.max()): if stats[i, cv2.CC_STAT_AREA] > mean*10 or stats[i, cv2.CC_STAT_AREA] < mean/10: labels[labels==i] = 0 labels = renumber_labels(labels) return labels
Example #15
Source File: Grouping.py From CSGNet with MIT License | 2 votes |
def train_gen(self, number_of_objects, number_of_trees): """ Generates cluster programs to be drawn in one image. :param number_of_objects: Total number of objects to draw in one image :param number_of_trees: total number of cluster to draw in one image :return: """ num_objs = 0 programs = [] while num_objs < number_of_objects: index = np.random.choice(len(self.train_substrings)) if num_objs + len(self.train_substrings[index].keys()) > number_of_objects: required_indices = sorted(self.train_substrings[index].keys())[0:number_of_objects - num_objs] cluster = {} for r in required_indices: p = self.train_substrings[index][r] image = image_from_expressions([p,], stack_size=9, canvas_shape=[64, 64]) # Makes sure that the object created doesn't have disjoint parts, # don't include the program, because it makes the analysis difficult. nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats( np.array(image[0], dtype=np.uint8)) if nlabels > 2: continue cluster[r] = self.train_substrings[index][r] if cluster: programs.append(cluster) num_objs += len(cluster.keys()) num_objs += len(cluster.keys()) else: cluster = {} for k, p in self.train_substrings[index].items(): image = image_from_expressions([p], stack_size=9, canvas_shape=[64, 64]) nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats( np.array(image[0], dtype=np.uint8)) if nlabels > 2: continue cluster[k] = p if cluster: programs.append(cluster) num_objs += len(cluster.keys()) return programs