目录

前言:

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边缘检测查找/绘制轮廓及轮廓特征霍夫直线/圆变换相关推荐

  1. opencv for python的图像梯度算子以及canny边缘检测

    opencv for python的图像梯度算子以及canny边缘检测 一.图像梯度算子: 二.Canny边缘检测(一个多级边缘检测算法): 一.图像梯度算子: 1.概念简介(部分引自百度百科): 图 ...

  2. android openCV检测图像的基本特征,包括Canny边缘检测、Harris角点检测、霍夫直线检测-基于Android studio

    实现平台:windows下的Android studio1.4 依赖库:openCV3.1.0 程序安装平台:Android6.0 实现的功能:从手机中选择一张图片,检测图片的基本特征,通过menu菜 ...

  3. QT+opencv学习笔记(5)——霍夫直线检测、圆检测及椭圆检测

    开发环境为:win10+QT5.8+opencv3.2 Hough变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛.最基本的Hough变换是从黑白图像中检测直线,还可以经过改进检测圆.椭 ...

  4. OpenCV中霍夫直线变换

    OpenCV中霍夫直线变换 首先要知道,一条直线的通用表达式为y=ax+b\color{#F00}y=ax+by=ax+b,a为直线的斜率,b为直线的截距,知道这两个参数可以唯一确定一条直线.通常我们 ...

  5. OpenCV标准霍夫直线检测详解

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转载自:OpenCV学堂 霍夫直线检测 对于图像来说可以从笛卡 ...

  6. 基于opencv的c++图像处理(霍夫直线检测与最小二乘法直线拟合)

    前言 基于opencv的c++接口,实现标准的霍夫直线检测.基于统计概率的霍夫直线检测.以及最小二乘法直线拟合. 相关的opencv接口解析 CV_EXPORTS_W void HoughLines( ...

  7. OpenCV霍夫直线houghlines点集的实例(附完整代码)

    OpenCV霍夫直线houghlines点集的实例 OpenCV霍夫直线houghlines点集的实例 OpenCV霍夫直线houghlines点集的实例 #include <opencv2/c ...

  8. OpenCV霍夫直线检测的实例(附完整代码)

    OpenCV霍夫直线检测的实例 OpenCV霍夫直线检测的实例 OpenCV霍夫直线检测的实例 #include <opencv2/imgproc.hpp> #include <op ...

  9. c++版本opencv(36.霍夫直线检测37.直线类型与线段-)

    c++版本opencv(36.霍夫直线检测37.直线类型与线段-) 一.36.霍夫直线检测- 二,37.直线类型与线段- 来自网易云课堂贾志刚老师 一.36.霍夫直线检测- 同一条直线上的点,r和c塔 ...

最新文章

  1. 【大话设计模式】——浅谈设计模式基础
  2. 织梦引用html,html直接引用vue和element-ui的方法
  3. 临危不乱,.Net+IIS环境经常出现的问题及排障。
  4. 使用ASP.NET Atlas开发随输入内容自动调整行数的textarea
  5. python time 时钟计时_如何使用Python的timeit计时代码段以测试性能?
  6. HDU - 1542 Atlantis(线段树+扫描线)
  7. 虚拟DOM Diff算法解析
  8. 为Windows 服务器网络搬家
  9. 设计模式之:深入浅出 java 单例模式(Singleton)
  10. 爬虫演练-动态的抓取cp网站数据的演练-注意要反爬
  11. c51随机数不重复_怎么让51单片机产生随机数?
  12. android 按键点击触摸有水印效果_“100例”—优秀产品设计按键细节设计美图
  13. jquery easyui 表单结合对话框
  14. 解读《道德经》nbsp;五十六章nbsp;知者不言…
  15. 如何比较两个速度的大小地程序_58安居客小程序平台化与多小程序开发探索与实践...
  16. 【C++】哈希——unordered系列容器|哈希冲突|闭散列|开散列
  17. 面包菜单收起和出现案例
  18. 【电脑运用及修理】Internet Explorer 浏览器
  19. leetcode13——步长k的差值小于t的元素组,包含1的正方形面积,完全二叉树的结点个数,矩形重叠面积,汇总区间
  20. 手把手教你写代码生成器(也算ORM的续)

热门文章

  1. 方差、均方差、中位数的意义
  2. LINUX下在线音乐任意听firefox+totem-xine+mediawrap
  3. MySQL基础-(概念、安装、SQL语句、约束)
  4. Magicodes.WeiChat——使用OAuth 2.0获取微信用户信息
  5. 东野圭吾梦幻花读后感_梦幻花读后感
  6. P2P网络中内网穿透的方法总结(2019)
  7. Modification of UCT with Patterns in Monte-Carlo Go(论文阅读)
  8. 深度学习——动态调整学习率方案
  9. 2022年全球市场汽车轮毂总体规模、主要生产商、主要地区、产品和应用细分研究报告
  10. mysql 查阻塞_mysql检查阻塞进程