教程3_图像的轮廓

目录

目标

1. 特征矩

2、轮廓质心

3. 轮廓面积

4. 轮廓周长

5. 轮廓近似

6. 轮廓凸包

7. 边界矩形

7.1.直角矩形

7.2. 旋转矩形

8. 最小闭合圈

9. 拟合一个椭圆

10. 拟合直线


目标

        在本文中,我们将学习 - 如何找到轮廓的不同特征,例如面积,周长,质心,边界框等。 - 您将看到大量与轮廓有关的功能。

1. 特征矩

        特征矩可以帮助您计算一些特征,例如物体的质心,物体的面积等。请查看特征矩上的维基百科页面。函数 cv.moments() 提供了所有计算出的矩值的字典。见下文:

import numpy as np
import cv2 as cv
img = 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 )

        从这一刻起,您可以提取有用的数据,例如面积,质心等。

2、轮廓质心

        质心由关系给出,cx=M10/M00 和 cy=M01/M00。可以按照以下步骤进行,第一个示例为简单的检测单个轮廓,第二个示例能检测图片中的多个轮廓。

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 )cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])print('轮廓的质心坐标为:(%d,%d) '%cx %cy)
import cv2  
import numpy as np  # 读取图像  
image = cv2.imread('7.jpg')  # 转换为灰度图像  
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 应用阈值来获取二值图像  
_, thresholded = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)  # 查找轮廓  
contours, _ = cv2.findContours(thresholded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  # 遍历每个轮廓  
for contour in contours:  # 计算轮廓的矩  M = cv2.moments(contour)  # 检查矩是否存在(轮廓不为空)  if M["m00"] != 0:  # 计算质心  cX = int(M["m10"] / M["m00"])  cY = int(M["m01"] / M["m00"])  # 在图像上绘制质心  cv2.circle(image, (cX, cY), 5, (255, 0, 0), -1)  cv2.putText(image, "centroid", (cX - 25, cY - 25), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)  # 显示结果图像  
cv2.imshow('Image with Centroids', image)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

3. 轮廓面积

        轮廓区域由函数 cv.contourArea() 或从矩 M['m00'] 中给出。

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 )area = cv.contourArea(cnt) 

4. 轮廓周长

        也称为弧长。可以使用 cv.arcLength() 函数找到它。第二个参数指定形状是闭合轮廓(True)还是曲线。

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 )perimeter = cv.arcLength(cnt,True)

5. 轮廓近似

        根据我们指定的精度,它可以将轮廓形状近似为顶点数量较少的其他形状。它是Douglas-Peucker算法的实现。检查维基百科页面上的算法和演示。

        为了理解这一点,假设您试图在图像中找到一个正方形,但是由于图像中的某些问题,您没有得到一个完美的正方形,而是一个“坏形状”(如下图所示)。现在,您可以使用此功能来近似形状。在这种情况下,第二个参数称为epsilon,它是从轮廓到近似轮廓的最大距离。它是一个精度参数。需要正确选择epsilon才能获得正确的输出。

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 )epsilon = 0.1*cv.arcLength(cnt,True) 
approx = cv.approxPolyDP(cnt,epsilon,True)

        在第二张图片中,绿线显示了ε=弧长的10%时的近似曲线。第三幅图显示了ε=弧长度的1%时的情况。第三个参数指定曲线是否闭合。 

6. 轮廓凸包

        凸包外观看起来与轮廓逼近相似,但不相似(在某些情况下两者可能提供相同的结果)。在这里,cv.convexHull()函数检查曲线是否存在凸凹缺陷并对其进行校正。一般而言,凸曲线是始终凸出或至少平坦的曲线。如果在内部凸出,则称为凸度缺陷。例如,检查下面的手的图像。红线显示手的凸包。双向箭头标记显示凸度缺陷,这是凸包与轮廓线之间的局部最大偏差。

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 )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] = [[234,202]]与第一个结果相同(对于其他结果依此类推)。

7. 边界矩形

有两种类型的边界矩形。

7.1.直角矩形

        它是一个矩形,不考虑物体的旋转。所以边界矩形的面积不是最小的。它是由函数cv.boundingRect()找到的。

        令(x,y)为矩形的左上角坐标,而(w,h)为矩形的宽度和高度。

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 )x,y,w,h = cv.boundingRect(cnt)
cv.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
7.2. 旋转矩形

        这里,边界矩形是用最小面积绘制的,所以它也考虑了旋转。使用函数是 cv.minAreaRect()。它返回一个Box2D结构,其中包含以下细节 -(中心(x,y),(宽度,高度),旋转角度)。但要画出这个矩形,我们需要矩形的四个角。它由函数 cv.boxPoints() 获得:

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 )rect = cv.minAreaRect(cnt)
box = cv.boxPoints(rect)
box = np.int0(box)
cv.drawContours(img,[box],0,(0,0,255),2)

        两个矩形都显示在一张单独的图像中。绿色矩形显示正常的边界矩形。红色矩形是旋转后的矩形。

