How to use openCV's connected components with stats in python?
The function works as follows:
# Import the cv2 libraryimport cv2# Read the image you want connected components ofsrc = cv2.imread('/directorypath/image.bmp')# Threshold it so it becomes binaryret, thresh = cv2.threshold(src,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)# You need to choose 4 or 8 for connectivity typeconnectivity = 4 # Perform the operationoutput = cv2.connectedComponentsWithStats(thresh, connectivity, cv2.CV_32S)# Get the results# The first cell is the number of labelsnum_labels = output[0]# The second cell is the label matrixlabels = output[1]# The third cell is the stat matrixstats = output[2]# The fourth cell is the centroid matrixcentroids = output[3]
Labels is a matrix the size of the input image where each element has a value equal to its label.
Stats is a matrix of the stats that the function calculates. It has a length equal to the number of labels and a width equal to the number of stats. It can be used with the OpenCV documentation for it:
Statistics output for each label, including the background label, see below for available statistics. Statistics are accessed via stats[label, COLUMN] where available columns are defined below.
- cv2.CC_STAT_LEFT The leftmost (x) coordinate which is the inclusive start of the bounding box in the horizontal direction.
- cv2.CC_STAT_TOP The topmost (y) coordinate which is the inclusive start of the bounding box in the vertical direction.
- cv2.CC_STAT_WIDTH The horizontal size of the bounding box
- cv2.CC_STAT_HEIGHT The vertical size of the bounding box
- cv2.CC_STAT_AREA The total area (in pixels) of the connected component
Centroids is a matrix with the x and y locations of each centroid. The row in this matrix corresponds to the label number.
I have come here a few times to remember how it works and each time I have to reduce the above code to :
_, thresh = cv2.threshold(src,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)connectivity = 4 # You need to choose 4 or 8 for connectivity typenum_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh , connectivity , cv2.CV_32S)
Hopefully, it's useful for everyone :)
Adding to Zack Knopp
answer,If you are using a grayscale image you can simply use:
import cv2import numpy as npsrc = cv2.imread("path\\to\\image.png", 0)binary_map = (src > 0).astype(np.uint8)connectivity = 4 # or whatever you preferoutput = cv2.connectedComponentsWithStats(binary_map, connectivity, cv2.CV_32S)
When I tried using Zack Knopp
answer on a grayscale image it didn't work and this was my solution.