Python使用Opencv实现边缘检测以及轮廓检测的实现


Posted in Python onDecember 31, 2020

边缘检测

Canny边缘检测器是一种被广泛使用的算法,并被认为是边缘检测最优的算法,该方法使用了比高斯差分算法更复杂的技巧,如多向灰度梯度和滞后阈值化。

Canny边缘检测器算法基本步骤:

  • 平滑图像:通过使用合适的模糊半径执行高斯模糊来减少图像内的噪声。
  • 计算图像的梯度:这里计算图像的梯度,并将梯度分类为垂直、水平和斜对角。这一步的输出用于在下一步中计算真正的边缘。
  • 非最大值抑制:利用上一步计算出来的梯度方向,检测某一像素在梯度的正方向和负方向上是否是局部最大值,如果是,则抑制该像素(像素不属于边缘)。这是一种边缘细化技术,用最急剧的变换选出边缘点。
  • 用滞后阈值化选择边缘:最后一步,检查某一条边缘是否明显到足以作为最终输出,最后去除所有不明显的边缘。

Opencv使用Canny边缘检测相对简单,代码如下:

import cv2
import numpy as np

img = cv2.imread("hammer.jpg", 0)
cv2.imwrite("canny.jpg", cv2.Canny(img, 200, 300))
cv2.imshow("canny", cv2.imread("canny.jpg"))
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

Python使用Opencv实现边缘检测以及轮廓检测的实现

Canny函数的原型为

cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient ]]])

必要参数:
第一个参数是需要处理的原图像,该图像必须为单通道的灰度图;
第二个参数是滞后阈值1;
第三个参数是滞后阈值2。

轮廓检测

轮廓检测主要由cv2.findContours函数实现的。
函数的原型为

cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])

函数参数
第一个参数是寻找轮廓的图像;

第二个参数表示轮廓的检索模式,有四种(本文介绍的都是新的cv2接口):

  • cv2.RETR_EXTERNAL表示只检测外轮廓 。
  • cv2.RETR_LIST检测的轮廓不建立等级关系。
  • cv2.RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
  • cv2.RETR_TREE建立一个等级树结构的轮廓。

第三个参数method为轮廓的逼近方法

  • cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1。
  • cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息。
  • cv2.CHAIN_APPROX_TC89_L1和cv2.CHAIN_APPROX_TC89_KCOS都是使用teh-Chinl chain近似算法。

返回值

如:image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

image:是原图像

contours:图像的轮廓,以列表的形式表示,每个元素都是图像中的一个轮廓。

hier:相应轮廓之间的关系。这是一个ndarray,其中的元素个数和轮廓个数相同,每个轮廓contours[i]对应4个hierarchy元素hierarchy[i][0] ~hierarchy[i][3],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,则该值为负数。

原图:

Python使用Opencv实现边缘检测以及轮廓检测的实现

示例一

import cv2
import numpy as np

img = cv2.pyrDown(cv2.imread("hammer.jpg", cv2.IMREAD_UNCHANGED))
# threshold 函数对图像进行二化值处理,由于处理后图像对原图像有所变化,因此img.copy()生成新的图像,cv2.THRESH_BINARY是二化值
ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY)
# findContours函数查找图像里的图形轮廓
# 函数参数thresh是图像对象
# 层次类型,参数cv2.RETR_EXTERNAL是获取最外层轮廓,cv2.RETR_TREE是获取轮廓的整体结构
# 轮廓逼近方法
# 输出的返回值,image是原图像、contours是图像的轮廓、hier是层次类型
image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for c in contours:
  # 轮廓绘制方法一
  # boundingRect函数计算边框值,x,y是坐标值,w,h是矩形的宽和高
  x, y, w, h = cv2.boundingRect(c)
  # 在img图像画出矩形,(x, y), (x + w, y + h)是矩形坐标,(0, 255, 0)设置通道颜色,2是设置线条粗度
  cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)

  # 轮廓绘制方法二
  # 查找最小区域
  rect = cv2.minAreaRect(c)
  # 计算最小面积矩形的坐标
  box = cv2.boxPoints(rect)
  # 将坐标规范化为整数
  box = np.int0(box)
  # 绘制矩形
  cv2.drawContours(img, [box], 0, (0, 0, 255), 3)

  # 轮廓绘制方法三
  # 圆心坐标和半径的计算
  (x, y), radius = cv2.minEnclosingCircle(c)
  # 规范化为整数
  center = (int(x), int(y))
  radius = int(radius)
  # 勾画圆形区域
  img = cv2.circle(img, center, radius, (0, 255, 0), 2)

# # 轮廓绘制方法四
# 围绕图形勾画蓝色线条
cv2.drawContours(img, contours, -1, (255, 0, 0), 2)
# 显示图像
cv2.imshow("contours", img)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果如图所示:

Python使用Opencv实现边缘检测以及轮廓检测的实现

示例二

import cv2
import numpy as np

img = cv2.pyrDown(cv2.imread("hammer.jpg", cv2.IMREAD_UNCHANGED))
ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY) , 127, 255, cv2.THRESH_BINARY)
# findContours函数查找图像里的图形轮廓
# 函数参数thresh是图像对象
# 层次类型,参数cv2.RETR_EXTERNAL是获取最外层轮廓,cv2.RETR_TREE是获取轮廓的整体结构
# 轮廓逼近方法
# 输出的返回值,image是原图像、contours是图像的轮廓、hier是层次类型
image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 创建新的图像black
black = cv2.cvtColor(np.zeros((img.shape[1], img.shape[0]), dtype=np.uint8), cv2.COLOR_GRAY2BGR)