8. 最小闭合圈

        接下来,使用函数 cv.minEnclosingCircle() 查找对象的圆周。它是一个以最小面积完全覆盖物体的圆。

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 )(x,y),radius = cv.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
cv.circle(img,center,radius,(0,255,0),2)

 

9. 拟合一个椭圆

        下一个是把一个椭圆拟合到一个物体上。它返回内接椭圆的旋转矩形。

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 )ellipse = cv.fitEllipse(cnt)
cv.ellipse(img,ellipse,(0,255,0),2)

 

10. 拟合直线

        同样,我们可以将一条直线拟合到一组点。下图包含一组白点。我们可以近似一条直线。

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 )rows,cols = img.shape[:2]
[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)

12. 长宽比

        它是对象边界矩形的宽度与高度的比值。

x,y,w,h = cv.boundingRect(cnt)
aspect_ratio = float(w)/h

12. 范围

        范围是轮廓区域与边界矩形区域的比值。

area = cv.contourArea(cnt)
x,y,w,h = cv.boundingRect(cnt)
rect_area = w*h
extent = float(area)/rect_area

13. 坚实度

        坚实度是等高线面积与其凸包面积之比。

area = cv.contourArea(cnt)
hull = cv.convexHull(cnt)
hull_area = cv.contourArea(hull)
solidity = float(area)/hull_area

14. 等效直径

        等效直径是面积与轮廓面积相同的圆的直径。

area = cv.contourArea(cnt)
equi_diameter = np.sqrt(4*area/np.pi)

15. 取向

        取向是物体指向的角度。以下方法还给出了主轴和副轴的长度。

(x,y),(MA,ma),angle = cv.fitEllipse(cnt)

16. 掩码和像素点

        在某些情况下,我们可能需要构成该对象的所有点。可以按照以下步骤完成:

mask = np.zeros(imgray.shape,np.uint8)
cv.drawContours(mask,[cnt],0,255,-1)
pixelpoints = np.transpose(np.nonzero(mask))
#pixelpoints = cv.findNonZero(mask)

        这里提供了两个方法,一个使用Numpy函数,另一个使用OpenCV函数(最后的注释行)。结果也是一样的,只是略有不同。Numpy给出的坐标是(行、列)格式,而OpenCV给出的坐标是(x,y)格式。所以基本上答案是可以互换的。注意,row = x, column = y

17. 最大值,最小值和它们的位置

        我们可以使用掩码图像找到这些参数。

min_val, max_val, min_loc, max_loc = cv.minMaxLoc(imgray,mask = mask)

18. 平均颜色或平均强度

        在这里,我们可以找到对象的平均颜色。或者可以是灰度模式下物体的平均强度。我们再次使用相同的掩码进行此操作。

mean_val = cv.mean(im,mask = mask)

19. 极端点

        极点是指对象的最顶部,最底部,最右侧和最左侧的点。

leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])
rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])
topmost = tuple(cnt[cnt[:,:,1].argmin()][0])
bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])

        例如,如果我将其应用于印度地图,则会得到以下结果: 

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

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

相关文章

【Java】LinkedList vs. ArrayList:Java中的数据结构选择

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌…

uniapp开发小程序遇到的问题,持续更新中

一、uniapp引入全局scss 在App.vue中引入uni.scss <style lang"scss">/* #ifndef APP-NVUE */import "uni.scss";/* #endif */ </style>注意&#xff1a;nvue页面的样式在编译时&#xff0c;有很多样式写法被限制了&#xff0c;容易报错。所…

【C++ leetcode】双指针(专题完结)

15. 三数之和 题目 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的…

面试经典150题【101-110】

文章目录 面试经典150题【101-110】9.回文数61.加一172.阶乘后的069.x的平方根50.Pow(x,n)149.直线上最多的点数52.N皇后II120.三角形最小路径和64.最小路径和63.不同路径II 面试经典150题【101-110】 6道偏数学的题和4道二维dp 9.回文数 一开始想转为字符串再判断。后来发现…

信号处理--基于混合CNN和transfomer自注意力的多通道脑电信号的情绪分类的简单应用

