Cluster模式 dom ssh gwt tcp bluetooth ldap svn默认安装路径 手机banner常用尺寸 oracle限制查询条数 matlab取实部 python面向对象 pythonset python的random函数 python设置环境变量 java获取年份 java8教程 java实现多线程 linux装机 系统集成项目管理工程师教程 typemonkey 海鸥浏览器 js闭包的理解 网络克隆 电子商城系统 源计划艾克 英雄联盟设置 asp程序下载 onaccuracychanged 软碟通u盘装系统教程 camworks dos命令大全及用法 小米自动开关机 bat转exe 控制面板命令 游戏补丁 百小度 手机如何打出删除线字 b站粉丝勋章 ps怎么给字体描边
当前位置: 首页 > 学习教程  > python

Python OpenCV 霍夫(Hough Transform)直线变换检测应用

2021/2/7 11:06:10 文章标签:

Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。本篇博客是这个系列的第 34 篇。 Python OpenCV基础知识铺垫霍夫直线变换函数原型概率霍夫变换(Probabilistic Hough Transform)橡皮擦的小节基础知识铺垫 上篇博客 咱们一起学习……

Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。本篇博客是这个系列的第 34 篇。


Python OpenCV


    • 霍夫直线变换函数原型

    • 概率霍夫变换(Probabilistic Hough Transform)

    • 基础知识铺垫


    • 橡皮擦的小节


    基础知识铺垫

    上篇博客 咱们一起学习了霍夫直线检测的原理,本篇就从应用层对其进行学习啦。

    学习了原理之后,在查看函数原型,发现确实简单了许多。

    霍夫直线变换函数原型

    在 OpenCV 中提供了两个霍夫直线检测的函数,一个是标准霍夫变换,另一个是概率霍夫变换。

    先学习一下标准霍夫变换吧,该变化方式也叫做多尺度霍夫变换。

    该方法使用的函数是,函数原型如下

    lines = cv2.HoughLines(image, rho, theta, threshold[, lines[, srn[, stn[, min_theta[, max_theta]]]]])

    参数说明:

    • image:输入 8 位灰度图像;

    • rho:生成极坐标时像素扫描步长;

    • theta:生成极坐标时候的角度步长;

    • threshold:阈值;

    • lines:返回值,极坐标表示的直线;

    • sen:是否应用多尺度的霍夫变换,如果不是设置 0 表示经典霍夫变换;

    • stn:是否应用多尺度的霍夫变换,如果不是设置 0 表示经典霍夫变换;

    • min_theta:角度扫描范围最小值;

    • max_theta:角度扫描范围最大值。

    该函数的返回值就是上篇博客提及的 ( θ,ρ ),其中 ρ 的单位是像素, θ 的单位是弧度。

    既然是直线检测,那我们先把图像的边缘检测出来,通过之前学习的知识即可,加入滑动条,方便调参。

    import cv2 as cvimport numpy as np
    
    src = cv.imread("./331.jpg")gray_img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)def nothing():passcv.namedWindow("bar")cv.createTrackbar("threshold1", "bar", 0, 255, nothing)cv.createTrackbar("threshold2", "bar", 0, 255, nothing)dst = cv.equalizeHist(gray_img)# 高斯滤波降噪gaussian = cv.GaussianBlur(dst, (9, 9), 0)cv.imshow("gaussian", gaussian)while True:threshold1 = cv.getTrackbarPos("threshold1", "bar")threshold2 = cv.getTrackbarPos("threshold2", "bar")# 边缘检测edges = cv.Canny(gaussian, threshold1, threshold2)cv.imshow("edges", edges)if cv.waitKey(1) & 0xFF == 27:breakcv.destroyAllWindows()

    运行代码之后,获取到的边缘如下,下面就可以对直线进行获取了,通过函数。

    Python OpenCV 霍夫(Hough Transform)直线变换检测应用
    修改代码如下:

    import cv2 as cvimport numpy as np
    
    src = cv.imread("./331.jpg")gray_img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)dst = cv.equalizeHist(gray_img)# 高斯滤波降噪gaussian = cv.GaussianBlur(dst, (9, 9), 0)# cv.imshow("gaussian", gaussian)# 边缘检测edges = cv.Canny(gaussian, 70, 150)cv.imshow("edges", edges)# Hough 直线检测# 重点注意第四个参数 阈值,只有累加后的值高于阈值时才被认为是一条直线,也可以把它看成能检测到的直线的最短长度(以像素点为单位)# 在霍夫空间理解为:至少有多少条正弦曲线交于一点才被认为是直线lines = cv.HoughLines(edges, 1.0, np.pi/180, 150)# 将检测到的直线通过极坐标的方式画出来print(lines.ndim)print(lines.shape)for line in lines:# line[0]存储的是点到直线的极径和极角,其中极角是弧度表示的,theta是弧度rho, theta = line[0]# 下述代码为获取 (x0,y0) 具体值a = np.cos(theta)b = np.sin(theta)x0 = a*rho
        y0 = b*rho# 下图 1000 的目的是为了将线段延长# 以 (x0,y0) 为基础,进行延长x1 = int(x0+1000*(-b))y1 = int(y0+1000*a)x2 = int(x0-1000*(-b))y2 = int(y0-1000*a)cv.line(src, (x1, y1), (x2, y2), (0, 255, 0), 2)cv.imshow("src", src)cv.waitKey()cv.destroyAllWindows()

    上述代码中,相关说明如下:

    • 第二个参数为半径的步长,第三个参数为每次偏转的角度,即我们提及的 ρθ;

    • rho 参数为极径 r, 以像素值为单位, 本案例使用 1 像素;

    • theta参数极角 θ 以弧度为单位,本案例使用 1 度 (即 np.pi/180);

    • threshold 参数随便给的。

    还有计算具体坐标用到的公式其实是这样的:(p,q) = (rcosθ,rsinθ)

    运行效果基本满意,达到预期。
    Python OpenCV 霍夫(Hough Transform)直线变换检测应用

    概率霍夫变换(Probabilistic Hough Transform)

    概率霍夫变换是一种概率直线检测,它是针对于上文标准霍夫检测的优化,核心点是采取概率挑选机制,选取一些点出来进行计算,相当于降采样。

    函数名称与原型如下:

    lines = cv2.HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]])

    参数说明:

    • src:输入 8-bit 的灰度图像;

    • rho:像素为单位的距离精度,double 类型的,推荐用 1.0;

    • theta:以弧度为单位的角度精度,推荐用 numpy.pi/180;

    • threshold:阈值;

    • lines:输出的极坐标来表示直线;

    • minLineLength:最短长度阈值,比这个长度短的线会被排除;

    • maxLineGap:最大间隔,如果小于此值,这两条直线就被看成是一条直线。

    该函数还有一个优点,返回值是一条条线段,不用我们在进行转换了

    修改上文代码如下,参数赋值部分直接写的,你可以自由修改,也可以通过滑动条调参:

    import cv2 as cvimport numpy as np
    
    src = cv.imread("./331.jpg")gray_img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)dst = cv.equalizeHist(gray_img)# 高斯滤波降噪gaussian = cv.GaussianBlur(dst, (9, 9), 0)# cv.imshow("gaussian", gaussian)# 边缘检测edges = cv.Canny(gaussian, 70, 150)cv.imshow("edges", edges)lines = cv.HoughLinesP(edges, 1.0, np.pi/180, 100,   minLineLength=100, maxLineGap=6)print(type(lines))for line in lines:x1, y1, x2, y2 = line[0]cv.line(src, (x1, y1), (x2, y2), (0, 255, 0), 2)cv.imshow("src", src)cv.waitKey()cv.destroyAllWindows()

    运行代码之后,可以获取到相应的线段。
    Python OpenCV 霍夫(Hough Transform)直线变换检测应用

    橡皮擦的小节

    OpenCV 的文章阶段性的难度开始爬升了,有些地方概念还是有点模糊,需要学习的地方太多了,一起加油吧

    希望今天的 1 个小时(今天内容有点多,不一定可以看完),你有所收获,我们下篇博客见~

    相关阅读


    技术专栏

    1. Python 爬虫 100 例教程,超棒的爬虫教程,立即订阅吧

    2. Python 爬虫小课,精彩 9 讲


    今天是持续写作的第 74 / 100 天。
    如果你有想要交流的想法、技术,欢迎在评论区留言。


    如果你想跟博主建立亲密关系,可以关注博主,或者关注博主公众号 “非本科程序员”,了解一个非本科程序员是如何成长的。
    博主 ID:梦想橡皮擦,希望大家点赞、评论、收藏。

    梦想橡皮擦CSDN认证博客专家高级产品经理互联网从业者业余编程爱好者
    6 年产品经理+教学经验,3 年互联网项目管理经验;互联网资深爱好者;沉迷各种技术无法自拔,导致年龄被困在 25 岁;CSDN 爬虫 100 例作者。个人公众号“非本科程序员”。

    本文链接: http://www.dtmao.cc/news_show_2000244.shtml

    附件下载

    相关教程

      暂无相关的数据...

    共有条评论 网友评论

    验证码: 看不清楚?