【OpenCV实现图像找到轮廓的不同特征,就像面积,周长,质心,边界框等等。】

文章目录

    • 概要
    • 图像矩
    • 凸包
    • 边界矩形

概要

OpenCV是一个流行的计算机视觉库,它提供了许多图像处理和分析功能,其中包括查找图像中物体的轮廓。通过查找轮廓,可以提取许多有用的特征,如面积、周长、质心、边界框等。

以下是几种使用OpenCV查找轮廓时常见的特征:

面积:可以使用 cv2.contourArea() 函数计算轮廓的面积。该函数将轮廓作为输入,并返回浮点数表示轮廓的面积。

周长:可以使用 cv2.arcLength() 函数计算轮廓的周长。该函数将轮廓作为输入,并返回浮点数表示轮廓的周长。

质心:可以使用 cv2.moments() 函数计算轮廓的质心。该函数将轮廓作为输入,并返回一个字典,其中包含轮廓的各种矩形,包括轮廓的质心。

边界框:使用 cv2.boundingRect() 函数可以计算轮廓的边界框。该函数将轮廓作为输入,并返回一个元组,其中包括边界框的x和y坐标以及宽度和高度。

最小区域矩形:使用 cv2.minAreaRect() 函数可以计算轮廓的最小区域矩形。该函数将轮廓作为输入,并返回一个元组,其中包括矩形的中心坐标、宽度和高度以及角度。

最小外接圆:使用 cv2.minEnclosingCircle() 函数可以计算轮廓的最小外接圆。该函数将轮廓作为输入,并返回一个元组,其中包括圆心坐标和半径。

这些特征可以用于描述轮廓并提取有用的信息。例如,面积和周长可以用于分类和识别物体,质心可以用于跟踪物体的运动,边界框和最小区域矩形可以用于确定物体的位置和方向,最小外接圆可以用于确定物体的大小。

图像矩

图像矩可以帮助您计算一些特征,如物体的质心、物体的面积等。函数 cv.moments() 提供了一个计算出所有矩值的字典。代码如下:import numpy as np
import cv2 as cvimg = cv.imread('star.jpg', 0)
ret, thresh = cv.threshold(img, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, 1, 2)cnt = contours[0]
M = cv.moments(cnt)
print(M)

在这个M中,你可以提取有用的数据,如面积,质心等等。质心由如下关系式给出:
在这里插入图片描述
代码如下:

cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])

轮廓面积
轮廓面积可以通过函数 cv.contourArea() 或者是 M[‘m00’] 得到。

area = cv.contourArea(cnt)

轮廓周长
它也被称为弧长。它可以由函数 cv.arcLength() 得到。第二个参数需要指名形状是否闭合,闭合传入 True,否则传入 False。

perimeter = cv.arcLength(cnt, True)

轮廓近似
OpenCV中的approxPolyDP()函数是一个实现了Douglas-Peucker算法的轮廓近似函数。该函数可以将一个轮廓形状近似为另一个顶点数量较少的形状,精度取决于我们指定的参数epsilon。

例如,如果我们想要在图像中找到一个正方形,但由于图像中的噪声或其他因素,我们无法得到完美的正方形轮廓。此时,我们可以使用approxPolyDP()函数来近似轮廓形状,从而得到更接近真实形状的结果。在这种情况下,我们需要选择一个合适的epsilon值来控制近似精度。通常建议将epsilon设置为原始轮廓周长的一定比例,例如0.1*cv.arcLength(cnt, True)。

使用approxPolyDP()函数可以减少轮廓的顶点数量,从而提高图像处理和分析的效率和准确性。

epsilon = 0.1*cv.arcLength(cnt, True)
approx = cv.approxPolyDP(cnt, epsilon, True)

凸包

hull = cv.convexHull(points[, hull[, clockwise[, returnPoints]]])

参数详细信息:

•points 是我们穿过的轮廓。
•clockwise:方向标志。如果为True,则输出凸包的方向为顺时针方向。否则,其方向为逆时针方向。
•returnPoints:默认情况下为True。它会返回外壳点的坐标。如果为False,则返回与外壳点相对应的轮廓点的索引。

所以要得到上图中的凸包,以下就足够了:

hull = cv.convexHull(cnt)

