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中工作日类库Busines Holiday的介绍与使用
Jul 06 Python
Python多继承顺序实例分析
May 26 Python
详解Python最长公共子串和最长公共子序列的实现
Jul 07 Python
对python列表里的字典元素去重方法详解
Jan 21 Python
Python中的十大图像处理工具(小结)
Jun 10 Python
django创建简单的页面响应实例教程
Sep 06 Python
基于python traceback实现异常的获取与处理
Dec 13 Python
Python中使用filter过滤列表的一个小技巧分享
May 02 Python
关于python3.9安装wordcloud出错的问题及解决办法
Nov 02 Python
Pycharm 设置默认解释器路径和编码格式的操作
Feb 05 Python
pandas数据分组groupby()和统计函数agg()的使用
Mar 04 Python
教你使用Python pypinyin库实现汉字转拼音
May 27 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笔记之:基于面向对象设计的详解
2013/05/14 PHP
PHP遍历目录并返回统计目录大小
2014/06/09 PHP
PHP编程求最大公约数与最小公倍数的方法示例
2017/05/29 PHP
PHP进阶学习之依赖注入与Ioc容器详解
2019/06/19 PHP
jQuery live
2009/05/15 Javascript
jQuery的.live()和.die() 使用介绍
2011/09/10 Javascript
jQuery实用基础超详细介绍
2013/04/11 Javascript
javascript调试之DOM断点调试法使用技巧分享
2014/04/15 Javascript
jQuery仅用3行代码实现的显示与隐藏功能完整实例
2015/10/08 Javascript
jQuery实现二级下拉菜单效果
2016/01/05 Javascript
javascript中apply、call和bind的使用区别
2016/04/05 Javascript
微信小程序 HTTPS报错整理常见问题及解决方案
2016/12/14 Javascript
简单实现js倒计时功能
2017/02/13 Javascript
原生JavaScript实现的无缝滚动功能详解
2020/01/17 Javascript
微信小程序如何通过用户授权获取手机号(getPhoneNumber)
2020/01/21 Javascript
vue路由缓存的几种实现方式小结
2020/02/02 Javascript
JavaScript实现拖动对话框效果的实现代码
2020/10/12 Javascript
Python使用scrapy采集数据时为每个请求随机分配user-agent的方法
2015/04/08 Python
Python基于回溯法子集树模板解决野人与传教士问题示例
2017/09/11 Python
Python创建一个空的dataframe,并循环赋值的方法
2018/11/08 Python
浅谈Python编程中3个常用的数据结构和算法
2019/04/30 Python
用Python实现最速下降法求极值的方法
2019/07/10 Python
Django之使用celery和NGINX生成静态页面实现性能优化
2019/10/08 Python
详解用Python调用百度地图正/逆地理编码API
2020/07/02 Python
Java Unsafe类实现原理及测试代码
2020/09/15 Python
捷克多品牌在线时尚商店:ANSWEAR.cz
2020/10/03 全球购物
你们项目是如何进行变更控制的
2015/08/26 面试题
大学校庆策划书
2014/01/31 职场文书
班干部演讲稿
2014/04/24 职场文书
党支部活动策划方案
2014/08/18 职场文书
政府个人对照检查材料
2014/08/28 职场文书
争先创优演讲稿
2014/09/15 职场文书
对外汉语教师推荐信
2015/03/27 职场文书
教师教育心得体会
2016/01/19 职场文书
Java常用工具类汇总 附示例代码
2021/06/26 Java/Android
redis sentinel监控高可用集群实现的配置步骤
2022/04/01 Redis