c++ hough变换代码_hough变换原理以及实现(转载)

原理链接如下:陌归:霍夫(Hough)变换之直线检测

代码链接:Ganso:Fundamentals——从车道线检测谈到霍夫变换

同样是一篇讲解原理的番外,这一篇主要讲解CV中常用的霍夫变换的数学原理。

霍夫变换的由来

“霍夫变换于1962年由Paul Hough首次提出,最初的Hough变换是设计用来检测直线和曲线,起初的方法要求知道物体边界线的解析方程,但不需要有关区域位置的先验知识。后于1972年由Richard Duda & Peter Hart推广使用。”

其实,霍夫变换的中心思想就是通过坐标变换来检测直线,后来经过改进,就可以检测椭圆等。

霍夫线变换

坐标系的角度:

说起直线,我们会想到笛卡尔坐标系(即x-y坐标系)下的直线方程,细分之则有点斜式、截距式等,

是我们最熟悉的一种。但直线垂直于x轴时斜率
不存在,这给我们带来许多不便之处。

这时极坐标就carry全场了,它与笛卡尔坐标系的转换关系:

,变形可得
为原点到直线的距离,也常用
表示,示意图如下:

50dca3042e2bd79d6056f916f9ede15f.png

由此极坐标下,直线可用

表示。这就启发我们,同一直线上的点具有相同的

1c62d69e8fb9800e316d1de66dd5cfc9.png
x-y坐标系下的一个点在rho-theta坐标系下为正弦曲线

b373328976dee12818644b3062262b7a.png
同一直线上的点会有相同的rho和theta,即在rho-theta下交于一点

统计学的角度:

内容出自:Opencv学习笔记-----霍夫变换直线检测及原理理解 - CSDN博客

d85a8c8af9c3106c581046b6d1ba5345.png

如上图,假定在一个8*8的平面像素中有一条直线,并且从左上角

像素点开始分别计算
为0°、45°、90°、135°、180°时的
,图中可以看出
分别为
,并给这5个值分别记一票,同理计算像素点
为0°、45°、90°、135°、180°时的
,再给计算出来的5个
值分别记一票,此时就会发现
的这个值已经记了两票了,以此类推,遍历完整个8*8的像素空间的时候
就记了5票, 别的
值的票数均小于5票,所以得到该直线在这个8*8的像素坐标中的极坐标方程为
,到此该直线方程就求出来了。

霍夫圆变换

霍夫圆变换使用的算法叫霍夫梯度法,对应的函数为HoughCircles,这个函数实际上是对常规找圆算法的一种改进,这里不展开讲,想学习这个原理的同学请参考找圆算法((HoughCircles)总结与优化 - CSDN博客

1. base

导入必要的包,顺便写一个打印图像的函数,cv2与plt颜色通道不一致(所以为什么不用plt导入呢)。

import numpy as np
import matplotlib.pyplot as plt
import cv2# opencv的颜色通道顺序为[B,G,R],而matplotlib的颜色通道顺序为[R,G,B]。
def plotImg(img):if len(img.shape)==3:img = img[:,:,(2,1,0)]plt.imshow(img)else:plt.imshow(img, cmap='gray')plt.show()

导入图片,感觉如果干扰很多效果也不会太好。

image = cv2.imread('test_image.jpg')
plotImg(image)

b1c6c8e79981c229f5a2a74dbbc9077d.png

canny

灰度,模糊,canny三连击。
canny输入需求如此。

def canny(image):gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)blur = cv2.GaussianBlur(gray,(5,5),0)canny = cv2.Canny(blur, 50, 150)return cannylane_image = np.copy(image)
canny = canny(lane_image)
plotImg(canny)

02e0b2fb2536313b1f37895b50c66a35.png

region_of_interest

手工特征区域?作者的思路也是蛮清奇的。
简单来说就是对于视角前面的三角形区域做了一个mask,全部填充255,与原图像bitwise。

def region_of_interest(image):height = image.shape[0]polygons = np.array([[(200,height), (1100,height), (550,250)]])mask = np.zeros_like(image)cv2.fillPoly(mask, polygons, 255)masked_image= cv2.bitwise_and(image,mask)return masked_imagecropped_image = region_of_interest(canny)
plotImg(cropped_image)

a9dbdf7a4a5b8d7682e4c33dc704ba90.png

091455c4df7168d0a199a34b6f9b1837.png

2. Hough Transform

将图像提取边缘之后获得了很多杂乱的点,而我们需要做的就是找到过这些点的公共直线。

点斜式方程

点斜式方程是

,那么对于经过下图黑色点的直线簇,我们可以将其映射到一个以m,b位坐标的空间,b是m的线性函数。对于不同的两个点,我们可以将其直线簇映射到mb空间的两个直线上,而mb空间两个直线的交点(m,b)就是这两个点公共直线的参数。但是这样还是存在问题的,当直线是垂直的时候,m趋向于无穷,不好表示,我们需要另外一种映射。

