'How can I obtain "pixel-perfect" connected components in OpenCV?

I'm trying to obtain pixel-perfect connected components in an image using OpenCV. For example, in this image there are three connected components, the two rectangles and the background:

enter image description here

However, OpenCV's connectedComponents() function thinks there are only two, considering the rectangles to be a single component, I guess because they're so close (2 pixels) together:

import numpy as np
import cv2

filepath = "test.png"

if __name__ == "__main__":
    image = cv2.imread(filepath)

    hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    value_channel = hsv_image[:, :, -1]

    n_components, component_map = cv2.connectedComponents(
        binarized_values,
        connectivity=4
    )
    print(n_components) # prints 2

Is there a way to get truly pixel-perfect connected components?

Note that I need an answer for Python, and PyOpenCV does not seem to support the ccltype parameter mentioned in the docs to set the algorithm.



Solution 1:[1]

You could use Python Wand, which uses ImageMagick. Here is the ImageMagick command line for that. It finds 3 regions: two black rectangles and the white strip connected to the outer white border.

convert J3UDP.png -type bilevel \
-define connected-components:verbose=true \
-define connected-components:mean-color=true \
-connected-components 8 null:

Objects (id: bounding-box centroid area mean-color):
  1: 80x96+4+6 43.5,53.5 7680 gray(0)
  2: 80x96+86+6 125.5,53.5 7680 gray(0)
  0: 170x109+0+0 84.5,56.4 3170 gray(255)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 fmw42