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文件读写操作与linux shell变量命令交互执行的方法
Jan 14 Python
python使用PIL模块实现给图片打水印的方法
May 22 Python
python中cPickle类使用方法详解
Aug 27 Python
python使用pdfminer解析pdf文件的方法示例
Dec 20 Python
Python向excel中写入数据的方法
May 05 Python
python中时间模块的基本使用教程
May 14 Python
python卸载后再次安装遇到的问题解决
Jul 10 Python
python 同时读取多个文件的例子
Jul 16 Python
tesserocr与pytesseract模块的使用方法解析
Aug 30 Python
python实现遍历文件夹图片并重命名
Mar 23 Python
更新升级python和pip版本后不生效的问题解决
Apr 17 Python
python解包用法详解
Feb 17 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
星际中的相关伤害
2020/03/04 星际争霸
咖啡知识大全
2021/03/03 新手入门
通过html表格发电子邮件
2006/10/09 PHP
PHP函数microtime()用法与说明
2013/12/04 PHP
PHP生成图表pChart的示例解析
2020/07/31 PHP
js停止输出代码
2008/07/20 Javascript
JQuery.uploadify 上传文件插件的使用详解 for ASP.NET
2010/01/22 Javascript
基于JQuery的日期联动实现代码
2011/02/24 Javascript
JS实现生成会变大变小的圆环实例
2015/08/05 Javascript
JavaScript程序设计之JS调试
2015/12/09 Javascript
实例详解jQuery Mockjax 插件模拟 Ajax 请求
2016/01/12 Javascript
JS实现的四级密码强度检测功能示例
2017/05/11 Javascript
bootstrap精简教程_动力节点Java学院整理
2017/07/14 Javascript
详解webpack3如何正确引用并使用jQuery库
2017/08/26 jQuery
详解Angular调试技巧之报错404(not found)
2018/01/31 Javascript
使用webpack打包koa2 框架app
2018/02/02 Javascript
vue项目中api接口管理总结
2018/04/20 Javascript
Element-ui tree组件自定义节点使用方法代码详解
2018/09/17 Javascript
JS Generator 函数的含义与用法实例总结
2020/04/08 Javascript
vue的hash值原理也是table切换实例代码
2020/12/14 Vue.js
[00:50]2014DOTA2国际邀请赛 NEWBEE战队回顾
2014/08/01 DOTA
Python下载指定页面上图片的方法
2016/05/12 Python
Python调用C语言的方法【基于ctypes模块】
2018/01/22 Python
python获取文件真实链接的方法,针对于302返回码
2018/05/14 Python
python 实现视频流下载保存MP4的方法
2019/01/09 Python
Python+OpenCV+pyQt5录制双目摄像头视频的实例
2019/06/28 Python
在 Pycharm 安装使用black的方法详解
2020/04/02 Python
html5中audio支持音频格式的解决方法
2018/08/24 HTML / CSS
中国海淘族值得信赖的海淘返利网站:55海淘
2017/01/16 全球购物
学校门卫岗位职责范本
2014/06/30 职场文书
坎儿井导游词
2015/02/09 职场文书
工作能力自我评价2015
2015/03/05 职场文书
教师病假条范文
2015/08/17 职场文书
创业计划书之o2o水果店
2019/08/30 职场文书
Ajax实现异步加载数据
2021/11/17 Javascript
Python turtle编写简单的球类小游戏
2022/03/31 Python