15-轮廓检测

边缘是零零散散的,而轮廓是一个整体
cv2.findContours(img,mode,method)
img:输入图像对象名称
mode:轮廓检索模式

RETR_EXTERNAL:只检索最外面的轮廓
RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中
RETR_CCOMP:检索所有的轮廓,并将他们组织为两层;顶层是各部分的外部边界,第二层为空洞的边界
RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次(最常用)

method:轮廓逼近方法

CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)
CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分

为了更高的精确率,尽量最好使用二值图像

import cv2
import numpy as np
from matplotlib import pyplot as pltdef show_photo(name,picture):#图像显示函数cv2.imshow(name,picture)cv2.waitKey(0)cv2.destroyAllWindows()#做之前需要对照片进行二值处理
img = cv2.imread('E:\Jupyter_workspace\study\data/cfx.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换为灰度图
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)#对图像进行二值处理,小于127为0,大于127为255
show_photo('thresh',thresh)binary, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)show_photo('binary',binary)#就是作完二值操作的结果np.array(contours).shape#是一群list结构的轮廓点,保存一些轮廓的信息
#结果为:(2,)#hierarchy是一个层级,把结果全部保存到层级里面

二值处理后的图像
在这里插入图片描述
binary参数实则就是二值处理后的图像
在这里插入图片描述

绘制轮廓

cv2.drawContours(draw_img,contours,-1,(0,0,255),2)

参数1:一个照片对象名称
参数2:轮廓是什么
参数3:画第几个轮廓,-1表示把所有的轮廓都画出来
参数4:(B,G,R)画轮廓的线是什么颜色的
参数5:线条的宽度
import cv2
import numpy as np
from matplotlib import pyplot as pltdef show_photo(name,picture):#图像显示函数cv2.imshow(name,picture)cv2.waitKey(0)cv2.destroyAllWindows()#做之前需要对照片进行二值处理
img = cv2.imread('E:\Jupyter_workspace\study\data/cfx.png')
show_photo('img ',img )gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换为灰度图
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)#对图像进行二值处理,小于127为0,大于127为255
binary, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)draw_img = img.copy()#注意一定要copy要不然会对原图进行改变!!!
res = cv2.drawContours(draw_img,contours,-1,(0,0,255),2)#-1表示显示所有轮廓,(0,0,225)BGR表示红色,2为轮廓粗细
show_photo('-1 is All',res)draw_img = img.copy()#注意一定要copy要不然会对原图进行改变!!!
res = cv2.drawContours(draw_img,contours,0,(0,0,255),2)#0表示显示第0个轮廓,(0,0,225)BGR表示红色,2为轮廓粗
show_photo('zero',res)draw_img = img.copy()#注意一定要copy要不然会对原图进行改变!!!
res = cv2.drawContours(draw_img,contours,1,(0,0,255),2)#1表示显示第1个轮廓,(0,0,225)BGR表示红色,2为轮廓粗
show_photo('one',res)

原图:
在这里插入图片描述
显示所有轮廓(里外)
在这里插入图片描述
显示第0个轮廓(外)
在这里插入图片描述
显示第1个轮廓(内)
在这里插入图片描述

轮廓特征

import cv2
import numpy as np
from matplotlib import pyplot as pltdef show_photo(name,picture):#图像显示函数cv2.imshow(name,picture)cv2.waitKey(0)cv2.destroyAllWindows()img = cv2.imread('E:\Jupyter_workspace\study\data/cfx.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换为灰度图
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)#对图像进行二值处理,小于127为0,大于127为255
binary, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)cnt = contours[0]#contours存放所有轮廓的信息,这里取第一个轮廓cv2.contourArea(cnt)#第一个轮廓所对应的面积
#结果为:20909.0cv2.arcLength(cnt,True)#第一个轮廓所对应的周长,True表示闭合的
#结果为:612.0

轮廓近似

轮廓近似:举例子拿曲线AB进行近似计算