5cd13ce38b3e10625997882995b54edf.png

极坐标方程

在极坐标空间中,对于过固定点的直线,过原点做垂线,记距离为

,夹角为
,通过图示我们可以得到对于过一点x,y的直线簇有:

e528fe452f6199c8bb80a8d1b115f372.png

也就是说过固定点的直线簇

之间有一定的函数关系。

霍夫变换

我们将过每个点的直线簇映射到极坐标空间,基本都由一条曲线表示,比如图示的三个点,这样。曲线的交点对应的坐标就是过所有点的直线的极坐标参数。

e26e4e588eaa23a5a499ea1c0a5f328d.png

投票机制

当图片上的点非常多时,所有曲线并不期望相交于一点。我们可以将霍夫空间划分为一个个patch,当一个patch上面的交点满足大于某个threshold时,我们视为这些点有它们的公共直线。

7c972031b69a5892b4fc43d60ba02f4d.png

3. cv2实现

cv.2HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]])

参数
image 图像。
rho、theta:分辨率。(分别率就是指同一个角度,如果计算出两点的rio值小于2,则认为是同一直线。)
threshold:投票阈值。
lines:没有查到。
minLineLength:最小线条长度。
maxLineGap:最大线条间隔。

def display_lines(image,lines):line_image = np.zeros_like(image)if lines is not None:for line in lines:x1, y1, x2, y2 = line.reshape(4)cv2.line(line_image, (x1,y1), (x2,y2),(255,0,0),10)return line_imagelines = cv2.HoughLinesP(cropped_image, 2, np.pi/180, 100, np.array([133,2]), minLineLength=40, maxLineGap=5)
line_image = display_lines(image,lines)
plotImg(line_image)combo_image = cv2.addWeighted(lane_image,0.8, line_image,1,1)
plotImg(combo_image)

霍夫变换求直线

89d743002caca940846f802347727a37.png

8c807c0b2ee2ddee46824cefc53a7ab4.png

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

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

相关文章

java filter url匹配规则_java过滤器filter使用

一:filter:过滤器,拦截servlet的请求和响应。1、1 package jd.com.filter;23 import javax.servlet.*;4 import java.io.IOException;56 public classMyFilter implements Filter {7 Override8 public voiddestroy() {910 }1112 Override13 public voidi…

怎么对document.write写出来的内容调整对齐方式_干不过写PPT的?麦肯锡老阿姨教你4招...

PPT是我真正花过10,000小时以上的技能,毕竟在麦肯锡呆了7年。麦肯锡PPT重视内容与逻辑,我改行做营销后又开始注意视觉效果。怎么干过我们这些画PPT的?:)从内容到形式,我来讲讲4步流程,有助于提高效率。/ 01…

iphone查看删除的短信_苹果删除的短信

苹果删除的短信怎么恢复?大家在使用手机的时候,有些没用的短信就习惯清除了,但是有时候比较重要的短信很可能也会误删,后期想要找确又找不到,那么苹果删除的短信能恢复吗?怎么恢复呢?下面就来详细介绍一下。苹果删除的短信怎么…

pythonrequests证书_python requests证书问题解决

用requests包请求https的网站时,我们偶尔会遇到证书问题。也就是常见的SSLerror,遇到这种问题莫慌莫慌。这里没有找到合适的网站去报SSL证书的错误,所以就假装请求了一个https的网站,然后给报了SSLerror了,然后下面是解…

vscode代码运行时间工具_代码编辑器横评:为什么 VS Code 能拔得头筹

2015 年 4 月 29 日的 Build 大会上,微软发布了 Visual Studio Code 第一个预览版本。短短四年时间里,VS Code 高速成长。根据 2019 年 2 月的 PYPL Top IDE index 的排名,VS Code 的涨势迅猛,在所有编辑器与 IDE 中排名第六&…

mysql表还原初始状态_workbench 怎么恢复初始设置

答:同学你好,在ANSYS workbench的材料建模当中如果不小心把原来的布局给弄乱了,可以通过设置view菜单里面的reset window layout来恢复,具体的操作如图所示(另外在workbench的模型前处理中如果弄乱了也可以通过这个方法来实现)&am…

ie浏览器网页版进入_Win10系统中IE和edge浏览器无法打开网页如何解决

Win10系统中IE和edge浏览器无法打开网页如何解决最近有Win10系统用户们反馈最新Win10系统中的IE和edge浏览器都无法上网,打不开网页,而第三方浏览器却可以,遇到这样的情况该如何解决呢?引起IE和edge浏览器无法打开网页的可能原因&#xff0c…

java二期_JAVA基础之多线程二期

