【OpenCV-Python】——边缘和轮廓Laplacian/Sobel/Canny边缘检测查找/绘制轮廓及轮廓特征霍夫直线/圆变换
目录
前言:
1、边缘检测
1.1 Laplacian边缘检测
1.2 Sobel边缘检测
1.3 Canny边缘检测
2、图像轮廓
2.1 查找轮廓
2.2 绘制轮廓
2.3 轮廓特征
3、霍夫变换
3.1 霍夫直线变换
3.2 霍夫圆变换
总结:
前言:
图像的边缘是指图像中灰度值急剧变化的位置,边缘检测的目的是为了绘制边缘线条。边缘检测的目的是为了绘制出边缘线条。边缘通常是不连续的,不能表示整体。
图像的轮廓是指将边缘连接起来形成的整体。这次主要学习边缘检测、图像轮廓和霍夫变换。
1、边缘检测
边缘检测结果通常为黑白图像,图像中的白色线条表示边缘。常见的边缘检测算法有Laplacian边缘检测、Sobel边缘检测和Canny边缘检测。
1.1 Laplacian边缘检测
使用图像矩阵与拉普拉斯核进行卷积运算,其本质是计算图像中任意一点与其在水平方向和垂直方向上4个相邻点的平均值的差值。
dst=cv2.Laplacian(src,depth,ksize,scale,delta,borderType)
depth表示目标图像深度。后四个为可选参数,ksize为用于计算二阶导数滤波器的系数,必须为正数且奇数;scale为可选比例因子;delta为添加到边缘检测结果中的可选增量值;最后为边界类型。
img=cv2.imread('dog2.png')
cv2.imshow('img',img)
img2=cv2.Laplacian(img,cv2.CV_8U)
cv2.imshow('img2',img2)
cv2.waitKey(0)
1.2 Sobel边缘检测
将高斯滤波和微分方程结合起来执行图像卷积运算,其结果有一定抗噪性。
dst=cv2.Sobel(src,depth,dx,dy,ksize,scale,delta,borderType)
dx为导数x的阶数,dy为导数y的阶数。后四个为可选参数,ksize是扩展的Sobel内核的大小,必须是1,3,5或7;scale为计算导数的可选比例因子,其他与拉普拉斯一样。
img=cv2.imread('dog2.png')
cv2.imshow('img',img)
img2=cv2.Sobel(img,cv2.CV_8U,0,1) #表示只计算垂直方向的导数
cv2.imshow('img2',img2)
cv2.waitKey(0)
1.3 Canny边缘检测
Laplacian和Sobel边缘检测都通过卷积计算边缘,算法比较简单,因此结果噪声较多或者损失过多的边缘信息。Canny的算法则更加复杂:首先使用高斯滤波去除图像噪声;然后使用Sobel核进行滤波,计算梯度;在边缘使用非最大值抑制;对检测出的边缘进行双阈值以去除假阳性;最后分析边缘之间的连接性,保留真正的边缘,消除不明显的边缘。
dst=cv2.Canny(src,threshold1,threshold2,apertureSize,L2gradient)
threshold1是第1阈值,threshold2是第2个阈值。后两个为可选参数,前者为计算梯度时使用的Sobel核大小,后者为标志。
img=cv2.imread('dog2.png')
cv2.imshow('img',img)
img2=cv2.Canny(img,150,200)
cv2.imshow('img2',img2)
cv2.waitKey(0)
2、图像轮廓
图像轮廓是指由位于边缘、连续的、具有相同颜色和强度的点构成的曲线,可用于形状分析、对象检测和识别等。
2.1 查找轮廓
contours,hierarchy=cv2.findContours(image,mode,method,offset)
contours是返回的轮廓,hierarchy是返回的轮廓的层次结构;mode是轮廓检索模式,method是轮廓的近似方法。offset是可选参数,为每个轮廓点移动的可选偏移量。
img=cv2.imread('tuxing.png')
cv2.imshow('img',img)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图
ret,thresh=cv2.threshold(gray,125,255,cv2.THRESH_BINARY) #为了提高准确率,二值化阈值处理
b,c,h=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #查找轮廓,这里接受参数是三个因为两个报错了
print('轮廓:',c)
print('轮廓类型:',type(c))
print('轮廓个数:',len(c))
print('层次:',h)
print('层次类型:',type(h))
for i in range(3):img3=np.zeros(img.shape,np.uint8)+255 #创建一幅与原图等大小的白色图像cv2.polylines(img3,[c[i]],True,(255,0,0),2) #依次绘制轮廓cv2.imshow('img%s'%i,img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.findContours()返回的是一个list对象,保存了轮廓数组。轮廓数组的每个元素都是一个表示轮廓的array对象;返回的轮廓层次是一个numpy.ndarray对象。
轮廓层次:返回的轮廓层次是一个numpy.ndarray对象。根据轮廓的嵌套关系,可将轮廓之间的层次关系分为父级和子级,外部轮廓为父级,内部是子级。numpy.ndarray对象的每个元素关系格式:【下一个轮廓 前一个轮廓 第一个子级轮廓 父级轮廓】,如【-1 0 2 -1】中-1表示不存咋对应轮廓,前一个轮廓在轮廓数组中的序号为0,第一个子级轮廓序号为2.
2.2 绘制轮廓
绘制轮廓用cv2.drawContours()函数:
image=cv2.drawContours(image,contours,contoursIdx,color,thickness,linetype,hierarchy,maxLevel,offset)
image是在其中绘制轮廓的图像,如先定义的一块白色图像;contours为返回的轮廓数组,contoursIdx是要绘制的轮廓的索引,大于或等于0时绘制对应序号的轮廓,负数时(通常为-1)表示绘制所有的轮廓);color为颜色。后面的都是可选参数,hierarchy是轮廓层次,maxLevel是可绘制的最大轮廓层次深度,offset是绘制轮廓的偏移位置。例如:
img3=cv2.drawContours(img3,c,-1,(0,0,255),2) #c上面接受了返回的轮廓信息
2.3 轮廓特征
①轮廓的矩
轮廓的矩包含了轮廓的各种几何特征,如面积、位置、角度、形状等。函数是cv2.moments():
ret=cv2.moments(array,binaryImage)
ret是返回的轮廓矩,是一个字典对象。大多数矩的含义比较抽象,但其中的零阶矩(m00)表示轮廓的面积;array为轮廓数组;binaryImage为True时,会将array对象的所有非0值设置为1。
img=cv2.imread('tuxing.png')
cv2.imshow('img',img)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图
ret,thresh=cv2.threshold(gray,125,255,cv2.THRESH_BINARY) #为了提高准确率,二值化阈值处理
b,c,h=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #查找轮廓,这里接受参数是三个因为两个报错了
for i in range(3):m=cv2.moments(c[i])print('轮廓%s的矩'%i,m)print('轮廓%s的面积:'%i,m['m00']) #零阶矩表示面积
cv2.waitKey(0)
cv2.destroyAllWindows()
②轮廓的面积
ret=cv2.contourArea(contour,oriented)
ret为返回的面积,直接是一个数值;orient为可选参数,为True时,返回值的正与负表示轮廓时顺时针还是逆时针;为False(默认值)时,函数返回值为绝对值。
③轮廓的长度
ret=cv2.ardLength(contour,closed)
ret是返回值,直接是一个长度值;closed时布尔值,为True时表示轮廓是封闭的。
④轮廓的近似多边形
ret=cv2.approxPolyDP(contours,epsilon,closed)
ret是返回的多边形轮廓数组;是精度,表示多边形接近轮廓的最大距离;close是布尔值,True为封闭。
app=cv2.approxPolyDP(c[0],0.1,True) #c[0]表示上面得到的轮廓0
img=cv2.drawContours(img,[app],-1,(255,0,0),2) #绘制多边形轮廓
⑤轮廓的凸包、直边界矩形、旋转矩形、最小外包圆、拟合椭圆、拟合直线、最小外包三角形等,这里不具体介绍,需要时可具体查找。
3、霍夫变换
霍夫变换用于在图像中查找直线和圆等形状。
3.1 霍夫直线变换
cv2.HoughLines()函数利用霍夫变换算法检测图像中的直线:
lines=cv2.HoughLines(image,rho,theta,threshold)
lines是返回的直线,rho是距离的精度(以像素为单位)通常是1;theta是角度的精度,通常使用Π/180°,表示搜索所有可能的角度;threhold未阈值,值越小检测出的直线越多。
一般是在边缘检测如Canny后再检测直线,注意返回的是直线的数组信息,还要通过line函数绘制:
img=cv2.imread('xiangqi.png')
cv2.imshow('img',img)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图
edges=cv2.Canny(gray,50,150,apertureSize=3) #边缘检测
lines=cv2.HoughLines(edges,1,np.pi/180,150) #霍夫直线变换
img3=img.copy()
for line in lines: #一种固定用法。lines是一系列数组,line是一个数组(一个直线的信息)。逐条绘制rho,theta=line[0]a=np.cos(theta)b=np.sin(theta)x0,y0=a*rho,b*rhopt1=(int(x0 + 1000 * (-b)), int(y0 + 1000 * (a))) #计算直线端点pt2=(int(x0 - 1000 * (-b)), int(y0 - 1000 * (a))) #计算直线端点cv2.line(img3,pt1,pt2,(0,0,255),1) #绘制
cv2.imshow('HoughLines',img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
另一种cv2.HoughLinesP()函数利用概率霍夫变换算法来检测图像中的直线:
lines=cv2.HoughLinesP(image,rho,theta,threshold,minLineLength,maxLineGap)
后两个是可选参数,前者是可接受的直线的最小长度,默认值0;后者是共线线段之间的最大间隔,默认为0。
img=cv2.imread('xiangqi.png')
cv2.imshow('img',img)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图
lines=cv2.HoughLinesP(edges,1,np.pi/180,1,100,10) #霍夫直线变换
img3=img.copy()
for line in lines: #一种固定用法。lines是一系列数组,line是一个数组(一个直线的信息)。逐条绘制x1,y1,x2,y2=line[0]cv2.line(img3,(x1,y1),(x2,y2),(0,0,255),2) #绘制
cv2.imshow('HoughLines',img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
3.2 霍夫圆变换
cv2.HoughCircles()函数利用霍夫变换查找图像中的圆:
circles=cv2.HoughCircles(image,method,dp,minDist,param1,param2,minRadius,maxRadius)
method是查找方法,可设置为cv2.HOUGH_GRADIET和cv2.HOUGH_GRADIET_ALT;dp是累加器分辨率,与图像分辨率成反比,如dp=1时累加器与输入图像的分辨率相同,dp=2时累加器的宽度和高度是输入图像的一半;minDist是圆心间的最小距离。
后四个是可选参数,param1是对应Canny边缘检测的高阈值(低阈值时高阈值的一半),默认100;param2时圆心位置必须达到的投票数,值越大,检测出的圆越少,默认100。minRadius是最小圆半径,默认为0;最后是最大圆半径,默认为0:
img=cv2.imread('xiangqi.png')
cv2.imshow('img',img)
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图
edges=cv2.Canny(gray,50,150,apertureSize=3) #边缘检测
circles=cv2.HoughCircles(edges,cv2.HOUGH_GRADIENT,1,50,param2=30,minRadius=10,maxRadius=40) #霍夫直线变换
circles=np.uint16(np.around(circles))
img3=img.copy()
for i in circles[0,:]: #一种固定用法。lines是一系列数组,line是一个数组(一个直线的信息)。逐条绘制cv2.circle(img3,(i[0],i[1]),i[2],(0,255,0),2) #绘制圆cv2.circle(img3, (i[0],i[1]),2,(255,0,0),3) # 绘制圆心
cv2.imshow('HoughCircles',img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
总结:
由于是初学者可能很多地方没有总结完全或者有误,后续深入学习后会不断回来该删,也欢迎各位朋友指正!下次学习直方图!
【OpenCV-Python】——边缘和轮廓Laplacian/Sobel/Canny边缘检测查找/绘制轮廓及轮廓特征霍夫直线/圆变换相关推荐
- opencv for python的图像梯度算子以及canny边缘检测
opencv for python的图像梯度算子以及canny边缘检测 一.图像梯度算子: 二.Canny边缘检测(一个多级边缘检测算法): 一.图像梯度算子: 1.概念简介(部分引自百度百科): 图 ...
- android openCV检测图像的基本特征,包括Canny边缘检测、Harris角点检测、霍夫直线检测-基于Android studio
实现平台:windows下的Android studio1.4 依赖库:openCV3.1.0 程序安装平台:Android6.0 实现的功能:从手机中选择一张图片,检测图片的基本特征,通过menu菜 ...
- QT+opencv学习笔记(5)——霍夫直线检测、圆检测及椭圆检测
开发环境为:win10+QT5.8+opencv3.2 Hough变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛.最基本的Hough变换是从黑白图像中检测直线,还可以经过改进检测圆.椭 ...
- OpenCV中霍夫直线变换
OpenCV中霍夫直线变换 首先要知道,一条直线的通用表达式为y=ax+b\color{#F00}y=ax+by=ax+b,a为直线的斜率,b为直线的截距,知道这两个参数可以唯一确定一条直线.通常我们 ...
- OpenCV标准霍夫直线检测详解
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转载自:OpenCV学堂 霍夫直线检测 对于图像来说可以从笛卡 ...
- 基于opencv的c++图像处理(霍夫直线检测与最小二乘法直线拟合)
前言 基于opencv的c++接口,实现标准的霍夫直线检测.基于统计概率的霍夫直线检测.以及最小二乘法直线拟合. 相关的opencv接口解析 CV_EXPORTS_W void HoughLines( ...
- OpenCV霍夫直线houghlines点集的实例(附完整代码)
OpenCV霍夫直线houghlines点集的实例 OpenCV霍夫直线houghlines点集的实例 OpenCV霍夫直线houghlines点集的实例 #include <opencv2/c ...
- OpenCV霍夫直线检测的实例(附完整代码)
OpenCV霍夫直线检测的实例 OpenCV霍夫直线检测的实例 OpenCV霍夫直线检测的实例 #include <opencv2/imgproc.hpp> #include <op ...
- c++版本opencv(36.霍夫直线检测37.直线类型与线段-)
c++版本opencv(36.霍夫直线检测37.直线类型与线段-) 一.36.霍夫直线检测- 二,37.直线类型与线段- 来自网易云课堂贾志刚老师 一.36.霍夫直线检测- 同一条直线上的点,r和c塔 ...
最新文章
- 【大话设计模式】——浅谈设计模式基础
- 织梦引用html,html直接引用vue和element-ui的方法
- 临危不乱,.Net+IIS环境经常出现的问题及排障。
- 使用ASP.NET Atlas开发随输入内容自动调整行数的textarea
- python time 时钟计时_如何使用Python的timeit计时代码段以测试性能?
- HDU - 1542 Atlantis(线段树+扫描线)
- 虚拟DOM Diff算法解析
- 为Windows 服务器网络搬家
- 设计模式之:深入浅出 java 单例模式(Singleton)
- 爬虫演练-动态的抓取cp网站数据的演练-注意要反爬
- c51随机数不重复_怎么让51单片机产生随机数?
- android 按键点击触摸有水印效果_“100例”—优秀产品设计按键细节设计美图
- jquery easyui 表单结合对话框
- 解读《道德经》nbsp;五十六章nbsp;知者不言…
- 如何比较两个速度的大小地程序_58安居客小程序平台化与多小程序开发探索与实践...
- 【C++】哈希——unordered系列容器|哈希冲突|闭散列|开散列
- 面包菜单收起和出现案例
- 【电脑运用及修理】Internet Explorer 浏览器
- leetcode13——步长k的差值小于t的元素组,包含1的正方形面积,完全二叉树的结点个数,矩形重叠面积,汇总区间
- 手把手教你写代码生成器(也算ORM的续)
热门文章
- 方差、均方差、中位数的意义
- LINUX下在线音乐任意听firefox+totem-xine+mediawrap
- MySQL基础-(概念、安装、SQL语句、约束)
- Magicodes.WeiChat——使用OAuth 2.0获取微信用户信息
- 东野圭吾梦幻花读后感_梦幻花读后感
- P2P网络中内网穿透的方法总结(2019)
- Modification of UCT with Patterns in Monte-Carlo Go(论文阅读)
- 深度学习——动态调整学习率方案
- 2022年全球市场汽车轮毂总体规模、主要生产商、主要地区、产品和应用细分研究报告
- mysql 查阻塞_mysql检查阻塞进程