但是,如果要查找凸性缺陷,则需要传递returnPoints=False。为了理解它,我们将拍摄上面的矩形图像。首先我发现它的轮廓是cnt。现在我找到了它的凸包,returnPoints=True,我得到了以下值:[[234 202]],[[51 202]],[[51 79]],[[234 79]],它们是矩形的四个角点。现在,如果returnPoints=False也这样做,我得到以下结果:[[129],[67],[0],[142]]。这些是等高线中对应点的索引。例如,检查第一个值:cnt[129]=[[234202]],该值与第一个结果相同(其他值依此类推)。

cv2.convexHull()函数的语法如下:

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

其中,参数的详细信息如下:

• points:表示我们要找凸包的轮廓。

• clockwise:方向标志。如果为True,则输出凸包的方向为顺时针方向;否则,其方向为逆时针方向。

• returnPoints:默认情况下为True。它会返回外壳点的坐标。如果为False,则返回与外壳点相对应的轮廓点的索引。

因此,如果我们只需要得到轮廓的凸包,则可以使用以下代码:

hull = cv2.convexHull(cnt)

但是,如果需要查找凸性缺陷,则需要将returnPoints设置为False。为了更好地理解其含义,考虑以下矩形图像。首先,我们找到了矩形的轮廓cnt。接着,我们使用returnPoints=True选项来计算其凸包,得到以下四个点的坐标值:[[234 202]],[[51 202]],[[51 79]],[[234 79]]。这些坐标值是矩形四个角的点。现在,如果我们将returnPoints设置为False,得到的将是以下四个点的索引值:[[129], [67], [0], [142]]。这些是轮廓数组中对应点的索引值。例如,第一个值129表示cnt[129]=[[234 202]],该值与前面求得的第一个凸包点的坐标值相同(其他索引值也类似)。

检查凸性
有一个函数可以检查曲线是否是凸的,cv.isContourConvex()。它只返回True或False。

k = cv.isContourConvex(cnt)

边界矩形

边界矩形是用于包围对象或轮廓的矩形形状。有两种类型的边界矩形:

7.a. 直边界矩形:
直边界矩形是一个简单的矩形,不考虑对象的旋转。它可以通过使用cv2.boundingRect()函数来找到。该函数返回一个四元组(x,y,w,h),其中(x,y)表示矩形左上角的坐标,(w,h)表示矩形的宽度和高度。

x, y, w, h = cv2.boundingRect(cnt)
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)

以上代码将在图像img上绘制一个矩形,框住了轮廓cnt所代表的对象。

7.b. 旋转矩形:
旋转矩形是根据对象的最小面积绘制的矩形,并考虑了对象的旋转。要获得旋转矩形,可以使用cv2.minAreaRect()函数。该函数返回一个Box2D结构,其中包含矩形的中心坐标(x,y)、宽度和高度(w,h),以及旋转角度。

要绘制旋转矩形,我们需要得到矩形的四个角点。可以使用cv2.boxPoints()函数获得这些角点,该函数将旋转矩形作为参数,并返回一个数组包含四个角点的坐标。

rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(img, [box], 0, (0, 0, 255), 2)

以上代码将在图像img上绘制一个红色边界框,该边界框是根据轮廓cnt的最小面积旋转矩形计算而来。
最小外接圆

# 导入OpenCV库
import cv2 as cv# 使用cv.minEnclosingCircle()找到最小外接圆
(x, y), radius = cv.minEnclosingCircle(cnt)
center = (int(x), int(y))
radius = int(radius)# 在图像上绘制最小外接圆
cv.circle(img, center, radius, (0, 255, 0), 2)# 显示图像
cv.imshow('最小外接圆', img)

拟合椭圆

# 使用cv.fitEllipse()将椭圆拟合到对象上
ellipse = cv.fitEllipse(cnt)# 在图像上绘制拟合的椭圆
cv.ellipse(img, ellipse, (0, 255, 0), 2)# 显示图像
cv.imshow('拟合椭圆', img)

直线拟合

# 获取图像的行和列数
rows, cols = img.shape[:2]# 使用cv.fitLine()将直线拟合到一组点上
[vx, vy, x, y] = cv.fitLine(cnt, cv.DIST_L2, 0, 0.01, 0.01)
lefty = int((-x * vy / vx) + y)
righty = int(((cols - x) * vy / vx) + y)# 在图像上绘制拟合的直线
cv.line(img, (cols - 1, righty), (0, lefty), (0, 255, 0), 2)# 显示图像
cv.imshow('直线拟合', img)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/154645.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割7(数据预处理)

