python opencv 边缘检测_Python使用Opencv实现边缘检测以及轮廓检测的实现

边缘检测

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()

运行结果:

7489ba67ad227c4f75abdeaee3a05c11.png

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],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,则该值为负数。

原图:

1599b9f2de3e829785ed8f0601076667.png

示例一

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()

运行结果如图所示:

6d6fcd0d64de14a5bd81086843fe0b15.png

示例二

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()

运行结果如图所示:

c581f19ddcb92f25cf04079fbee2bdd8.png

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

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

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

相关文章

web程序入门五(http无状态)

Asp.net中的状态保持方案: ViewState:是donet特有的 微软提供的对象来完成状态保持 ViewState["key1"] 11; 赋值 键值对 形式 object类型 ViewState["key1"] 直接取值,将其转化成相应的类型 原理:本质…

互评Beta版本(Hello World!——SkyHunter)

1 基于NABCD评论作品,及改进建议 SkyHunter这款游戏我很喜欢,小时候总玩飞机类的游戏,这款游戏我上课的时候试玩了,在我电脑上运行是很好玩的,音乐震撼,画面玄幻,富有金属音乐的味道&#xff0c…

unshift() 方法将一个或多个元素添加到数组的开头,并返回新数组的长度

var arr [1, 2];arr.unshift(0); //result of call is 3, the new array length //arr is [0, 1, 2]arr.unshift(-2, -1); // 5 //arr is [-2, -1, 0, 1, 2]arr.unshift( [-3] ); //arr is [[-3], -2, -1, 0, 1, 2]语法 arr.unshift(element1, ..., elementN)参数列表 elemen…

markdown基础语法整理

标题级别(一共六级) (建议在#后加一个空格比较标准) 通过在文字下方添加“”和“-”,他们分别表示一级标题和二级标题。在文字开头加上 “#”,通过“#”数量表示几级标题。(共1~6级标题,级别越小字体越大&a…

安卓源码下载

SetupSecurityPortingTuningCompatibilityReference转到源代码SetupGetting StartedDownloading and Building RequirementsEstablishing a Build EnvironmentDownloading the SourcePreparing to BuildCompiling with JackUsing Reference BoardsRunning BuildsBuilding Kerne…

mysql常用命令英文词汇_MySQL中文全文索引插件 mysqlcft 1.0.0 安装使用文档

MySQL在高并发连接、数据库记录数较多的情况下,SELECT ... WHERE ... LIKE %...%的全文搜索方式不仅效率差,而且以通配符%和_开头作查询时,使用不到索引,需要全表扫描,对数据库的压力也很大。MySQL针对这一问题提供了一…

dobbo 简单框架

转载于:https://www.cnblogs.com/huangjianping/p/7986881.html

spring mysql整合_springboot mybatis mysql 整合

1、pom文件配置mysqlmysql-connector-javaruntimeorg.springframework.bootspring-boot-starter-testtestorg.mybatis.spring.bootmybatis-spring-boot-starter1.2.0org.springframework.bootspring-boot-starter-jdbc2、mybatis 数据库连接配置spring.datasource.driver-class…

微信小程序怎么取mysql_微信小程序如何加载数据库真实数据?

微信小程序要加载网站数据库里面的真实数据,有一个硬性的要求,就是你的网站域名必须是https协议才行,要不然你第一步服务器域名配置你都通过不了,小编我也是前不久申请的https://www.100txy.com,具体申请步骤大家自行去…

mysql定时任务

1. 查看是否开启定时策略 show variables like %event_sche%; 若出现如下图,则此时是关闭状态 开启定时策略(重启无效) set global event_scheduler 1; 则需要在配置文件my.ini的设置(重启有效) [mysqld] event_schedulerON //这一行加入mysqld标签下 2. 创建存储过…

02使用常规步骤编译NanoPiM1Plus的Android4.4.2

02使用常规步骤编译NanoPiM1Plus的Android4.4.2 大文实验室/大文哥 壹捌陆捌零陆捌捌陆捌贰 21504965 AT qq.com 完成时间:2017/12/5 17:51 版本:V1.0 开发板:NanoPi M1 Plus/zh SDK:Android4.4.2 按照全志A33平台编译调通的功能&…

验证 Swarm 数据持久性 - 每天5分钟玩转 Docker 容器技术(104)

上一节我们成功将 Rex-Ray Volume 挂载到了 Service。本节验证 Failover 时,数据不会丢失。 Scale Up 增加一个副本: docker service update --replicas 2 my_web 运行之前我们先推测一下,理想的结果应该是:swarm 在 swarm-worker…

java multimap 序列化_C++ JSON库的使用

1. 如何使用?2. 常用方法2.1 创建json对象2.1.1 使用cin,cout输入输出流2.1.2 提供根据键直接生成键值对的方法2.1.3 json::array json::object2.1.4 几个区别2.2 序列化2.2.1 标准输出自动序列化2.2.2 使用dump()函数2.3 反序列化2.3.1 从标准输入反序列化2.3.2 通…

【Excle数据透透视表】如何删除数据透视表

选中区域A4:C17,在键盘上按DELETE键删除,结果提示:那么如何删除呢?解决方案选中整个数透视表,再删除具体操作:选中整个数据透视表→DELETE注意:删除之后,源数据不会受到影响转载于:https://www.…

java 启动redis服务器_docker启动redis并使用java连接

一、先查找镜像docker search redis二、拉取镜像docker pull redis三、等待拉取完毕四、查看拉去的镜像docker iamges五、运行redis连接1:https://blog.csdn.net/weixin_38956287/article/details/80423607连接2:http://www.runoob.com/docker/docker-in…

【算法学习】整体二分

我们开门见山,讲讲一道sb题: 给你一个数组,查这个数组的第x大元素。 排序?可以 二分?怎么做啊? 二分出一个mid,判断这个数组中有多少个数小于等于mid,如果个数大于等于x,…

mysql100个优化技巧_完整篇:100+个MySQL调试和优化技巧(2)

▼MySQL模式优化51.检查和经常优化表.52. 经常重写InnoDB表优化.53. 有时,当添加列时删除索引,然后在添加回来索引,这样就会更快.54. 针对不同的需求,使用不同的存储引擎.55. 使用归档存储引擎日志表或审计表-这是更有效地写道.56…

简单的SQL注入学习

引贴: http://blog.163.com/lucia_gagaga/blog/static/26476801920168184648754/ 首先需要编写一个php页面,讲php页面放入/opt/lampp/htdocs目录下: 解释一下这个页面: 1.通过if语句判断变量是否初始化 2.if语句中通过mysql_conne…

什么是网站监控?

网站监控是跟踪网站的可用性和性能,以最小化宕机时间,优化性能并确保顺畅的用户体验。维护网站正常运行对于任何企业来说都是至关重要的,因而对大多数业务来说,网站应用监控都是一个严峻的挑战。Applications Manager网站应用监控…

intellij idea 分屏设置 与快捷键

1、找到分屏功能 File -> setting -> keymap,搜索(注意大小写):   Split Vertically 水平分屏   Split Horizontally 垂直分屏 2、设置快捷键, 编辑快捷键的地方在搜索框同一行:    在标签上直…