首页 > 其他分享 >机器视觉学习(十一)—— 最小矩形和圆形区域、近似轮廓、凸包

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

时间:2024-03-31 23:31:43浏览次数:12  
标签:轮廓 函数 image cv2 近似 凸包 图像 视觉 矩形

目录

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

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()函数显示结果图像。

标签:轮廓,函数,image,cv2,近似,凸包,图像,视觉,矩形
From: https://blog.csdn.net/qq_74375828/article/details/137133602

相关文章

  • 机器视觉学习(八)—— 阈值化
    目录一、阈值化二、二值化和示例2.1二值化2.2示例代码一、阈值化OpenCV是一个开源的计算机视觉库,可以用于图像处理和计算机视觉任务。阈值化是图像处理中的一种常见操作,可以将图像的像素值分成两个或多个不同的类别,通常是黑色和白色。使用OpenCV进行阈值化的步骤如......
  • 毕业设计:基于图像增强的交通标志识别系统 深度学习 机器视觉
    目录前言课题背景和意义实现技术思路一、算法理论基础1.1 直方图均衡化1.2SKNet 分类模型二、 数据集三、实验及结果分析3.1 实验环境搭建3.2 模型训练最后前言  ......
  • LeetCode 84. 柱状图中最大的矩形
    解题思路单调栈经典题型,这道题我们需要找到heights[i]左边的最近的比heights[i]小的值,找到heights[i]右边的最近的比heights[i]小的值。所以我们想到了单调栈。相关代码classSolution{publicintlargestRectangleArea(int[]heights){intn=h......
  • 毕业设计:基于深度学习的物品识别目标检测系统 机器视觉
    目录前言设计思路一、课题背景与意义二、算法理论原理2.1深度学习2.2注意力机制三、检测的实现3.1数据集3.2实验环境搭建3.3实验及结果分析最后前言    ......
  • 代码随想录算法训练营第六十天|84.柱状图中最大的矩形
    84.柱状图中最大的矩形刷题https://leetcode.cn/problems/largest-rectangle-in-histogram/description/文章讲解https://programmercarl.com/0084.%E6%9F%B1%E7%8A%B6%E5%9B%BE%E4%B8%AD%E6%9C%80%E5%A4%A7%E7%9A%84%E7%9F%A9%E5%BD%A2.html视频讲解https://www.bilibili.com......
  • 视觉循迹小车(旭日x3派、摄像头、循迹)
    1、旭日x3派(烧录好系统镜像)2、USB摄像头3、TB66124、小车底盘(直流电机或直流减速电机) 视觉循迹原理x3派读取摄像头图像,转换成灰度图像,从灰度图像中选择第 120 行(图像的一个水平线),遍历第120行的全部320列,根据像素值小于或大于阈值,将相应的值(0 或 1)添加到 date 列表......
  • 代码随想录算法训练营第六十天 | 84.柱状图中最大的矩形
      84.柱状图中最大的矩形 已解答困难 相关标签相关企业 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为1。求在该柱状图中,能够勾勒出来的矩形的最大面积。 示例1:输入:heights=[2,1,5,6,2,3]输出:10......
  • YOLOv9 实战指南:打造个性化视觉识别利器,从零开始训练你的专属测试集
    论文地址:YOLOv9:LearningWhatYouWanttoLearnUsingProgrammableGradientInformationGitHub:WongKinYiu/yolov9:Implementationofpaper-YOLOv9:LearningWhatYouWanttoLearnUsingProgrammableGradientInformation(github.com)一、摘要今天的深度学习......
  • 认知战壳吉桔:打造认知战战略视觉锤快速抓住用户眼球
    认知战壳吉桔:打造认知战战略视觉锤快速抓住用户眼球关键词:新质生产力、人类命运共同体、认知战、认知域、认知战研究中心、认知战争、认知战战术、认知战战略、认知域作战研究、认知作战、认知控制、战略思想、CognitiveWarfare、CognitiveDomain、CognitiveControl内容摘......
  • (60/60)last dance|柱状图中最大的矩形
    lastdance柱状图中最大的矩形leetcode:84.柱状图中最大的矩形单调栈思路和接雨水很类似,但需要首尾加0(尾0是为了触发计算,首0是为了避免首元素触发计算时没有left)注意点尾加0后还是要遍历到heights.size()-1,因为是以取出元素为基准计算的,而取出元素是当前遍历元素的上一......