Pietro Sonza
Pietro Sonza

Reputation: 79

How to get only the center object in an image using OpenCV?

I'm trying to get only the center retangle in this image by using connected cv2.connectedComponentsWithStats. However I don't know how to get only the center image.

enter image description here

My attempt was this:

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, bw = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

img = cv2.threshold(bw, 127, 255, cv2.THRESH_BINARY)[1]  # ensure binary
def undesired_objects(image):
    image = image.astype('uint8')
    nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(image, connectivity=4)
    sizes = stats[:, -1]

    max_label = 1
    max_size = sizes[1]
    for i in range(2, nb_components):
        if sizes[i] > max_size:
            max_label = i
            max_size = sizes[i]

    img2 = np.zeros(output.shape)
    img2[output == max_label] = 255
    cv2.imshow("Biggest component", img2)
    cv2.waitKey()

undesired_objects(img)

Upvotes: 2

Views: 423

Answers (1)

crackanddie
crackanddie

Reputation: 708

I think you should process your image better before using connectedComponentsWithStats

import cv2
import numpy as np


def threshold_gray_const(image_, rang: tuple):
    return cv2.inRange(image_, rang[0], rang[1])


def reject_borders(image_):
    out_image = image_.copy()
    h, w = image_.shape[:2]
    for row in range(h):
        if out_image[row, 0] == 255:
            cv2.floodFill(out_image, None, (0, row), 0)
        if out_image[row, w - 1] == 255:
            cv2.floodFill(out_image, None, (w - 1, row), 0)
    for col in range(w):
        if out_image[0, col] == 255:
            cv2.floodFill(out_image, None, (col, 0), 0)
        if out_image[h - 1, col] == 255:
            cv2.floodFill(out_image, None, (col, h - 1), 0)
    return out_image


img = cv2.imread("D:\\Downloads\\ZXo3i.png")

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# ret, bw = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
#
# img = cv2.threshold(bw, 127, 255, cv2.THRESH_BINARY)[1]  # ensure binary
img = threshold_gray_const(gray, (240, 255))
img = reject_borders(img)


def undesired_objects(image):
    image = image.astype('uint8')

    nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(image, connectivity=4)
    sizes = stats[:, -1]

    max_label = 1
    max_size = sizes[1]
    for i in range(2, nb_components):
        if sizes[i] > max_size:
            max_label = i
            max_size = sizes[i]

    img2 = np.zeros(output.shape)
    img2[output == max_label] = 255
    cv2.imshow("Biggest component", img2)
    cv2.waitKey()


undesired_objects(img)

Upvotes: 2

Related Questions