1,首先直线连接AB,再曲线AB上找到离AB直线最远的一点C,点C到直线AB的距离为d1
2,用户需要自定义一个值epsilon作为阈值
3,将d1与阈值epsilon进行比较;若d1 < epsilon可直接将直线AB代替曲线AB,近似结束若d1 > epsilon则,连接直线AC和直接BC在曲线AC上找离直线AC最短的一点D,点D到直线AC的距离为d2若d2 < epsilon可直接将直线AC代替曲线AC若d2 > epsilon则做同样的操作在曲线BC上找离直线BC最短的一点E,点E到直线BC的距离为d3同样的操作

在这里插入图片描述

import cv2
import numpy as np
from matplotlib import pyplot as pltdef show_photo(name,picture):#图像显示函数cv2.imshow(name,picture)cv2.waitKey(0)cv2.destroyAllWindows()img = cv2.imread('E:\Jupyter_workspace\study\data/lunkuo.png')
show_photo('img ',img )gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)cnt = contours[0]draw_img = img.copy()
res =cv2.drawContours(draw_img,[cnt],-1,(0,0,255),2)
show_photo('res',res)

原图:
在这里插入图片描述
轮廓近似后效果
在这里插入图片描述

近似函数:

cv2.approxPolyDP(cnt,epsilon,True)

参数1:传入要近似的轮廓
参数2:自定义一个值来进行轮廓比较,一般是按周长的百分比进行设置的
参数3:轮廓是否封闭
import cv2
import numpy as np
from matplotlib import pyplot as pltdef show_photo(name,picture):#图像显示函数cv2.imshow(name,picture)cv2.waitKey(0)cv2.destroyAllWindows()img = cv2.imread('E:\Jupyter_workspace\study\data/lunkuo.png')
show_photo('img ',img )gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)epsilon = 0.1*cv2.arcLength(cnt,True)#倍数越小越接近本身轮廓
approx = cv2.approxPolyDP(cnt,epsilon,True)draw_img = img.copy()
res =cv2.drawContours(draw_img,[approx],-1,(0,0,255),2)
show_photo('res',res)

原图:
在这里插入图片描述
近似函数处理过后的图像:
在这里插入图片描述

边界矩形

获得轮廓的边缘矩形:cv2.boundingRect(cnt)

参数:指定操作的对象是哪个轮廓
返回值:轮廓对应的边缘矩形的x,y坐标和w,h宽高值
import cv2
import numpy as np
from matplotlib import pyplot as pltdef show_photo(name,picture):#图像显示函数cv2.imshow(name,picture)cv2.waitKey(0)cv2.destroyAllWindows()img = cv2.imread('E:\Jupyter_workspace\study\data/lunkuo1.png')
show_photo('img',img)#原图gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
res, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = contours[0]#这里的轮廓取得是第0个,当然也可以取其他的轮廓x, y, w, h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
show_photo('img',img)area = cv2.contourArea(cnt)#轮廓面积
x, y, w, h = cv2.boundingRect(cnt)
rect_area = w * h #轮廓对应的边缘矩形的面积,宽×高为对应边缘矩形的面积
extent = float(area) / rect_area
print('轮廓面积与边界矩形之比',extent)
#结果为:轮廓面积与边界矩形之比 0.5113636363636364

原图:
在这里插入图片描述
获取第0个轮廓边界矩形:
在这里插入图片描述

外接圆

import cv2
import numpy as np
from matplotlib import pyplot as pltdef show_photo(name,picture):#图像显示函数cv2.imshow(name,picture)cv2.waitKey(0)cv2.destroyAllWindows()img = cv2.imread('E:\Jupyter_workspace\study\data/lunkuo1.png')
show_photo('img',img)gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
res, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = contours[0]#对轮廓0操作,当然也可以换成其他的轮廓x, y, w, h = cv2.boundingRect(cnt)
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
img = cv2.circle(img,center,radius,(0,255,0),2)#(B,G,R),2为轮廓粗细程度
show_photo('img',img)

原图:
在这里插入图片描述
对第0轮廓进行外接圆操作:
在这里插入图片描述

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

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