在上一节:【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割6(数据预处理) 中,我们已经得到了与mhd图像同seriesUID名称的mask nrrd数据文件了,可以说是一一对应了。 并且,mask的文件,还根据结…

FANUC机器人PRIO-621和PRIO-622设备和控制器没有运行故障处理

FANUC机器人PRIO-621和PRIO-622设备和控制器没有运行故障处理 如下图所示,新的机器人开机后提示报警: PRIO-621 设备没有运行 PRIO-622 控制器没有运行 我们首先查看下手册上的报警代码说明,如下图所示, 如下图所示&#xff0c…

DSP 开发例程(5): tcp_server

目录 DSP 开发例程(5): tcp_server创建工程源码编辑tcp_echo.chelloWorld.c 调试说明 DSP 开发例程(5): tcp_server 此例程实现在 EVM6678L 开发板上创建 TCP Server进程, 完成计算机与开发板之间的 TCP/IP 通信. 例程源码可从我的 gitee 仓库上克隆或下载. 点击 DSP 开发教程…

IDEA MyBatisX插件介绍

一、前言 前几年写代码的时候,要一键生成DAO、XML、Entity基础代码会采用第三方工具,比如mybatis-generator-gui等,现在IDEA或Eclipse都有对应的插件,像IDEA中MyBatisX就是一个比较好用的插件。 二、MyBatisX安装配置使用 MyBa…

【UE 模型描边】UE5中给模型描边 数字孪生 智慧城市领域 提供资源下载

目录 0 引言1 Soft Outlines1.1 虚幻商城1.2 使用步骤 2 Auto Mesh Outlines2.1 虚幻商城2.2 使用步骤 3 Survivor Vision3.1 虚幻商城3.2 使用步骤 结尾 🙋‍♂️ 作者:海码007📜 专栏:UE虚幻引擎专栏💥 标题&#xf…

大数据-Storm流式框架(三)--Storm搭建教程

一、两种搭建方式 1、storm单节点搭建 2、完全分布式搭建 二、storm单节点搭建 准备 下载地址:Index of /dist/storm 1、环境准备: Java 6 Python 2.6.6 2、上传、解压安装包 3、在storm目录中创建logs目录 mkdir logs 启动 ./storm help …

原型和原型链的理解

记住一句话:万物皆对象 对于原型和原型链,我们要知道一下几个:函数对象,实例对象、原型对象 1)函数对象——就是平时称的对象; 2)实例对象——new出的对象或者{ }; 3)原型…

Jenkins项目部署

使用jenkins部署项目 简易版使用jenkins部署项目 将war包部署到tomcat中 将已有的war包部署到tomcat中(jenkins与tomcat在同一台主机) 点击Jenkins主页的新建任务 输入任务名称 选择构建一个自由风格的软件项目后点击确定 在构建内添加构建步骤,选择执行shell 输入…

【Android】Android Framework系列---CarPower电源管理

Android Framework系列—CarPower电源管理 智能座舱通常包括中控系统、仪表系统、IVI系统 、后排娱乐、HUD、车联网等。这些系统需要由汽车电源进行供电。由于汽车自身的特殊供电环境(相比手机方便的充电环境,汽车的蓄电池如果没有电是需要专业人士操作…

使用 node.js 简单搭建Web服务 使用node简单搭建后端服务 使用node搭建服务

使用 node.js 简单搭建Web服务 使用node简单搭建后端服务 使用node搭建服务 1、初始化项目2、安装 Express.js Web 服务框架3、创建 app.js 主入口文件, 并且实现 GET、POST请求4、启动服务5、请求测试 1、初始化项目 例如项目名为 node-server-demo mkdir node-server-demo进…

GEO生信数据挖掘(十一)STRING数据库PPI蛋白互作网络 Cytoscape个性化绘图【SCI 指日可待】

GEO生信数据挖掘(十)肺结核数据-差异分析-WGCNA分析(900行代码整理注释更新版本) 通过 前面十篇文章的学习,我们应该已经可以获取到一个”心仪的基因列表“了,相较于原始基因数量,这个列表的数…

数据结构与算法解析(C语言版)--搭建项目环境

本栏目致力于从0开始使用纯C语言将经典算法转换成能够直接上机运行的程序,以项目的形式详细描述数据存储结构、算法实现和程序运行过程。 参考书目如下: 《数据结构C语言版-严蔚敏》 《数据结构算法解析第2版-高一凡》 软件工具: dev-cpp 搭…