机器视觉学习(十一)—— 最小矩形和圆形区域、近似轮廓、凸包

目录

一、最小矩形区域与最小圆形区域 

1.1 cv2.minAreaRect()函数

1.2 cv2.minEnclosingCircle()函数

1.3 最小矩形区域与最小圆形区域示例

二、 显示近似轮廓

2.1 cv2.approxPolyDP()函数

2.2 显示近似轮廓示例代码

2.2.1 简约版 

2.2.2 进阶版 

三、 显示凸包

3.1 cv2.convexHull()函数

3.2 显示凸包示例代码


一、最小矩形区域与最小圆形区域 

1.1 cv2.minAreaRect()函数

cv2.minAreaRect()函数是OpenCV中的一个函数,用于计算点集的最小外接矩形。

函数原型如下:

retval = cv2.minAreaRect(points)

参数说明:

  • points:需要计算最小外接矩形的点集。可以是一个numpy数组或者一个contour(轮廓)。

返回值说明:

  • retval:返回一个 Box2D 结构,其中包含以下信息:
    • retval[0]:矩形的中心点坐标 (x, y)。
    • retval[1]:矩形的宽度和高度。
    • retval[2]:旋转角度,表示矩形相对于水平轴的旋转角度。

1.2 cv2.minEnclosingCircle()函数

cv2.minEnclosingCircle()函数是一个OpenCV函数,用于计算给定点集的最小外接圆。

函数的语法如下:

center, radius = cv2.minEnclosingCircle(points)

参数说明:

  • points:输入的点集,可以是一个点的列表或数组。

返回值说明:

  • center:最小外接圆的圆心坐标。
  • radius:最小外接圆的半径。

注意:

  • 输入点集的数据类型应为numpy数组。
  • 函数计算的是最小外接圆,即能包含所有输入点的最小半径的圆。

1.3 最小矩形区域与最小圆形区域示例

使用cv2.minAreaRect()函数来计算最小矩形区域,使用函数cv2.minEnclosingCircle()函数来计算最小圆形区域。

最小矩形区域:

import cv2
import numpy as np

# 创建一个轮廓
contours = np.array([[100, 100], [200, 100], [200, 200], [100, 200]])

# 计算最小矩形区域
rect = cv2.minAreaRect(contours)
box = cv2.boxPoints(rect)
box = np.int0(box)

