Home>


I want to label only two items from the largest.

import cv2
import numpy as np
import sys
# Load image
img = cv2.imread ('syaeidilate.png')
# Gray scale
gray = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY)


# Labeling process (detailed version)
label = cv2.connectedComponentsWithStats (gray)
# Extract object information by item
n = label [0]-1
data = np.delete (label [2], 0, 0)
center = np.delete (label [3], 0, 0)

# Convert binary image to color for exporting labeling results
color_src = cv2.cvtColor (gray, cv2.COLOR_GRAY2BGR)
# Display labeling results using object information
for i in range (n):
    # Display the circumscribed rectangle of each object with a red frame
    x0 = data [i] [0]
    y0 = data [i] [1]
    x1 = data [i] [0] + data [i] [2]
    y1 = data [i] [1] + data [i] [3]
    cv2.rectangle (color_src, (x0, y0), (x1, y1), (0, 0, 255))


    # Display the center of gravity coordinates of each object in yellow
    cv2.putText (color_src, "X:" + str (int (center [i] [0])), (x1-10, y1 + 15), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 255))
    cv2.putText (color_src, "Y:" + str (int (center [i] [1])), (x1-10, y1 + 30), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 255))

# Save image
cv2.imwrite ('syaeilbl.png', color_src)
  • Answer # 1

    The third column of the label information returned by connectedComponentsWithStats () is the width and the fourth column is the height, so the area of ​​each label is calculated by width * height and sorted by argsort () in ascending order. Get the index and use argsort () [-3: -1] to get the third and second from the back (that is, the index of the second and third largest labels). (Except for the biggest because it is the background)

    ### Added part 1
    stats = label [2]
    area = stats [:, cv2.CC_STAT_WIDTH] * stats [:, cv2.CC_STAT_HEIGHT]
    top2_idx = area.argsort () [-3: -1] # 2nd and 3rd largest area label (excluding 1st because it is background)
    Whole code
    import cv2
    import numpy as np
    import sys
    # Load image
    img = cv2.imread ('syaeidilate.png')
    # Gray scale
    gray = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY)
    # Labeling process (detailed version)
    label = cv2.connectedComponentsWithStats (gray)
    ### Added part 1
    stats = label [2]
    area = stats [:, cv2.CC_STAT_WIDTH] * stats [:, cv2.CC_STAT_HEIGHT]
    top2_idx = area.argsort () [-3: -1] # 2nd and 3rd label with the largest area (excluding the 1st because it is the background)
    # Extract object information by item
    data = label [2]
    center = label [3]
    # Convert binary image to color for exporting labeling results
    color_src = cv2.cvtColor (gray, cv2.COLOR_GRAY2BGR)
    # Display labeling results using object information
    for i in top2_idx:
        # Display the circumscribed rectangle of each object with a red frame
        x0 = data [i] [0]
        y0 = data [i] [1]
        x1 = data [i] [0] + data [i] [2]
        y1 = data [i] [1] + data [i] [3]
        cv2.rectangle (color_src, (x0, y0), (x1, y1), (0, 0, 255))
        # Display the center of gravity coordinates of each object in yellow
        cv2.putText (color_src, "X:" + str (int (center [i] [0])), (x1-10, y1 + 15), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 255))
        cv2.putText (color_src, "Y:" + str (int (center [i] [1])), (x1-10, y1 + 30), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 255))
    # Save image
    cv2.imwrite ('syaeilbl.png', color_src)