GrabCut: object extraction by separating the foreground and background of an image

Image
GrabCut is an algorithm that is used to extract the foreground from an image.  OpenCV has a python implementation of this algorithm which we can use for our purpose. GrabCut in OpenCV OpenCV provides the implementation of the GrabCut as a function cv2.grabCut()  . The function takes seven parameters as arguments and returns three parameters. cv.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount[, mode]) Parameters: img : take an image as input ( 8-bit 3-channel image). mask : input/output 8-bit single-channel mask. When we set parameter mode to cv2.GC_INIT_WITH_RECT ,  the mask will be initialized automatically.  rect : coordinates of a rectangle or bounding box which includes the foreground object in the format (x, y, w, h) . The parameter is only used when the parameter mode==GC_INIT_WITH_RECT . bgdModel : temporary array for the background model and use it int

OpenCV: extraction of the image part within the bounding box

We can extract the part of an image within the bounding box. The bounding box can be a rectangle, triangle, or polygon.

OpenCV provides functions to draw geometric shapes in the image, with these functions we can do our extraction job.

Extraction of the image part within the bounding box

We will extract the part from the below image which is lies within the blue rectangle.



We will do our job by following these steps

  • Load and visualize the image.
  • Create an empty image.
  • Draw the bounding box.
  • Extract the part within the bounding box.
  • Visualize the result.

Let's implement the code.

Import necessary packages

    	# Import necessary packages
        import numpy as np
        import cv2
        import matplotlib.pyplot as plt

Load and visualize

We will load the image into memory with the OpenCV function cv2.imread() and visualize the image by plotting with the matplotlib package.
        # Load image
        file_name = 'images/sample_image.jpeg'
        image = cv2.imread(file_name)

        # Visualize image
        plt.imshow(image)
        plt.show()
	
Fig: Loaded image
Note: OpenCV read image into BGR order.

Create an empty image

We will use an empty image as a mask. Create a NumPy array with zero elements. The shape of the image will be the same as image height and width and data type 8bit unsigned integer. An image shape is \((720, 1080, 3)\) represents (height, width, number of channel) . Actually, this empty image is an 8-bit single-channel image.

    	# Create an empty image/ Mask initialization
        mask = np.zeros(image.shape[:2], dtype=np.uint8) # 8-bit single channel image where each value is zero

Draw the bounding box into the empty image(mask)

        # Draw the bounding box
        bottom = (50, 200) # rectangle left bootom coordinates
        top = (250, 400) # rectangle right top coordinates
        cv2.rectangle(mask, bottom, top, color=255,thickness=cv2.FILLED ) 
The bottom is the left bottom corner coordinate of the rectangle and top is the top right corner coordinates of the rectangle. these lines of code will draw a rectangle. But what it does? Actually, it replaces all the values with 255 in the array within the boundary we provide. Here is the detail of cv2.rectangle() function

Extract the part within the bounding box.

We will get our expected segmentation of the image with the bitwise AND operation.
        # Extraction of the part of the image
        img_segment = cv2.bitwise_and(image, image, mask=mask) # bitwise AND operation
The mask array contains 255 inside the rectangle boundary and others are 0. As a result after the bitwise operation, the whole image pixels value will be 0 (black) except the rectangle part. 

Visualize the result

Plot the segmented image
        # Visualize the result.
        plt.imshow(img_segment)
        plt.show()
Fig: Resultant image

Full implementation

OpenCV also has implemented functions for circle, triangle, polygon, line. Drawing Functions in OpenCV. We can use them to do our job.

Comments

Popular posts from this blog

GrabCut: object extraction by separating the foreground and background of an image