In this article, we will introduce how OpenCV can find contour and get bounding box with example code.

  • Code: contours. Py

OpenCV provides the findContours function to findContours, which is called with a binary image as input and some options.

Let’s take the following figure as an example:

Binary image

Code engineering Data/provides binary mask images of puppies and red balls:

Detectron2_seg_threshold.py was generated using a pre-trained instance segmentation model. The model detection results are as follows:

The Mask R-CNN used for the model has a predicted border. However, other models will only have a prediction mask, so if you want the border, you can use OpenCV to extract it.

The code also provides a way to obtain a red globe mask based on the gamut:

import cv2 as cv
import numpy as np

# fetch image
img = cv.imread(args.image, cv.IMREAD_COLOR)

# HSV threshold, get mask
def _threshold_hsv(image, lower, upper) :
  hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
  mask = cv.inRange(hsv, lower, upper)
  result = cv.bitwise_and(image, image, mask=mask)
  return result, mask

_, thres = _threshold_hsv(img, np.array([0.110.190]), np.array([7.255.255]))

# Clear small dots (optional)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3.3), (1.1))
thres = cv.morphologyEx(thres, cv.MORPH_OPEN, kernel)
Copy the code

Find the outline

# find contours
# cv.RETR_EXTERNAL: Only look for external contours
contours, hierarchy = cv.findContours(
  threshold, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)

# Approximate outline, minus points (optional)
contours_poly = [cv.approxPolyDP(c, 3.True) for c in contours]

# Draw outline
h, w = threshold.shape[:2]
drawing = np.zeros((h, w, 3), dtype=np.uint8)
for i in range(len(contours)):
  cv.drawContours(drawing, contours_poly, i, (0.255.0), 1, cv.LINE_8, hierarchy)
Copy the code

Get bounding box

BoundingRect gets the bounding box and draws:

for contour in contours_poly:
  rect = cv.boundingRect(contour)
  cv.rectangle(drawing,
                (int(rect[0]), int(rect[1])),
                (int(rect[0]+rect[2]), int(rect[1]+rect[3])),
                (0.255.0), 2, cv.LINE_8)
Copy the code

MinEnclosingCircle gets the boundary circle and draws:

for contour in contours_poly:
  center, radius = cv.minEnclosingCircle(contour)
  cv.circle(drawing, (int(center[0]), int(center[1)),int(radius),
            (0.255.0), 2, cv.LINE_8)
Copy the code

reference

  • OpenCV Tutorials / Image Processing

GoCoding personal practice experience sharing, please pay attention to the public account!