相关文章

抛硬币仿真实验java_探索HyperLogLog算法(含Java实现)

引言HyperLogLog算法经常在数据库中被用来统计某一字段的Distinct Value(下文简称DV)&#xff0c;比如Redis的HyperLogLog结构&#xff0c;出于好奇探索了一下这个算法的原理&#xff0c;无奈中文资料很少&#xff0c;只能直接去阅读论文以及一些英文资料&#xff0c;总结成此文…

kotlin键值对数组_Kotlin程序以升序对数组进行排序

kotlin键值对数组Given an array, we have to sort its elements in ascending order. 给定一个数组&#xff0c;我们必须按升序对其元素进行排序。 Example: 例&#xff1a; Input:arr [10, 20, 5, 2, 30]Output:sorted array (Ascending Order): [2, 5, 10, 20, 30]在Kotl…

微机原理——总线和时序

前提 8088有两个组态&#xff1a; 最大组态和最小组态&#xff0c;通过引脚MN/MX*的电平决定组态。&#xff08;*表示低电平有效&#xff09; 两种组态没有本质区别。 8088的引脚&#xff1a; 引脚可分为下面几种类别&#xff1a; 1、数据和地址引脚 2、读写控制引脚 3、中断…

PHP站内搜索:多关键字查找,加亮显示

1、SQL语句中的模糊查找LIKE条件一般用在指定搜索某字段的时候, 通过"% _" 通配符的作用实现模糊查找功能&#xff0c;通配符可以在前面也可以在后面或前后都有。搜索以PHP100开头&#xff1a; SELECT * FROM teble WHERE title LIKE PHP100% 搜索以PHP100结束&…

16-模板匹配

cv2.matchTemplate(img,template,cv2.TM_SQDIFF) 参数一&#xff1a;原图图像对象名称 参数二&#xff1a;模板图像对象名称 参数三&#xff1a;差别程度的计算方法(六选一推荐使用带归一化的) 模板匹配和卷积原理很像&#xff0c;模板从原图像上从原点开始滑动&#xff0c;计…

对MySQL性能影响关系紧密的五大配置参数

以下的文章主要是对MySQL性能影响关系紧密的五大配置参数的介绍&#xff0c;我前几天在相关网站看见对MySQL性能影响关系紧密的五大配置参数的资料&#xff0c;觉得挺好&#xff0c;就拿出来供大家分享&#xff0c;望你能有所收获。(一)连接 连接通常来自Web服务器&#xff0c;…

JAVA安装作用_jdk安装配置及其作用

2.安装好了就是去配置路径了&#xff0c;我的是win7系统&#xff0c;步骤如下&#xff1a;桌面上的计算机右击-》高级系统设置—》环境变量-》系统变量-》新建一共要新建三个变量JAVA_HOME,PATH和CLASSPATH1>JAVA_HOME:(这么写为了方便以后可能改动jdk的安装路径&#xff0c…

用C#开发Windows应用程序

To develop windows application, we need to using studio and follow some steps: 要开发Windows应用程序 &#xff0c;我们需要使用studio并遵循一些步骤&#xff1a; Step 1) First of all we launch visual studio. 步骤1)首先&#xff0c;我们启动Visual Studio。 Ste…

图像分割——基于二维灰度直方图的阈值处理

前言 像素灰度值仅仅反映了像素灰度级的幅值大小&#xff0c;并没有反映出像素与邻域的空间相关信息。 二维灰度直方图的概念 二维灰度直方图&#xff1a;像素的灰度值分布和邻域的平均灰度值分布构成的二维直方图 二维直方图的值N(i,j) 。其中&#xff0c;if(x,y) 图像(x,y…

多维角度聊聊结对编程

在敏捷软件开发的各种实践中&#xff0c;结对编程&#xff08;Pair Programming&#xff0c;下文简称Pair&#xff09;是特别有争议的。Pair有一个特点&#xff0c;那就是还没有进行过任何Pair实践前&#xff0c;你很可能对它已经有了“喜欢” 或者是“讨厌”的印象。如果有人问…