# 绘制最小矩形
img = np.zeros((300, 300), dtype=np.uint8)
cv2.drawContours(img, [box], 0, (255), 2)
cv2.imshow('Min Area Rectangle', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

对于最小矩形区域,返回的是一个包含四个点的数组,可以使用cv2.boxPoints()来获取这四个点的坐标。

函数原型:   cv.boxPoints(rect)      
        作用:   将 cv2.minAreaRect(contour)得到的结果转化成四个点的坐标

最小圆形区域:

import cv2
import numpy as np

# 创建一个轮廓
contours = np.array([[100, 100], [200, 100], [200, 200], [100, 200]])

# 计算最小圆形区域
(x, y), radius = cv2.minEnclosingCircle(contours)
center = (int(x), int(y))
radius = int(radius)

# 绘制最小圆形
img = np.zeros((300, 300), dtype=np.uint8)
cv2.circle(img, center, radius, (255), 2)
cv2.imshow('Min Enclosing Circle', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

对于最小圆形区域,返回的是圆心的坐标和半径。

二、 显示近似轮廓

2.1 cv2.approxPolyDP()函数

cv2.approxPolyDP()函数是OpenCV中用于对轮廓进行近似的函数。

函数语法如下:

approx = cv2.approxPolyDP(curve, epsilon, closed)

参数说明: 

  • curve:输入的曲线/轮廓。
  • epsilon:表示近似精度的参数。它是一个距离阈值,表示轮廓与近似轮廓之间的最大距离。较小的值会产生更准确的近似,但也会导致近似轮廓较长。较大的值会生成更简化的近似轮廓。
  • closed:一个布尔值,表示曲线是否是闭合的。如果为True,函数会将曲线近似为一个闭合的多边形。如果为False,函数会将曲线近似为一个开放的多边形。

函数会返回一个近似轮廓,它是一个由近似点组成的多维数组。

2.2 显示近似轮廓示例代码

要显示近似轮廓,你可以使用cv2.drawContours()函数绘制轮廓。

以下两个示例代码,演示如何使用cv2.approxPolyDP()函数对轮廓进行近似,并绘制近似轮廓:

2.2.1 简约版 
import cv2
import numpy as np

# 读取图像并将其转换为灰度图像
image = cv2.imread('image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 进行阈值处理
_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

# 查找轮廓
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 创建一个空白的图像作为近似轮廓的绘制目标
approx_image = np.zeros_like(image)

# 遍历每个轮廓
for contour in contours:
    # 近似轮廓
    epsilon = 0.01 * cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, epsilon, True)
    
    # 绘制近似轮廓
    cv2.drawContours(approx_image, [approx], -1, (0, 255, 0), 2)

# 显示图像
cv2.imshow('Approximated Contours', approx_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这个示例中,我们首先读取图像并将其转换为灰度图像,并进行阈值处理以获取二值图像。然后使用cv2.findContours()函数查找图像中的轮廓。

接下来,我们遍历每个轮廓,并使用cv2.approxPolyDP()函数对轮廓进行近似。然后,我们创建一个空白的图像approx_image作为近似轮廓的绘制目标。

最后,我们使用cv2.drawContours()函数将近似轮廓绘制到approx_image上,并显示图像。

2.2.2 进阶版 

使用OpenCV中的Canny函数显示近似轮廓更直观

import cv2

def show_approx_contour(image_path):
    # 读取图像
    image = cv2.imread(image_path)

    # 将图像转换为灰度
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 使用Canny函数检测边缘
    edges = cv2.Canny(gray, 50, 150)

    # 执行轮廓检测
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 近似轮廓
    approx_contours = []
    for contour in contours:
        epsilon = 0.01 * cv2.arcLength(contour, True)
        approx = cv2.approxPolyDP(contour, epsilon, True)
        approx_contours.append(approx)

    # 在原始图像上绘制轮廓
    cv2.drawContours(image, approx_contours, -1, (0, 255, 0), 2)

    # 显示图像
    cv2.imshow("Approximate Contours", image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

# 示例用法
image_path = "path/to/your/image.jpg"
show_approx_contour(image_path)

在这个示例中,我们首先读取输入的图像,并将其转换为灰度图像。然后,我们使用Canny函数来检测图像的边缘。

接下来,我们使用cv2.findContours()函数来执行轮廓检测。然后,我们对每个轮廓应用cv2.approxPolyDP()函数来近似轮廓线。这个函数使用Douglas-Peucker算法,它根据指定的精度参数来逐渐减少轮廓中的点数。

最后,我们使用cv2.drawContours()函数在原始图像上绘制近似的轮廓线,然后使用cv2.imshow()函数显示结果图像。

三、 显示凸包

3.1 cv2.convexHull()函数

cv2.convexHull()函数是OpenCV中的一个函数,用于计算给定点集的凸包。

凸包是包围点集的多边形,使得多边形的所有内角都小于180度,并且所有点都位于多边形的边界上。

函数的语法如下:

hull = cv2.convexHull(points[, hull[, clockwise[, returnPoints]] 

参数说明:

  • points:输入的点集,可以是一个numpy数组,每个点的数据类型应是int32。
  • hull:可选参数,指定输出的凸包点集的索引,默认为None。
  • clockwise:可选参数,指定是否按顺时针方向输出凸包点集,默认为False。
  • returnPoints:可选参数,指定是否返回凸包点集的坐标,默认为True。

返回值:

  • 如果hull参数为None,则返回凸包点集的索引。
  • 如果hull参数不为None,则返回凸包点集的坐标。

函数的使用示例:

import numpy as np
import cv2

points = np.array([[10, 10], [10, 100], [100, 100], [100, 10]], dtype=np.int32)
hull = cv2.convexHull(points)

print(hull)

输出结果:

[[[ 10 100]]
 [[100 100]]
 [[100  10]]
 [[ 10  10]]]

3.2 显示凸包示例代码

要在OpenCV中显示凸包,可以使用cv2.convexHull()函数。

下面是显示凸包的示例代码:

import cv2

def show_convex_hull(image_path):
    # 读取图像
    image = cv2.imread(image_path)

    # 将图像转换为灰度
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 使用Canny函数检测边缘
    edges = cv2.Canny(gray, 50, 150)

    # 执行轮廓检测
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 寻找凸包
    convex_hulls = []
    for contour in contours:
        hull = cv2.convexHull(contour)
        convex_hulls.append(hull)

    # 在原始图像上绘制凸包
    cv2.drawContours(image, convex_hulls, -1, (0, 255, 0), 2)

    # 显示图像
    cv2.imshow("Convex Hull", image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

# 示例用法
image_path = "path/to/your/image.jpg"
show_convex_hull(image_path)

在这个示例中,我们首先读取输入的图像并将其转换为灰度图像。然后,我们使用Canny函数检测图像的边缘。

接下来,我们使用cv2.findContours()函数执行轮廓检测。然后,对于每个轮廓,我们使用cv2.convexHull()函数找到凸包。

最后,我们使用cv2.drawContours()函数在原始图像上绘制凸包,然后使用cv2.imshow()函数显示结果图像。

相关推荐

  1. 计算机视觉——OpenCV C++实现

    2024-04-01 22:02:02       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-01 22:02:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-01 22:02:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-01 22:02:02       82 阅读
  4. Python语言-面向对象

    2024-04-01 22:02:02       91 阅读

热门阅读

  1. Linux共享网络给其它主机

    2024-04-01 22:02:02       36 阅读
  2. FastAPI+React全栈开发13 FastAPI概述

    2024-04-01 22:02:02       27 阅读
  3. C# 字符串转json

    2024-04-01 22:02:02       32 阅读
  4. 医疗器械测试面试准备—质量部总监二面

    2024-04-01 22:02:02       54 阅读
  5. 蓝桥杯考前复习二

    2024-04-01 22:02:02       41 阅读
  6. 前端CSS样式(image)

    2024-04-01 22:02:02       39 阅读
  7. 2084: [蓝桥杯2023初赛] 整数删除

    2024-04-01 22:02:02       40 阅读
  8. Stable Diffusion 本地部署教程

    2024-04-01 22:02:02       40 阅读
  9. 学习记录之数学表达式(3)

    2024-04-01 22:02:02       29 阅读