OpenCV 学习笔记03 直线和圆检测
检测边缘和轮廓不仅重要,还经常用到,它们也是构成其他复杂操作的基础。
直线和形状检测与边缘和轮廓检测有密切的关系。
霍夫hough 变换是直线和形状检测背后的理论基础。霍夫变化是基于极坐标和向量开展的,常规的直线是二维平面直角坐标上建立的
y = kx + b
该直线的参数 k、b 存在有负值,负值则不便于计算(有资料这样撰写的,没有深究,就以此为参考吧),对于极坐标而言,其表达式为
r=x * cosθ + y * sinθ
参数r、θ均可以为正数(极坐标r值永远是大于等于0的数,θ就可以用0~360度表示方便计算。其中r表示直线到原点的最短距离,θ表示x轴与原点到直线最短距离的夹角)。
1 直线检测
直线检测可通过 HoughLines 和 HoughLinesP 函数来完成,
- HoughLines - 使用标准的Hough变换
- HoughLinesP - 使用概率Hough变换,因此名称后有一个P
HoughLinesP 属于标准Hough变换的优化版本,它不仅分析点点的子集并且还会估计这些点都属于一条直线的概率。该函数计算代价会少一些,执行会变得更快一些。
HoughLinesP 函数的应用
作用:通过概率Hough变换算法实现对二值图像中的线检测
cv2.HoughLinesP(image, rho, theta, threshold[, minLineLength[, maxLineGap]]) -> lines
参数:
image - 8-bit、单通道single-channel二进制源图像;
HoughLines函数会接受由Canny边缘检测滤波器处理过的单通道二值图像,但不一定必须经过Canny处理;不过经过去噪且只有边缘的图像当作Hough变换的输入会得到不错的效果,因此使用Canny滤波器的返回值是一个普遍的惯例。
rho - 累加器的距离分辨率,单位为像素,一般取值为1。
theta - 累加器的角度分辨率,单位为弧度,一般取值为np.pi/180
threshold - 累加器的阈值参数,只有落在直线上的像素点数大于thresh值才会返回直线。
minLineLength - 最小线段长度,小于该值的直线会被舍弃掉
maxLineGap - 同一直线中允许的最大间隙值(gap between points)
返回值:
lines - 矢量线,每行有 4 个元素组成,(x_1, y_1, x_2, y_2),(x_1, y_1) 和 (x_2, y_2) 分别是开始点和结束点
示例:
import cv2
import numpy as np
img = cv2.imread('lines.png')
# 将图片转为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 边缘轮廓检测
edges = cv2.Canny(gray,50,120)
minLineLength = 20
maxLineGap = 5
lines = cv2.HoughLinesP(edges,1,np.pi/180,100,minLineLength,maxLineGap)
# 打印lines.shape值,(29, 1, 4)
# print(lines.shape)
# 打印lines值
# print(lines) ♦
for line in lines:
# 打印line[0].shape,(4,)
# print(line[0].shape)
# 打印line值
# print(line[0]) ♦ ♦
cv2.line(img,(line[0][0],line[0][1]),(line[0][2],line[0][3]),(255,255,0),5)
# 边缘检测轮廓绘图
cv2.imshow("edges", edges)
# Hough变换后绘图
cv2.imshow("Hough", img)
cv2.waitKey()
cv2.destroyAllWindows()
另,第一个 ♦ 输出值(第 17 行)
[[[ 82 356 943 356]] [[ 82 358 943 358]] [[455 333 455 39]] [[457 333 457 39]] [[282 331 309 331]] [[145 682 413 682]] [[562 121 818 121]] [[373 613 376 618]] [[402 663 405 668]] [[732 708 843 597]] [[560 330 560 123]] [[355 582 365 599]] [[561 331 819 331]] [[533 652 729 652]] [[285 461 355 581]] [[819 330 819 122]] [[534 538 730 538]] [[196 593 242 514]] [[251 498 254 493]] [[145 681 178 624]] [[457 511 457 455]] [[457 668 457 713]] [[457 617 457 667]] [[732 483 843 594]] [[455 433 455 489]] [[730 537 730 483]] [[457 597 457 541]] [[532 651 532 540]] [[732 484 843 595]]]
另,第二个 ♦ ♦ 输出值(第 17 行)
[ 82 356 943 356] [ 82 358 943 358] [455 333 455 39] [457 333 457 39] [282 331 309 331] [145 682 413 682] [562 121 818 121] [373 613 376 618] [402 663 405 668] [732 708 843 597] [560 330 560 123] [355 582 365 599] [561 331 819 331] [533 652 729 652] [285 461 355 581] [819 330 819 122] [534 538 730 538] [196 593 242 514] [251 498 254 493] [145 681 178 624] [457 511 457 455] [457 668 457 713] [457 617 457 667] [732 483 843 594] [455 433 455 489] [730 537 730 483] [457 597 457 541] [532 651 532 540] [732 484 843 595]
图片对比

