Search code examples
pythonopencvimage-segmentationconnected-componentslabeling

How to get region properties from image that is already labeled in OpenCV?


I am labeling images using the watershed algorithm in OpenCV (similar to this tutorial: https://docs.opencv.org/3.4/d3/db4/tutorial_py_watershed.html) such that at the end I obtain an array of labels where each region has an integer value corresponding to its label. Now, I want to obtain the coordinates of the bounding boxes and areas of each region.

I know this is easily done with skimage.measure.regionprops() but for considerations of speed of execution I would like to achieve this without importing skimage, ideally directly with OpenCV.

I have tried using cv2.connectedComponentsWithStats() but it only seems to work if the image is binary not if the labels are already defined.

I have tried to binarize the labeled image and then relabel it with connectedComponentsWithStats() as follows (note that the background has a label of 1 in this case and I want to remove it):

segmented = cv2.watershed(image.astype('uint8'), markers)

segmented_bin = segmented.copy()
segmented_bin[segmented < 2] = 0
segmented_bin[segmented > 1] = 255
num_labels, label_image, stats, centroids = cv2.connectedComponentsWithStats(segmented_bin.astype('uint8'), 4, cv2.CV_32S)

But this approach merges regions that are not separated by background which is not the desired effect.

Essentially I would like to know if there is a function similar to connectedComponentsWithStats() that deals with already labeled images?


Solution

  • If anybody else is interested, I ended up reverting to skimage.measure.regionprops() since I could not get cv2.connectedComponentsWithStats(). The time overhead is only in the tens of millisecond per image.