目录 关于 工具 数据集 数据集简述 方法实现 数据读取 ​编辑数据预处理 传统机器学习模型(逻辑回归&#xff0c;支持向量机&#xff0c;随机森林) 多层感知机模型 CNNtransfomer模型 代码获取 关于 本实验利用结合了卷积神经网络 (CNN) 和 Transformer 组件的混合…

windows下powershell与linux下bash美化教程(使用starship)

starship美化教程 Win11 Powershell 安装 在命令行使用下面命令安装 # 安装starship winget install starship将以下内容添加到 Microsoft.PowerShell_profile.ps1&#xff0c;可以在 PowerShell 通过 $PROFILE 变量来查询文件的位置 Invoke-Expression (&starship i…

web学习笔记(四十五)Node.js

目录 1. Node.js 1.1 什么是Node.js 1.2 为什么要学node.js 1.3 node.js的使用场景 1.4 Node.js 环境的安装 1.5 如何查看自己安装的node.js的版本 1.6 常用终端命令 2. fs 文件系统模块 2.1引入fs核心模块 2.2 读取指定文件的内容 2.3 向文件写入指定内容 2.4 创…

yarn按包的时候报错 ../../../package.json: No license field

运行 yarn config list 然后运行 yarn config set strict-ssl false 之后yarn就成功了

基于SpringBoot“网上选课系统”设计和实现(源码定制以及咨询!!)

博主介绍&#xff1a;✌全网粉丝10W,B站项目阿龙、csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、华为云获奖者&#xff0c;“程序员阿龙”✌ 主要内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python&#xff0c;MYSQL、Hodpoo…

SpringBoot2.6.3 + knife4j-openapi3

1.引入项目依赖&#xff1a; <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-spring-boot-starter</artifactId><version>4.5.0</version> </dependency> 2.新增配置文件 import io.swag…

Docker搭建LNMP环境实战(05):CentOS环境安装Docker-CE

前面几篇文章讲了那么多似乎和Docker无关的实战操作&#xff0c;本篇总算开始说到Docker了。 1、关于Docker 1.1、什么是Docker Docker概念就是大概了解一下就可以&#xff0c;还是引用一下百度百科吧&#xff1a; Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以…

【机器学习之---数学】随机游走

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 随机游走 1. 概念 1.1 例1 在你的饮食俱乐部度过了一个富有成效的晚上后&#xff0c;你在不太清醒的状态下离开了。因此&#xff0c;你会醉醺醺地在展…

数据结构(五)单链表专题

在开始之前&#xff0c;我先来给大家讲一下顺序表与链表的区别&#xff1a; 它们在堆上存储的差异&#xff1a; 我们可以很容易的知道&#xff0c;循序表是连续的有序的&#xff0c;但链表是杂乱的&#xff0c;它们通过地址彼此联系起来。 1. 链表的概念及结构 概念&#xff1…

智慧交通(代码实现案例)

1.项目简介 目标: 了解智慧交通项目的架构知道智慧交通项目中的模块能够完成智慧交通项目的环境搭建 该项目是智慧交通项目&#xff0c;通过该项目掌握计算机视觉的方法在交通领域的相关应用&#xff0c;包括车道线检测的方法&#xff0c;多目标车辆追踪及流量统计方法&#…

Linux Tomcat的服务器如何查看接口请求方式?

问题描述 最近在和安卓开发对接接口&#xff0c;遇到一个接口总是报405错误&#xff0c;有对接经验的开发应该都知道是请求方式不对&#xff0c;假如接口定义为POST请求的&#xff0c;但是客户端却用GET请求&#xff0c;这时候就会报这个错误。Android客户端那边使用xUtils框架…

【小白入门篇3】还是GPT4更香

上一节文章《【小白入门篇2】总有一款AI工具适合你》介绍了很多ai产品给大家&#xff0c;有同学私信我&#xff0c;国内工具还是比较差&#xff0c;还是想用gpt4模型。这个章节介绍一些gpt4工具给大家, 其中大部分都只有一些免费的次数, 而且都需要kx上网才能访问。 OpenAI ch…

浙大版《C语言程序设计(第4版)》题目集-练习4-7 求e的近似值

自然常数 e 可以用级数 1 1 / 1 ! 1 / 2 ! ⋯ 1 / n ! ⋯ 11/1!1/2!⋯1/n!⋯ 11/1!1/2!⋯1/n!⋯来近似计算。本题要求对给定的非负整数 n&#xff0c;求该级数的前 n1 项和。 输入格式: 输入第一行中给出非负整数 n&#xff08;≤1000&#xff09;。 输出格式: 在一行…

记录一下安装ubuntu子系统的pycharm遇到的问题

sudo su #切换为root用户获取管理员权限用于新建用户 adduser username #新建用户&#xff08;例如用户名为username&#xff09; adduser username sudo #将用户添加到 sudo 组同样遇到这个问题&#xff0c;解决方法是&#xff1a;先新建一个用户名&#xff0c;然后再切换到这…

Android 性能优化实例分享-内存优化 兼顾效率与性能

背景 项目上线一段时间后,回顾重要页面 保证更好用户体验及生产效率&#xff0c;做了内存优化和下载导出优化&#xff0c;具体效果如最后的一节的表格所示。 下面针对拍摄流程的两个页面 预览页 导出页优化实例进行介绍&#xff1a; 一.拍摄前预览页面优化 预览效果问题 存在…

Quartus II仿真出现错误

ModelSim executable not found in D:/intelFPGA/18.0/quartus/bin64/modelsim_ase/win32aloem/ Error. 找不到modelsim地址&#xff0c;原来是我下载了.exe,但没有双击启动安装ase文件夹呀&#xff01;&#xff01;&#xff01;&#xff01;晕&#xff0c;服了我自己