我们可以发现,原图在Canny函数检测后,其轮廓均能被有效检测出来,在霍夫Hough变换时,需要进一步修改参数才能进行有效检测。
2 圆检测
上述代码是针对直线检测的,函数HoughCircles是实现圆的检测。
HoughCircles函数的应用
作用:使用Hough变换在灰度图像中查找 / 检测圆圈。
HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]]) -> circles
参数:
image - 8位单通道二进制图像。
method - 检测方法,唯一实现的方法是 HOUGH_GRADIENT
dp - 累加器分辨率,其与图像分辨率的反比,若dp = 1,则累加器具有与输入图像相同的分辨率,若dp = 2,则累加器的宽度和高度为输入图像的一半。
minDist - 检测到的圆的中心之间的最小距离,若太小,则除真实的一个外,可能错误地检测到多个相邻的圆圈,若太大,则可能会遗漏一些圆
param1 - 第一个特定于方法的参数。在#HOUGH_GRADIENT的情况下,它是传递给Canny边缘检测器的两个较高阈值(较低的一个小两倍)。
param2 - 第二种方法特定参数。在#HOUGH_GRADIENT的情况下,它是检测阶段圆心的累加器阈值。它越小,可以检测到更多的假圆圈。将首先返回与较大累加器值对应的圆圈。
minRadius - 最小圆半径
maxRadius - 最大圆半径
示例:
import cv2
import numpy as np
planets = cv2.imread('planet_glow.png')
gray_img = cv2.cvtColor(planets, cv2.COLOR_BGR2GRAY)
# 进行中值滤波操作
# 中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的 中值 代替
img = cv2.medianBlur(gray_img,5)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,120,param1=100,param2=30,minRadius=0,maxRadius=0)
print(help(cv2.HoughCircles))
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
# draw the outer circle
cv2.circle(planets,(i[0],i[1]),i[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(planets,(i[0],i[1]),2,(0,0,255),3)
cv2.imwrite("planets_circles.jpg",planets)
cv2.imshow('HoughCircles',planets)
cv2.waitKey()
cv2.destroyAllWindows
运行:

参考:
opencv 直线和圆检测,该文中仅有代码,可以借鉴
原图:

OpenCV 学习笔记03 直线和圆检测的更多相关文章
- OpenCV 学习笔记03 findContours函数
opencv-python 4.0.1 1 函数释义 词义:发现轮廓! 从二进制图像中查找轮廓(Finds contours in a binary image):轮廓是形状分析和物体检测和识别的 ...
- OpenCV 学习笔记03 边界框、最小矩形区域和最小闭圆的轮廓
本节代码使用的opencv-python 4.0.1,numpy 1.15.4 + mkl 使用图片为 Mjolnir_Round_Car_Magnet_300x300.jpg 代码如下: impor ...
- OpenCV 学习笔记03 boundingRect、minAreaRect、minEnclosingCircle、boxPoints、int0、circle、rectangle函数的用法
函数中的代码是部分代码,详细代码在最后 1 cv2.boundingRect 作用:矩形边框(boundingRect),用于计算图像一系列点的外部矩形边界. cv2.boundingRect(arr ...
- OpenCV 学习笔记03 凸包convexHull、道格拉斯-普克算法Douglas-Peucker algorithm、approxPloyDP 函数
凸形状内部的任意两点的连线都应该在形状里面. 1 道格拉斯-普克算法 Douglas-Peucker algorithm 这个算法在其他文章中讲述的非常详细,此处就详细撰述. 下图是引用维基百科的.ε ...
- opencv学习笔记霍夫变换——直线检测
参考大佬博文:blog.csdn.net/jia20003/article/details/7724530 lps-683.iteye.com/blog/2254368 openCV里有两个函数(比较 ...
- OpenCV 学习笔记03 drawContours函数
opencv-python 4.0.1 轮廓的绘制或填充. cv2.drawContours(image, contours, contourIdx, color[, thickness[, li ...
- OpenCV 学习笔记03 threshold函数
opencv-python 4.0.1 简介:该函数是对数组中的每一个元素(each array element)应用固定级别阈值(Applies a fixed-level threshold) ...
- OpenCV 学习笔记 07 目标检测与识别
目标检测与识别是计算机视觉中最常见的挑战之一.属于高级主题. 本章节将扩展目标检测的概念,首先探讨人脸识别技术,然后将该技术应用到显示生活中的各种目标检测. 1 目标检测与识别技术 为了与OpenCV ...
- opencv学习笔记(二)寻找轮廓
opencv学习笔记(二)寻找轮廓 opencv中使用findContours函数来查找轮廓,这个函数的原型为: void findContours(InputOutputArray image, O ...
随机推荐
- [Docker] Getting Started with Container Networks
It is possible to group containers into a network and we can create multi networks so that container ...
- Android 自定义 ListView 上下拉动“刷新最新”和“加载更多”歌曲列表
本文内容 环境 测试数据 项目结构 演示 参考资料 本文演示,上拉刷新最新的歌曲列表,和下拉加载更多的歌曲列表.所谓"刷新最新"和"加载更多"是指日期.演示代码 ...
- C#.NET常见问题(FAQ)-控制台程序如何做弹窗
最简单的弹窗,只要引用System.Windows.Forms,就可以使用WinForm的弹窗 如果要弹出是/否的选择对话框,则可以拷贝下面的代码 DialogResult dr = Messag ...
- Discuz常见小问题-_如何修改网站LOGO
1 界面-风格管理,点击编辑 2 默认的LOGO图片叫做logo.png,存放在X:\PHPNow\htdocs\Discuz\upload\static\image\common文件夹下面,其中X是 ...
- 如何解析android访问webservice返回的SoapObject数据(可用)
怎么解析android访问webservice返回的SoapObject数据 本帖最后由 kkDragon123 于 2013-03-26 15:50:07 编辑 我的数据如下:mingdanResp ...
- Linux安装和设置Samba服务器
1. 安装 安装前先关闭iptables和SELinux. Centos输入以下命令: yum install samba samba-client Ubuntu输入以下命令: apt-get ins ...
- Android ART runtime简述
此文章原始是PPT格式已转换为PDF,完整内容也能够下载文档阅读: AndroidARTruntimeOverview watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5 ...
- 算法笔记_213:第七届蓝桥杯软件类决赛部分真题(Java语言C组)
目录 1 平方末尾 2 七星填数 3 打印数字 4 赢球票 前言:以下代码仅供参考,若有错误欢迎指正哦~ 1 平方末尾 平方末尾 能够表示为某个整数的平方的数字称为“平方数” 比如,25,64 虽然无 ...
- JSjs获取当前时间的前一天/后一天(昨天/明天)
Date curDate = new Date(); var preDate = new Date(curDate.getTime() - 24*60*60*1000); //前一天 var next ...
- 〖Android〗超级终端/sdcard/local_profile备份
# mode set -o vi # env workpc=work@11.11.137.171 mepc=me@11.11.137.172 passwd=/sdcard/passwd_me # po ...