for cnt in contours:
  # 轮廓周长也被称为弧长。可以使用函数 cv2.arcLength() 计算得到。这个函数的第二参数可以用来指定对象的形状是闭合的(True) ,还是打开的(一条曲线)
  epsilon = 0.01 * cv2.arcLength(cnt, True)
  # 函数approxPolyDP来对指定的点集进行逼近,cnt是图像轮廓,epsilon表示的是精度,越小精度越高,因为表示的意思是是原始曲线与近似曲线之间的最大距离。
  # 第三个函数参数若为true,则说明近似曲线是闭合的,它的首位都是相连,反之,若为false,则断开。
  approx = cv2.approxPolyDP(cnt, epsilon, True)
  # convexHull检查一个曲线的凸性缺陷并进行修正,参数cnt是图像轮廓。
  hull = cv2.convexHull(cnt)
  # 勾画图像原始的轮廓
  cv2.drawContours(black, [cnt], -1, (0, 255, 0), 2)
  # 用多边形勾画轮廓区域
  cv2.drawContours(black, [approx], -1, (255, 255, 0), 2)
  # 修正凸性缺陷的轮廓区域
  cv2.drawContours(black, [hull], -1, (0, 0, 255), 2)
# 显示图像
cv2.imshow("hull", black)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果如图所示:

Python使用Opencv实现边缘检测以及轮廓检测的实现

参考资料:OpenCV 3计算机视觉 Python语言实现第二版

到此这篇关于Python使用Opencv实现边缘检测以及轮廓检测的实现的文章就介绍到这了,更多相关Python 边缘检测内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
深入解析Python设计模式编程中建造者模式的使用
Mar 02 Python
Python中摘要算法MD5,SHA1简介及应用实例代码
Jan 09 Python
python selenium自动上传有赞单号的操作方法
Jul 05 Python
Python设计模式之命令模式原理与用法实例分析
Jan 11 Python
python实现贪吃蛇游戏
Mar 21 Python
Python中捕获键盘的方式详解
Mar 28 Python
PyCharm 2019.3发布增加了新功能一览
Dec 08 Python
Python 过滤错误log并导出的实例
Dec 26 Python
Python unittest如何生成HTMLTestRunner模块
Sep 08 Python
详解python3类型注释annotations实用案例
Jan 20 Python
Python  Asyncio模块实现的生产消费者模型的方法
Mar 01 Python
使用numpy实现矩阵的翻转(flip)与旋转
Jun 03 Python
python 检测nginx服务邮件报警的脚本
Dec 31 #Python
Django 实现图片上传和下载功能
Dec 31 #Python
Python wordcloud库安装方法总结
Dec 31 #Python
Python的信号库Blinker用法详解
Dec 31 #Python
浅析python实现动态规划背包问题
Dec 31 #Python
python中doctest库实例用法
Dec 31 #Python
Python项目打包成二进制的方法
Dec 30 #Python
You might like
解析PHP中ob_start()函数的用法
2013/06/24 PHP
php循环创建目录示例分享(php创建多级目录)
2014/03/04 PHP
smarty模板引擎之内建函数用法
2015/03/30 PHP
PHP实现删除字符串中任何字符的函数
2015/08/11 PHP
ThinkPHP3.2框架操作Redis的方法分析
2019/05/05 PHP
JavaScript 程序编码规范
2010/11/23 Javascript
EasyUI 中 MenuButton 的使用方法
2012/07/14 Javascript
基于javascript实现单选及多选的向右和向左移动实例
2015/07/25 Javascript
js调出上下文菜单的实例
2015/12/17 Javascript
jquery ui dialog替代confirm实例分析
2016/01/25 Javascript
vue.js指令和组件详细介绍及实例
2017/04/06 Javascript
JavaScript中splice与slice的区别
2017/05/09 Javascript
详解Vue 事件修饰符capture 的使用
2017/12/29 Javascript
Vue实现内部组件轮播切换效果的示例代码
2018/04/07 Javascript
对vue中v-on绑定自定事件的实例讲解
2018/09/06 Javascript
微信小程序使用setData修改数组中单个对象的方法分析
2018/12/30 Javascript
Vue前端判断数据对象是否为空的实例
2020/09/02 Javascript
[13:40]TI3青蛙君全程回顾 DOTA2我们为梦想再战
2013/09/13 DOTA
Python运算符重载详解及实例代码
2017/03/07 Python
pytorch中的自定义反向传播,求导实例
2020/01/06 Python
如何基于matlab相机标定导出xml文件
2020/11/02 Python
Pytorch 图像变换函数集合小结
2021/02/01 Python
时尚的CSS3进度条效果
2012/02/22 HTML / CSS
HTML5 progress和meter控件_动力节点Java学院整理
2017/07/06 HTML / CSS
使用html5 canvas 画时钟代码实例分享
2015/11/11 HTML / CSS
重新定义牛仔布,100美元以下:Warp + Weft
2018/07/25 全球购物
《春笋》教学反思
2014/04/15 职场文书
协议书格式
2014/04/23 职场文书
小学数学教学经验交流材料
2014/05/22 职场文书
森林防火标语
2014/06/23 职场文书
人事行政主管岗位职责
2015/04/09 职场文书
员工工作失职检讨书范文!
2019/07/03 职场文书
python爬取企查查企业信息之selenium自动模拟登录企查查
2021/04/08 Python
ObjectMapper 如何忽略字段大小写
2021/06/29 Java/Android
java executor包参数处理功能 
2022/02/15 Java/Android
一篇文章告诉你如何实现Vue前端分页和后端分页
2022/02/18 Vue.js