1 介绍

        轮廓检测是图像处理中的重要任务,用于提取图像中物体的边界。OpenCV 提供了强大的轮廓检测功能,可以用于物体识别、形状分析、目标跟踪等应用。以下是 OpenCV 图像轮廓检测的详细说明。

1.1 轮廓检测的基本概念

  • 轮廓: 图像中物体的边界,由一系列点组成。
  • 轮廓层次结构: 轮廓之间的嵌套关系,例如一个轮廓是否包含另一个轮廓。
  • 轮廓特征: 轮廓的面积、周长、边界矩形、最小外接矩形、最小外接圆等。

1.2 轮廓检测常用函数

函数名称 功能描述
cv2.findContours() 查找图像中的轮廓
cv2.drawContours() 在图像上绘制轮廓
cv2.contourArea() 计算轮廓的面积
cv2.arcLength() 计算轮廓的周长或弧长
cv2.boundingRect() 计算轮廓的边界矩形
cv2.minAreaRect() 计算轮廓的最小外接矩形
cv2.minEnclosingCircle() 计算轮廓的最小外接圆
cv2.approxPolyDP() 对轮廓进行多边形近似

2 函数详细说明

2.1 cv2.findContours()

        该函数用于在二值图像中查找轮廓。轮廓是图像中具有相同颜色或强度的连续点的曲线。

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

        参数说明:

  • image: 输入的二值图像(通常为经过阈值处理或边缘检测后的图像)。
  • mode: 轮廓检索模式,常用的有:
    • cv2.RETR_EXTERNAL: 只检测最外层轮廓。
    • cv2.RETR_LIST: 检测所有轮廓,但不建立层次关系。
    • cv2.RETR_TREE: 检测所有轮廓,并建立完整的层次结构。
  • method: 轮廓近似方法,常用的有:
    • cv2.CHAIN_APPROX_NONE: 存储所有的轮廓点。
    • cv2.CHAIN_APPROX_SIMPLE: 压缩水平、垂直和对角线段,只保留端点。
  • contours: 输出的轮廓列表,每个轮廓是一个点集。
  • hierarchy: 输出的层次结构信息。
  • offset: 可选参数,轮廓点的偏移量。

        返回值:

  • contours: 检测到的轮廓列表。
  • hierarchy: 轮廓的层次结构信息。
import cv2

# 读取图像并转换为灰度图
image = cv2.imread('image.jpg', 0)
# 二值化处理
_, binary = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

2.2 cv2.drawContours()

        该函数用于在图像上绘制检测到的轮廓。

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

        参数说明:

  • image: 要绘制轮廓的图像。
  • contours: 轮廓列表。
  • contourIdx: 要绘制的轮廓索引,如果为负数,则绘制所有轮廓。
  • color: 轮廓的颜色。
  • thickness: 轮廓线的厚度,如果为负数,则填充轮廓内部。
  • lineType: 线型。
  • hierarchy: 轮廓的层次结构信息。
  • maxLevel: 绘制的最大层次深度。
  • offset: 轮廓点的偏移量。
import cv2
import numpy as np

# 读取图像并转换为灰度图
image = cv2.imread('image.jpg', 0)
# 二值化处理
_, binary = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 创建一个空白图像
output = np.zeros_like(image)
# 绘制所有轮廓
cv2.drawContours(output, contours, -1, (255, 0, 0), 2)
cv2.imshow('Contours', output)
cv2.waitKey(0)

2.3 cv2.contourArea()

        该函数用于计算轮廓的面积。

area = cv2.contourArea(contour[, oriented])
  • contour: 输入的轮廓点集。
  • oriented: 可选参数,如果为True,返回有符号的面积。
import cv2

# 读取图像并转换为灰度图
image = cv2.imread('image.jpg', 0)
# 二值化处理
_, binary = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

for contour in contours:
    area = cv2.contourArea(contour)
    print(f"Contour area: {area}")

2.4 cv2.arcLength()

        该函数用于计算轮廓的周长或弧长。

length = cv2.arcLength(curve, closed)
  • curve: 输入的轮廓点集。
  • closed: 布尔值,表示轮廓是否闭合。
import cv2

# 读取图像并转换为灰度图
image = cv2.imread('image.jpg', 0)
# 二值化处理
_, binary = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

for contour in contours:
    perimeter = cv2.arcLength(contour, True)
    print(f"Contour perimeter: {perimeter}")

2.5 cv2.boundingRect()

        该函数用于计算轮廓的边界矩形。

x, y, w, h = cv2.boundingRect(points)
  • points: 输入的轮廓点集。
for contour in contours:
    x, y, w, h = cv2.boundingRect(contour)
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow('Bounding Rectangles', image)
cv2.waitKey(0)

2.6 cv2.minAreaRect()

        该函数用于计算轮廓的最小外接矩形(旋转矩形)。

rect = cv2.minAreaRect(points)
  • points: 输入的轮廓点集。
for contour in contours:
    rect = cv2.minAreaRect(contour)
    box = cv2.boxPoints(rect)
    box = np.int8(box)
    cv2.drawContours(image, [box], 0, (0, 0, 255), 2)
cv2.imshow('Min Area Rectangles', image)
cv2.waitKey(0)

2.7 cv2.minEnclosingCircle()

        该函数用于计算轮廓的最小外接圆。

(center, radius) = cv2.minEnclosingCircle(points)
  • points: 输入的轮廓点集。
for contour in contours:
    (x, y), radius = cv2.minEnclosingCircle(contour)
    center = (int(x), int(y))
    radius = int(radius)
    cv2.circle(image, center, radius, (255, 0, 0), 2)
cv2.imshow('Min Enclosing Circles', image)
cv2.waitKey(0)

2.8 cv2.approxPolyDP()

        该函数用于对轮廓进行多边形近似。

approx = cv2.approxPolyDP(curve, epsilon, closed)
  • curve: 输入的轮廓点集。
  • epsilon: 近似精度,值越小,近似越精确。
  • closed: 布尔值,表示轮廓是否闭合。
for contour in contours:
    epsilon = 0.01 * cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, epsilon, True)
    cv2.drawContours(image, [approx], 0, (0, 255, 0), 2)
cv2.imshow('Approx Polygons', image)
cv2.waitKey(0)

3 轮廓检测的应用

  • 物体识别: 通过轮廓检测可以识别图像中的物体,例如检测圆形、矩形等。
  • 形状分析: 通过计算轮廓的特征(如面积、周长、边界矩形等),可以分析物体的形状。
  • 目标跟踪: 在视频中,可以通过轮廓检测跟踪运动的目标。
  • 图像分割: 通过轮廓检测可以将图像中的物体分割出来。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