17-直方图

直方图 何为直方图&#xff1f;没那么高大上&#xff0c;其实就是二维统计图。每个照片都是有像素点所组成&#xff0c;当然也是[0,255]&#xff0c;直方图就是统计每个值所对应的像素点有几个。 直方图横坐标表示0-255这些像素点值&#xff1b;纵坐标表示对应像素点值的个数有…

java求水电费_java水电费管理系统

每天记录学习&#xff0c;每天会有好心情。*^_^*今天和一个朋友共同完成了一个基于web的java水电费管理系统项目&#xff0c;我们在开发时选用的框架是SSM(MYECLIPSE)框架。我这个朋友知识有限&#xff0c;只会这个框架&#xff0c;哈哈&#xff0c;都是为了方便他。和往常一样…

zemax微透镜阵列示例_阵列反向! Ruby中的示例方法

zemax微透镜阵列示例阵列反向&#xff01; 方法 (Array reverse! Method) In this article, we will study about Array.reverse! method. You all must be thinking the method must be doing something related to reversing certain elements as we have done in the case o…

Opencv实战【1】人脸检测并对ROI区域进行部分处理(变身乔碧萝!!!)

步骤&#xff1a; 1、利用Opencv自带的分类器检测人脸 预备知识&#xff1a;Haar特征分类器 Haar特征分类器就是一个XML文件&#xff0c;该文件中会描述人体各个部位的Haar特征值。包括人脸、眼睛、嘴唇等等。 Haar特征分类器存放地址&#xff1a; &#xff08;找自己的安装…

【黑马甄选离线数仓day10_会员主题域开发_DWS和ADS层】

day10_会员主题域开发 会员主题_DWS和ADS层 DWS层开发 门店会员分类天表: 维度指标: 指标&#xff1a;新增注册会员数、累计注册会员数、新增消费会员数、累计消费会员数、新增复购会员数、累计复购会员数、活跃会员数、沉睡会员数、会员消费金额 维度: 时间维度&#xff08…

iPad和iPhone的app图标尺寸、用途、设置方法

下面是在iPhone专用程序、iPad专用程序和通用程序中使用图标文件的指导&#xff0c;由译言网翻译自苹果官方文档。原文 http://article.yeeyan.org/view/395/100567 注意&#xff1a;图标是你的程序包所必需的组成部分。如果你没有提供程 序所需的各种尺寸的图标&#xff0c;系…

18-傅里叶变化

以时间为参照就是时域分析&#xff0c;当然时间是动态变化的 而傅里叶变换是以频域为基准的&#xff0c;不用关心动态变化&#xff0c;只关心做了多少次而已&#xff0c;次数&#xff0c;频率 傅里叶说过&#xff0c;任何一个周期函数都可以用正弦函数堆叠起来形成。强吧&#…

java中访问修饰符_Java中的非访问修饰符是什么?

java中访问修饰符Java非访问修饰符 (Java non access modifiers) We have 7 non-access modifiers in Java. The name of these non-access modifiers are given below, Java中有7个非访问修饰符 。 这些非访问修饰符的名称如下所示&#xff1a; native 本机 synchronized 已同…

mui实现分享功能_MUI 分享功能(微信、QQ 、朋友圈)

配置文件&#xff1a;manifest.jsonplus ->plugins 下边"share": {/*配置应用使用分享功能&#xff0c;参考http://ask.dcloud.net.cn/article/27*/"qq": {"appid": "",/*腾讯QQ开放平台申请应用的AppID值*/"description"…

Java 注解学习笔记

转自&#xff1a;http://wanqiufeng.blog.51cto.com/409430/458883 一、什么是java注解 注解&#xff0c;顾名思义&#xff0c;注解,就是对某一事物进行添加注释说明&#xff0c;会存放一些信息&#xff0c;这些信息可能对以后某个时段来说是很有用处的。 Java注解又叫java标注…