Sunday, 28 January 2024

OpenCV: Contour detection

Contours are the boundaries of an object. Contours are used to detect and object and perform shape analysis.

 

Contours vs edges

Contours is a continuous curve that define the shape of an object in the image, where as an edge is a point in an image where there is a sharp change in color intensity. Contour is a closed curve, where as an edge is either open or closed curve. Contour detection is often used in object detection and recognition applications.

 

You can apply number of different transformations to the image to find contours.

 

a. Grayscale: Grayscale images simplify the process of identifying contours in an image, as they reduce the image to a single channel representing intensity or brightness. This helps image identification algorithms to distinguish the objets from their background.

 

Apart from this, following points help you to understand better.

a.   Grayscale images are computationally less intensive to process the data than colored images.

b.   Most of the contour detection algorithms are designed to work with grayscale images.

 

b. Blurring: Blurring the image helps you to reduce the noise. Be cautious, as too much blurring difficult the process to detect the edges.

 

c. Thresholding: It convert the image to black and white. It helps contour detection algorithms to identify the edges of objects in the image easier.

 

d. Morphological Operations: Morphological transformations like dilation, erosion can be used to fill in gaps in contours, smooth out edges, and remove noise.

 

e. watershed transformation: This technique is used to identify individual contours in an image, even if the contours are overlapping.

 

e. Edge detection: you can apply edge detection techniques like the Canny edge detector or Sobel operator to enhance the edges of objects in the binary image.

 

e. Contour identification: Find the boundaries of objects in the image.

 

f. Contour Post-processing: You can perform number of steps like refine the detected contours, drop or remove small or spurious contours, and improve the accuracy of the contour results.

 

Is there any specific order that I should apply transformations to detect contours?

There is no specific order as such, order is completely depend on the specific requirements of your task and the characteristics of the image. But following are the some general guidelines to find the contours.

1.   Convert the image to grayscale

2.   Apply blur operation to reduce noise

3.   Apply thresholding operation

4.   Apply morphological transformations and watershed transformations.

 

How to find contours in OpenCV?

Using cv2.findContours method, we can identify the boundaries of an object within a binary or grayscale image.

 

Signature

contours, hierarchy = cv2.findContours(image, mode, method)

 

‘findContours’ method return a list of contours, those can be further processed by a computer vision applications. ‘hoerarchy’ contains information about the nesting of contours and the relationships between them.

 

Following table summarizes different parameters of findContours method.

 

Parameter

Description

image

Input binary or grey scale image

mode

Specifies how the contours are determined. Following constants are supported.

 

cv2.RETR_EXTERNAL: Only the external contours are retrieved. This is useful when you're interested in the contours of the outer objects.

 

cv2.RETR_LIST: Retrieves all of the contours in the image.

 

cv2.RETR_CCOMP: Retrieves all contours and organizes them into a two-level hierarchy. The top-level hierarchy consists of external boundaries of components, while the second level corresponds to holes and nested objects.

 

cv2.RETR_TREE: Retrieves all contours and constructs a full hierarchy of nested contours.

method

Specifies contour approximation method. Following constants are supported.

 

cv2.CHAIN_APPROX_NONE: All contour points are stored. This provides the most detailed contour information.

 

cv2.CHAIN_APPROX_SIMPLE: Compresses horizontal, vertical, and diagonal segments and leaves only their end points. This is the most commonly used method.

 

cv2.CHAIN_APPROX_TC89_L1 and cv2.CHAIN_APPROX_TC89_KCOS: Applies the Tangent to the arc, 1 or k cos methods.

 

 

Example

contours, hierarchies = cv.findContours(canny, cv.RETR_LIST, cv.CHAIN_APPROX_NONE)

 

Draw the contours on a blank image

Using drawContours method, we can draw contours on a image.

 

Signature

cv2.drawContours(image, contours, contourIdx, color, thickness, lineType, hierarchy, maxLevel, offset)

 

Following table summarizes the parameters.

 

Parameter

Description

image

Specifies the input image on which we want to draw contours

contours

List of contorus that you want to draw

contourIdx

It specifies which contours are drawn on the image.

 

a. If contourIdx is set to a positive integer, then this function draw the contour at specific index position in the list.

 

b. If contourIdx is set to negative value, then this function draws all the contours in the list of contours.

 

c. If you provide list of integers, then this method draws the contours at specific index positions.

 

color

It is a tuple, where color is represented in (B,G,R) format.

thickness

Specify thickness of contour lines. If thickness is set it to a negative value (e.g., -1), then contour is filled rather than outlined.

lineType

Specifies the type of line used for drawing the contours.

 

Ex: cv2.LINE_AA, cv2.LINE_8

hierarchy

 

maxLevel

It is an optional parameter. It is used when working with hierarchical contours to specify the maximum level to draw.

 

The default value is 0, which means all levels will be drawn.

offset

It is an optional parameter, and specify an offset to add to all contour points. This is useful for adjusting the position of the drawn contours.

 

 

Example

blank_image = np.zeros(image.shape, dtype='uint8')

cv.drawContours(blank_image, contours, -1, (0, 255, 0), 1)

 

Find the below working application.

 

contours.py

import cv2 as cv
import numpy as np

image = cv.imread('bear.jpeg')
cv.imshow('Bear', image)

# Convert this image to grayscale
grayscale_image = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow('grayscale_image', grayscale_image)

blurred_image = cv.GaussianBlur(grayscale_image, (3, 3), cv.BORDER_DEFAULT)
cv.imshow('blurred_image', blurred_image)

# Define the structuring element (square in this case)
kernel = np.ones((3, 3), np.uint8)

# Perform dilation
dilated_image = cv.dilate(blurred_image, kernel, iterations=1)
cv.imshow('dilated_image', dilated_image)

# Get the edges
canny = cv.Canny(dilated_image, 125, 175)
cv.imshow('canny edges', canny)

# Get the contours, contours are returned as a list
contours, hierarchies = cv.findContours(canny, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
print(f'Total contours are  : {len(contours)}')

max_length = -1
contour_index = -1
max_contour_index = contour_index

for contour in range(len(contours)):
    contour_index = contour_index + 1

blank_image = np.zeros(image.shape, dtype='uint8')

# Draw the contours on blank image
cv.drawContours(blank_image, contours, -1, (0, 255, 0), thickness=1)
cv.imshow('contours on blank_image', blank_image)

# Wait for Infinite amount of time for a keyboard key to be pressed
cv.waitKey(0)

# Close the OpenCV windows
cv.destroyAllWindows()

 

Output

Original image

 


Gray scale image

  


Blurred image

 


 

Dilated image




Canny edges

 

 


Contours on a blank image



 

Previous                                                    Next                                                    Home

No comments:

Post a Comment