一、主线程public class MainThread {/*** 主线程:指执行main()方法的线程,且该线程是单线程,从上到下执行* JVM执行main()方法时,JVM会将main()方法放入到栈内存中执行,* 同时CPU会为main()方法开辟一条执行路径&…

cad插件_CAD素材与插件合集

CAD素材与插件合集CAD字体包下载链接:https://pan.baidu.com/s/16Wq4boqm254qJNJG5fD5EA提取码:h28nCAD经典模式下载链接:https://pan.baidu.com/s/18U6vSetQxg6bCNJDElZtFA提取码:wlje电气符号下载链接:https://pan.b…

一个form 如何做两次提交_如何做一个自信魅力的女人

有一种常见的说法是外观完全决定了吸引力,错,如果你希望人们被你吸引,如果你想做一个优秀的、成功的、万众瞩目的女性,那么你必须做很多努力,才能成为一个有魅力的人。1做自己不要复制像杰西卡兰格或安德里亚汤普森这样…

python的语句_Python的语句

python中的两种语句&#xff1a;1、if条件控制语句格式&#xff1a;if:a int(input("请输入第一个数&#xff1a;"))b int(input("请输入第二个数&#xff1a;"))if a < b:print("a比b小")if-else:a int(input("请输入第一个数&#…

vbs代码炫酷效果_Python|实现黑客帝国代码雨效果

Python|实现黑客帝国代码雨效果估计大家都看过电影《黑客帝国》吧&#xff0c;片中的一段代码雨片段实在是炫酷&#xff0c;试想一下&#xff0c;片中的代码雨效果在自己电脑屏幕上实现了会是一种什么样的感觉&#xff0c;会不会有种身临黑客之境呢&#xff1f;本着满足好奇心和…

电脑手写输入法_百度输入法“手写输入”为什么不是老年人的专利?AI的进步...

智能手机的不断普及&#xff0c;也让人机交互取得了很快的发展&#xff0c;就从大家一下常用的设计输入法来看&#xff0c;效果也是越来越智能化了&#xff0c;一个输入法的自我修养选择gboard的原因有很多种&#xff0c;这也是作为一款我国国民输入法的第一要素&#xff0c;毕…

java abs前缀变量_JAVA工具例大全--cn.hutool.setting.AbsSetting读取配置文件例子

用类cn.hutool.setting.AbsSetting的如下方法:getCharpublic Character getChar(String key,String group)获取char类型属性值Parameters:key - 属性名group - 分组名Returns:属性值引用hutool,在项目maven的pom.xml的dependencies中加入以下内容:cn.hutoolhutool-all5.4.3读取…

python语言的数据类型图解_Python基础——数据类型(图解+实例,非常详细!)

Python基础——数据类型(图解实例&#xff0c;非常详细&#xff01;)Python基础——数据类型(图解实例&#xff0c;非常详细&#xff01;)内容及版权声明&#xff1a;笔记是根据开课吧——Python语法爬虫分析课和自己的理解记录&#xff0c;其中包含课程的截图&#xff0c;仅学…

台式电脑如何设置开机密码_设置苹果Mac电脑的开机密码-macw资讯

有很多用户刚从windows系统转过来使用mac系统&#xff0c;可能有很多东西都不知道在哪里&#xff0c;不知道怎么去设置&#xff1f;下面我们就来看下mac是怎样设置开机密码的。非常简单&#xff0c;来跟小编一起来学习然后设置苹果Mac电脑的开机密码吧&#xff01;1、首先&…

java重写面试题_Java面试题:重写了equals方法,为什么还要重写hashCode方法?

核心问题&#xff1a;重写了equals方法&#xff0c;为什么还要重写hashCode方法&#xff1f;这不仅仅是一道面试题&#xff0c;而且是关系到我们的代码是否健壮和正确的问题。在前面两篇文章涉及到了equals方法的底层讲解&#xff1a;《说说和equals的区别&#xff1f;你的回答…

python怎么读取石墨表格_每2秒进行一次statsd xaxis石墨统计 - python

我已经安装了石墨&#xff0c;nodejs-statsd(用于接收数据)和python statsd客户端(用于发送数据)。下面是一个测试脚本&#xff0c;该脚本将数据发送到statsd进程的udp套接字。#!/usr/bin/env pythonimport timeimport randomimport statsdc statsd.StatsClient(localhost,812…

电脑显示器闪屏_Win7系统电脑显示器屏幕闪屏的解决办法

Win7系统电脑闪屏怎么办&#xff1f;近日一个用户反馈&#xff0c;在使用Win7系统电脑的时候&#xff0c;会出现闪屏的问题&#xff0c;该如何解决呢&#xff1f;请看下文具体解决办法。解决办法&#xff1a;1、首先右击桌面空白处&#xff0c;并在右键菜单中&#xff0c;直接选…

java webservice 身份验证_java-Http基本身份验证不适用于Spring WS和WebS...

我尝试使用Spring(-WS)将HTTP基本身份验证凭据添加到我的SOAP请求中.该请求本身有效,但是没有凭据提交. HTTP标头应如下所示&#xff1a;[...]Connection: Keep-AliveUser-Agent: Apache-HttpClient/4.1.1 (java 1.5)Authorization: Basic mybase64encodedtopsecretcredentials…