霍夫直线检测算法
霍夫直线检测算法
霍夫直线检测算法是一种经典的图像处理算法,主要用于检测图像中的直线。
其基本原理是将图像中的每条直线转换为参数空间中的一个点,然后统计所有点的数量,并找出最大数量的点所代表的直线。
具体步骤如下:
1. 预处理图像:将图像转换为灰度图,并进行边缘检测,得到二值化图像。
2. 构建参数空间:以极坐标系表示直线,建立以直线的极径r和极角theta为坐标轴的二维参数空间。
3. 在参数空间中累加:对于图像中的每一个边缘像素点,在参数空间中对应于所有可能的直线(不同的theta和不同的r值),将对应的点的数量加1。
4. 提取直线:在参数空间中找到数量最大的点,该点所对应的直线即为图像中的一条直线。
将该直线在图像中画出。
5. 重复步骤4,找出剩下的直线。
霍夫直线检测算法在处理直线比较集中的图像时效果比较好,但对于直线数量较多或者遮挡比较严重的图像效果不佳。
此外,算法的时间复杂度较高,因此
在实际应用中一般需要结合其他方法来提高检测效率。
hough变换直线检测主要原理
hough变换直线检测主要原理
霍夫变换是一种在图像空间进行几何形状检测的方法,用于检测平面上的直线。
主要原理如下:
1. 点与直线的表示:霍夫变换使用极坐标系来表示直线,每个点在图像中表示一条通过该点的直线。
直线可以用两个参数表示:r表示离原点的距离,θ表示与x轴的夹角。
2. 累加过程:对每个点,遍历所有可能的直线参数,并在霍夫空间中进行累加。
对于每个点,对应于通过该点的所有直线,累加器中相应位置的值加1。
这个累加过程可以在霍夫空间中的一个二维数组中进行。
3. 阈值检测:当累加器中的某个值超过预设的阈值时,认为该直线存在。
这个阈值可以根据应用需求进行设置。
4. 参数反算:根据累加器中的峰值,反算出对应的直线参数(r和θ),并在图像中绘制出检测到的直线。
霍夫变换的主要优点是对于存在噪声和局部遮挡的图像仍然能够有效地检测直线。
但是其缺点是计算复杂度较高,直线的参数空间较大,需要处理大量的累加器。
同时,霍夫变换对于直线的精确定位和参数估计准确性不高,对于曲线的检测效果较差。
OpenCV---直线检测
OpenCV---直线检测直线检测相关Hough变换是经典的检测直线的算法。
其最初⽤来检测图像中的直线,同时也可以将其扩展,以⽤来检测图像中简单的结构。
变换图⽰霍夫直线检测的两种⽅法1.获取灰度图像2.canny边缘检测3.获取霍夫直线信息4.算出直线位置,画出每条直线⼀:HoughLines霍夫变换def line_detection(image):gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)edges = cv.Canny(gray,50,150,apertureSize=3) #apertureSize是sobel算⼦⼤⼩,只能为1,3,5,7lines = cv.HoughLines(edges,1,np.pi/180,200) #函数将通过步长为1的半径和步长为π/180的⾓来搜索所有可能的直线for line in lines:rho,theta = line[0] #获取极值ρ长度和θ⾓度a = np.cos(theta) #获取⾓度cos值b = np.sin(theta) #获取⾓度sin值x0 = a * rho #获取x轴值y0 = b * rho #获取y轴值 x0和y0是直线的中点x1 = int(x0 + 1000*(-b)) #获取这条直线最⼤值点x1y1 = int(y0 + 1000*(a)) #获取这条直线最⼤值点y1x2 = int(x0 - 1000 * (-b)) #获取这条直线最⼩值点x2 y2 = int(y0 - 1000 * (a)) #获取这条直线最⼩值点y2 其中*1000是内部规则cv.line(image,(x1,y1),(x2,y2),(0,0,255),2) #开始划线cv.imshow("image line",image)src = cv.imread("./l.png") #读取图⽚dWindow("input image",cv.WINDOW_AUTOSIZE) #创建GUI窗⼝,形式为⾃适应cv.imshow("input image",src) #通过名字将图像和窗⼝联系line_detect_possible_demo(src)cv.waitKey(0) #等待⽤户操作,⾥⾯等待参数是毫秒,我们填写0,代表是永远,等待⽤户操作cv.destroyAllWindows() #销毁所有窗⼝相关知识补充(⼀)HoughLines⽅法def HoughLines(image, rho, theta, threshold, lines=None, srn=None, stn=None, min_theta=None, max_theta=None): # real signature unknown; restored from __doc__ cv.HoughLines(edges,1,np.pi/180,200)cv2.HoughLines函数输出的是[float, float]形式的ndarray,其中每个值表⽰检测到的线(ρ , θ)中浮点点值的参数。
霍夫变换(详解)
给定具体的五个点:
(a)image space
(b)hough space
选择由尽可能多直线汇成的点,如A和B。
y=x-1 y=1 (a)image space (b)hough translation
A,B确定了两组参数(k,q),代入直线方程y=kx+q, 可以描述图像空间中对应的直线。
特殊情况,
hough translation 霍夫变换检测直线
基本原理
霍夫变换利用点和线之间的对偶性,将 图像空间中直线上离散的 像素点 通过参数方 程映射为霍夫空间中的 曲线 ,并将霍夫空间 中多条曲线的 交点 作为直线方程的参数 映射 为图像空间中的 直线。 给定直线的参数方程,可以利用霍夫变 换来检测图像中的直线。
原图
二值化
canny边缘检测
霍夫变换直线检测
谢谢!
给定具体的三个点:
y=x-1
(1,-1) (a)image space 图像空间中共线的点, 在霍夫空间对应的直线相交于一点。 (b)hough space
点和线的对偶性
(1)图像空间中的点,对应霍夫空间中的直 线。 (2)图像中的直线,对应霍夫空间中的点。 (3)共点的直线,在霍夫空间中对应的点在 一条直线上。 (4)共线的点,在霍夫空间中对应的直线交 与一点。
(b)hough space
过同一点的直线,在霍夫空间中所对应的点在一条直线上。
两个点的情况:
y=kx+q
(k,q)
(a)image space 霍夫空间中的交点,确定了一组参数(k,q) 。 将(k,q)代入直线方程 y=kx+q , 可以描述图像空间中过A,B两点的直线。
(b)hough space
霍夫变换直线检测原理
霍夫变换直线检测原理
霍夫变换(Hough Transform)是一种用来检测图像中的直线的算法,它在图像处理领域非常重要,它可以用来检测图像中的线条,圆和椭圆。
霍夫变换的基本原理是,将输入图像中的每个像素点看作是坐标系中的一个点,然后通过一些函数来确定是否存在直线,圆或椭圆,并将这些函数称为霍夫变换函数。
霍夫变换的直线检测是一个非常重要的过程,它的基本原理是将输入图像中的每个像素点看作是坐标系中的一个点,然后用霍夫变换函数来检测输入图像中是否存在直线。
霍夫变换函数有两种,一种是极坐标函数,另一种是直角坐标函数。
在极坐标函数中,霍夫变换函数的形式是:r=xcosθ+ysinθ,在直角坐标函数中,霍夫变换函数的形式是:y=mx+b。
霍夫变换直线检测的过程大致分为以下几步:首先,将输入图像转换为灰度图像,然后使用适当的滤波算法去除噪声;其次,使用边缘检测算法检测图像的边缘,并获得边缘的像素点坐标;然后,使用霍夫变换函数对边缘的像素点进行拟合,获得直线的参数;最后,使用拟合后的参数对直线进行绘制,完成图像中直线检测的任务。
总而言之,霍夫变换是一种用来检测图像中的直线的算法,它是一种极其重要的算法,它可以有效地检测图像中的线条,圆和椭圆,而其直线检测的原理是,将输入图像中的每个像素点看作是坐标系
中的一个点,然后使用霍夫变换函数拟合像素点,获得直线的参数,最后使用参数对直线进行绘制。
霍夫变换后的直线p值
霍夫变换后的直线p值霍夫变换是一种常用的图像处理算法,主要用于检测图像中的直线或其他几何形状。
在霍夫变换中,直线被表示为参数空间中的一个点,而不是在图像中的像素点。
这种表示方式使得直线的检测更加简便和高效。
在霍夫变换中,直线p的值表示直线的参数,通常是两个参数的组合,比如直线的斜率和截距。
通过对图像进行霍夫变换,可以得到参数空间中的一个点,该点对应于图像中的一条直线。
通过遍历整个图像,我们可以得到所有直线的参数点,并通过对这些点的分析和处理,实现对图像中直线的检测和提取。
使用霍夫变换检测直线的过程可以分为以下几个步骤:1. 边缘检测:首先对图像进行边缘检测,将图像中的边缘提取出来。
常用的边缘检测算法有Sobel算子、Canny算子等。
2. 参数空间的建立:根据直线的参数表示方式,建立一个参数空间,通常是一个二维的极坐标空间。
参数空间中的每个点表示一条直线的参数。
3. 点投票:遍历图像中的每个边缘点,将其在参数空间中对应的点进行投票。
每个边缘点的投票数将决定该直线参数点的强度。
4. 参数点的分析和处理:根据参数空间中的投票结果,可以找到投票数最多的几个点,这些点对应的直线参数即为最可能的直线。
可以通过设定一个阈值来确定哪些参数点表示的直线是有效的。
5. 直线的提取:根据最终确定的直线参数,可以将其转换回图像空间,得到图像中的直线。
霍夫变换在图像处理领域有着广泛的应用。
比如在计算机视觉中,可以通过霍夫变换检测图像中的直线,用于目标检测、图像配准等任务。
在自动驾驶领域,可以通过霍夫变换检测图像中的道路线,用于车道线检测和车道保持等功能。
然而,霍夫变换也存在一些限制。
首先,霍夫变换对噪声比较敏感,噪声点容易干扰到参数空间的计算。
其次,霍夫变换的计算复杂度较高,对于大规模图像的处理可能会耗费较多的时间和计算资源。
此外,霍夫变换只能检测直线,对于其他形状的检测需要使用其他的方法。
总结起来,霍夫变换是一种常用的图像处理算法,可以用于检测图像中的直线或其他几何形状。
霍夫直线检测matlab
霍夫直线检测matlab霍夫直线检测(Matlab程序实现)霍夫直线检测算法是一种基于图像的分析方法,它可以检测图像中的直线,适用于任何图像,包括灰度图像和彩色图像。
此方法可用于计算机视觉中检测物体轮廓的任务。
以下是Matlab程序实现霍夫直线检测的步骤:第一步:读取图片使用Matlab的imread函数从文件中读取图像。
im = imread('image.jpg');第二步:把图像转换为灰度图像使用Matlab的rgb2gray函数,把读取的图像转换为灰度图像。
im_gray = rgb2gray(im);第三步:对灰度图像进行边缘检测使用Matlab的edge函数,对图像进行边缘检测,以检测图像中的直线。
im_edges = edge(im_gray,'canny');第四步:使用Hough变换检测直线使用Matlab的hough函数,对图像中的边缘进行Hough变换,以检测图像中的直线。
[H, theta, rho] = hough(im_edges);第五步:绘制Hough变换图形使用Matlab的imshow函数,绘制Hough变换图形,以检测图像中的直线。
imshow(H,[],'XData',theta,'YData',rho);第六步:检测直线使用Matlab的houghpeaks函数,检测图像中的直线。
P = houghpeaks(H,5);第七步:从houghpeaks检测到的顶点中抽取直线使用Matlab的houghlines函数,从houghpeaks检测到的顶点中抽取直线。
lines = houghlines(im_edges,theta,rho,P);第八步:绘制检测到的直线使用Matlab的imshow函数,绘制检测到的直线。
OpenCV实现霍夫变换直线检测
OpenCV实现霍夫变换直线检测霍夫变换(Hough Transform)是图像处理中检测是否存在直线的重要算法,该算法是由Paul Hough在1962年⾸次提出,最开始只能检测图像中的直线,但是霍夫变换经过不断的扩展和完善已经可以检测多种规则形状,例如圆形、椭圆等。
霍夫变换通过将图像中的像素在⼀个空间坐标系中变换到另⼀个坐标空间坐标系中,使得在原空间中具有形同特性的曲线或者直线映射到另⼀个空间中形成峰值,从⽽把检测任意形状的问题转化为统计峰值的问题。
霍夫变换通过构建检测形状的数学解析式将图像中像素点映射到参数空间中,例如我们想检测两个像素点所在的直线,需要构建直线的数学解析式。
在图像空间x-y直⾓坐标系中,对于直线可以⽤式(7.1)所⽰的解析式来表⽰。
其中k是直线的斜率,b是直线的截距。
假设图像中存在⼀像素点A(x0,y0),所有经过这个像素点直线可以⽤式表⽰。
在图像空间x-y直⾓坐标系中,由于变量是x和y,因此式表⽰的是经过点像素点A(x0,y0)的直线,但是经过⼀点的直线有⽆数条,因此式中的和具有⽆数个可以选择的值,如果将x0和y0看作是变量, k和 b表⽰定值,那么式可以表⽰在k-b空间的⼀条直线,映射过程⽰意图如图所⽰。
⽤式的形式表⽰映射的结果如式所⽰,即霍夫变换将x-y直⾓坐标系中经过⼀点的所有直线映射成了k-b空间中的⼀条直线,直线上的每个点都对应着x-y直⾓坐标系中的⼀条直线。
当图像中存在另⼀个像素点B(x1,y1)时,在图像空间x-y直⾓坐标系中所有经过像素点B(x1,y1)的直线也会在参数空间中映射出⼀条直线。
由于参数空间中每⼀个点都表⽰图像空间x-y直⾓坐标系中直线的斜率和截距,因此如果有⼀条直线经过像素点A(x0,y0)和像素点B(x1,y1)时,这条直线所映射在参数空间中的坐标点应该既在像素点A(x0,y0)映射的直线上⼜在像素点B(x1,y1)映射的直线上。
在平⾯内⼀个点同时在两条直线上,那么这个点⼀定是两条直线的交点,因此这条同时经过A(x0,y0)和B(x1,y1)的直线所对应的斜率和截距就是参数空间中两条直线的交点。
霍夫变换+最小二乘法 直线检测
霍夫变换中直线拟合的最小二乘法ichriZ 1.基本概念(1)霍夫变换霍夫变换(Hough Transform) 是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进算法。
最基本的霍夫变换是从黑白图像中检测直线或线段。
(2)最小二乘法曲线拟合方法的一种,通过最小化误差的平方和寻找数据的最佳函数匹配。
2.适用情况霍夫变换是基于统计的方法,能将图像中的噪声或干扰点的影响消除,但其结果存在精度不够与直线有效区间不易控制的问题;最小二乘法是直线拟合的有效方法,但直接用于拟合时易受干扰点或噪声点影响。
在检测图像中的直线段时,先利用霍夫变换消除无效点的影响,再结合最小二乘法法进行拟合,可以提高检测效果。
3.霍夫变换原理与实现方法(一)霍夫变换原理在平面直角坐标系中一条直线,任取其上一点,有表示参数平面中的一条直线。
再取上另一点则有表示参数平面中的一条直线。
与相交于一点,对应于坐标系中直线即:同一直线上的不同的点在对应的参数平面中对应不同的直线,但都交于同一点,所以可以通过坐标系中的交点来寻找坐标系中的直线。
当坐标系中的直线数量为R时,坐标系中对应R个峰值交点,它们对应于坐标系中的R 条直线。
此种方法不能够表示这类直线,实际中常将原有直线表示为参数方程此直线上的点对应坐标系中的一族三角函数曲线,它们在有效区间内交于一点,对应于坐标系中的。
下图是一个具体例子:交点坐标(二)最小二乘法原理对于给定数据,要求在某个函数类中寻求一个函数,使本文中讨论的是直线的最小二乘法,故均取一次多项式。
设具有如下格式霍夫变换—>其中是待定参数,求具有这种形式的最小二乘法的实质,就是要适当的选择参数,使相应的函数满足条件。
也就是说,点是多元函数的极小点,从而满足方程组因此,可以通过解此方程组(称为法方程组)来求取,以便获得最小二乘解。
当讨论的曲线为代数多项式时,不妨取则有令得方程组即本文中模拟的是直线,使用一次多项式,则约束条件为其中直线表达式为(三)霍夫变换的实现方法图像处理中的二值边缘图,一般是处理离散数据,则根据霍夫变换可按下列步骤实现直线检测:(1)参数空间量化成m*n(m为的等分数,n为的等分数)个单元,并设置累加器矩阵;(2)给参数空间中的每个单元分配一个累加器,并把累加器的初始值置为0;(3)取出直角坐标系中的点带入式,并以量化的值计算出;(4)在参数空间中,找到和所对应的单元,并将该单元的累加器加1,即(5)当直角坐标系中的点都经过(3)(4)两步遍历后,检测参数空间中每个累加器的值,累加器最大的单元所对应的和即为直角坐标系中直线方程式的参数。
霍夫变换检测图像直线算法python实现
霍夫变换检测图像直线算法python实现创作不易,如果对您有帮助,帮忙点赞哦!⼀. 霍夫变换理解:可参考:⼆. 霍夫变换简介:霍夫变换,是将坐标由直⾓坐标系变换到极坐标系,然后再根据数学表达式检测某些形状(如直线和圆)的⽅法。
当 l1直线上的某些点变换到极坐标系下时,表现为某些线(和前⾯点数量⼀致),这些线交于⼀点,通过该点的坐标就能表⽰原先的 l1直线。
三. 霍夫变换⽤于检测图像直线算法实现:①提取图像边缘(可使⽤Canny算法等)[我也实现了它,前⾯Canny算法有问题可以参考我的另⼀篇⽂章:]②实现⼆值图像霍夫变换1. 求出图像对⾓线长:r_max2. 在边缘点 (x,y) 处,t 取[0,180),步长设为1,根据下式进⾏霍夫变换霍夫变换,(r_ho,t) 表⽰极坐标,(x,y) 表⽰直⾓坐标↑3. 做⼀个⼤⼩为 r_max * 180 的表,变换后⼀个值落在表内某坐标,就将该坐标表内值 + 1,简⾔之,就是在进⾏投票,统计通过哪个点的直线的数量最多(即在原图像上越趋近于⼀条直线)。
③进⾏⾮极⼤值抑制(NMS)操作,使找出的直线落在不同的地点NMS 的算法如下:1. 遍历该表,如果遍历到的像素的投票数⼤于其8近邻的像素投票值,则它不变。
2. 如果遍历到的像素的投票数⼩于其8近邻的像素投票值,则将其设置为0。
④找到20个投票数最多的点(即:直⾓坐标系下20条直线)准备进⾏输出1. np.ravel 将多维数组降为1维2. np.argsort 将数组元素从⼩到⼤排序,返回索引值3. [::-1] 数组反序 -> 得到从⼤到⼩索引值4. [:20] 前20个最⼤投票值的索引5. 根据索引得到坐标(r,t)⑤霍夫反变换后,画出原图中的20条直线,输出图像霍夫逆变换公式↑四. 纯⼿⼯实现 ——> 利⽤霍夫变换检测图像中的直线2import numpy as np3import matplotlib.pyplot as plt45# Canny算法:提取图像边缘6def Canny(img):78# Gray scale9def BGR2GRAY(img):10 b = img[:, :, 0].copy()11 g = img[:, :, 1].copy()12 r = img[:, :, 2].copy()1314# Gray scale15 out = 0.2126 * r + 0.7152 * g + 0.0722 * b16 out = out.astype(np.uint8)1718return out192021# Gaussian filter for grayscale22def gaussian_filter(img, K_size=3, sigma=1.3):2324if len(img.shape) == 3:25 H, W, C = img.shape26 gray = False27else:28 img = np.expand_dims(img, axis=-1)29 H, W, C = img.shape30 gray = True3132## Zero padding33 pad = K_size // 234 out = np.zeros([H + pad * 2, W + pad * 2, C], dtype=np.float)35 out[pad : pad + H, pad : pad + W] = img.copy().astype(np.float)3637## prepare Kernel38 K = np.zeros((K_size, K_size), dtype=np.float)39for x in range(-pad, -pad + K_size):40for y in range(-pad, -pad + K_size):41 K[y + pad, x + pad] = np.exp( - (x ** 2 + y ** 2) / (2 * sigma * sigma))42#K /= (sigma * np.sqrt(2 * np.pi))43 K /= (2 * np.pi * sigma * sigma)44 K /= K.sum()4546 tmp = out.copy()4748# filtering49for y in range(H):50for x in range(W):51for c in range(C):52 out[pad + y, pad + x, c] = np.sum(K * tmp[y : y + K_size, x : x + K_size, c]) 5354 out = np.clip(out, 0, 255)55 out = out[pad : pad + H, pad : pad + W]56 out = out.astype(np.uint8)5758if gray:59 out = out[..., 0]6061return out626364# sobel filter65def sobel_filter(img, K_size=3):66if len(img.shape) == 3:67 H, W, C = img.shape68else:69 H, W = img.shape7071# Zero padding72 pad = K_size // 273 out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float)74 out[pad : pad + H, pad : pad + W] = img.copy().astype(np.float)75 tmp = out.copy()7677 out_v = out.copy()78 out_h = out.copy()7980## Sobel vertical81 Kv = [[1., 2., 1.],[0., 0., 0.], [-1., -2., -1.]]82## Sobel horizontal83 Kh = [[1., 0., -1.],[2., 0., -2.],[1., 0., -1.]]86for y in range(H):87for x in range(W):88 out_v[pad + y, pad + x] = np.sum(Kv * (tmp[y : y + K_size, x : x + K_size]))89 out_h[pad + y, pad + x] = np.sum(Kh * (tmp[y : y + K_size, x : x + K_size]))9091 out_v = np.clip(out_v, 0, 255)92 out_h = np.clip(out_h, 0, 255)9394 out_v = out_v[pad : pad + H, pad : pad + W]95 out_v = out_v.astype(np.uint8)96 out_h = out_h[pad : pad + H, pad : pad + W]97 out_h = out_h.astype(np.uint8)9899return out_v, out_h100101102def get_edge_angle(fx, fy):103# get edge strength104 edge = np.sqrt(np.power(fx.astype(np.float32), 2) + np.power(fy.astype(np.float32), 2))105 edge = np.clip(edge, 0, 255)106107 fx = np.maximum(fx, 1e-10)108#fx[np.abs(fx) <= 1e-5] = 1e-5109110# get edge angle111 angle = np.arctan(fy / fx)112113return edge, angle114115116def angle_quantization(angle):117 angle = angle / np.pi * 180118 angle[angle < -22.5] = 180 + angle[angle < -22.5]119 _angle = np.zeros_like(angle, dtype=np.uint8)120 _angle[np.where(angle <= 22.5)] = 0121 _angle[np.where((angle > 22.5) & (angle <= 67.5))] = 45122 _angle[np.where((angle > 67.5) & (angle <= 112.5))] = 90123 _angle[np.where((angle > 112.5) & (angle <= 157.5))] = 135124125return _angle126127128def non_maximum_suppression(angle, edge):129 H, W = angle.shape130 _edge = edge.copy()131132for y in range(H):133for x in range(W):134if angle[y, x] == 0:135 dx1, dy1, dx2, dy2 = -1, 0, 1, 0136elif angle[y, x] == 45:137 dx1, dy1, dx2, dy2 = -1, 1, 1, -1138elif angle[y, x] == 90:139 dx1, dy1, dx2, dy2 = 0, -1, 0, 1140elif angle[y, x] == 135:141 dx1, dy1, dx2, dy2 = -1, -1, 1, 1142if x == 0:143 dx1 = max(dx1, 0)144 dx2 = max(dx2, 0)145if x == W-1:146 dx1 = min(dx1, 0)147 dx2 = min(dx2, 0)148if y == 0:149 dy1 = max(dy1, 0)150 dy2 = max(dy2, 0)151if y == H-1:152 dy1 = min(dy1, 0)153 dy2 = min(dy2, 0)154if max(max(edge[y, x], edge[y + dy1, x + dx1]), edge[y + dy2, x + dx2]) != edge[y, x]: 155 _edge[y, x] = 0156157return _edge158159def hysterisis(edge, HT=100, LT=30):160 H, W = edge.shape161162# Histeresis threshold163 edge[edge >= HT] = 255164 edge[edge <= LT] = 0165166 _edge = np.zeros((H + 2, W + 2), dtype=np.float32)167 _edge[1 : H + 1, 1 : W + 1] = edge169## 8 - Nearest neighbor170 nn = np.array(((1., 1., 1.), (1., 0., 1.), (1., 1., 1.)), dtype=np.float32) 171172for y in range(1, H+2):173for x in range(1, W+2):174if _edge[y, x] < LT or _edge[y, x] > HT:175continue176if np.max(_edge[y-1:y+2, x-1:x+2] * nn) >= HT:177 _edge[y, x] = 255178else:179 _edge[y, x] = 0180181 edge = _edge[1:H+1, 1:W+1]182183return edge184185# grayscale186 gray = BGR2GRAY(img)187188# gaussian filtering189 gaussian = gaussian_filter(gray, K_size=5, sigma=1.4)190191# sobel filtering192 fy, fx = sobel_filter(gaussian, K_size=3)193194# get edge strength, angle195 edge, angle = get_edge_angle(fx, fy)196197# angle quantization198 angle = angle_quantization(angle)199200# non maximum suppression201 edge = non_maximum_suppression(angle, edge)202203# hysterisis threshold204 out = hysterisis(edge, 100, 30)205206return out207208# 霍夫变换实现检测图像中的20条直线209def Hough_Line(edge, img):210## Voting211def voting(edge):212 H, W = edge.shape213214 drho = 1215 dtheta = 1216217# get rho max length218 rho_max = np.ceil(np.sqrt(H ** 2 + W ** 2)).astype(np.int)219220# hough table221 hough = np.zeros((rho_max, 180), dtype=np.int)222223# get index of edge224# ind[0] 是符合条件的纵坐标,ind[1]是符合条件的横坐标225 ind = np.where(edge == 255)226227## hough transformation228# zip函数返回元组229for y, x in zip(ind[0], ind[1]):230for theta in range(0, 180, dtheta):231# get polar coordinat4s232 t = np.pi / 180 * theta233 rho = int(x * np.cos(t) + y * np.sin(t))234235# vote236 hough[rho, theta] += 1237238 out = hough.astype(np.uint8)239240return out241242# non maximum suppression243def non_maximum_suppression(hough):244 rho_max, _ = hough.shape245246## non maximum suppression247for y in range(rho_max):248for x in range(180):249# get 8 nearest neighbor250 x1 = max(x-1, 0)251 x2 = min(x+2, 180)253 y2 = min(y+2, rho_max-1)254if np.max(hough[y1:y2, x1:x2]) == hough[y,x] and hough[y, x] != 0: 255pass256#hough[y,x] = 255257else:258 hough[y,x] = 0259260return hough261262def inverse_hough(hough, img):263 H, W, _= img.shape264 rho_max, _ = hough.shape265266 out = img.copy()267268# get x, y index of hough table269# np.ravel 将多维数组降为1维270# argsort 将数组元素从⼩到⼤排序,返回索引271# [::-1] 反序->从⼤到⼩272# [:20] 前20个273 ind_x = np.argsort(hough.ravel())[::-1][:20]274 ind_y = ind_x.copy()275 thetas = ind_x % 180276 rhos = ind_y // 180277278# each theta and rho279for theta, rho in zip(thetas, rhos):280# theta[radian] -> angle[degree]281 t = np.pi / 180. * theta282283# hough -> (x,y)284for x in range(W):285if np.sin(t) != 0:286 y = - (np.cos(t) / np.sin(t)) * x + (rho) / np.sin(t)287 y = int(y)288if y >= H or y < 0:289continue290 out[y, x] = [0,255,255]291for y in range(H):292if np.cos(t) != 0:293 x = - (np.sin(t) / np.cos(t)) * y + (rho) / np.cos(t)294 x = int(x)295if x >= W or x < 0:296continue297 out[y, x] = [0,0,255]298299 out = out.astype(np.uint8)300301return out302303304# voting305 hough = voting(edge)306307# non maximum suppression308 hough = non_maximum_suppression(hough)309310# inverse hough311 out = inverse_hough(hough, img)312313return out314315316# Read image317 img = cv2.imread("../paojie.jpg").astype(np.float32)318319# Canny320 edge = Canny(img)321322# Hough323 out = Hough_Line(edge, img)324325 out = out.astype(np.uint8)326327# Save result328 cv2.imwrite("out.jpg", out)329 cv2.imshow("result", out)330 cv2.waitKey(0)331 cv2.destroyAllWindows()View Code五. 实验结果:原图↑霍夫变换检测到的直线↑六. 参考内容:七. 版权声明:未经作者允许,请勿随意转载抄袭,抄袭情节严重者,作者将考虑追究其法律责任,创作不易,感谢您的理解和配合!。
机器视觉直线检测算法
机器视觉直线检测算法
机器视觉直线检测算法主要包括以下几种:
1. 霍夫变换:这是一种常用的直线检测算法,通过将图像空间中的像素点映射到参数空间中,找到在参数空间中交叉点最多的线段,从而确定直线的位置和方向。
在极坐标下,该算法可以检测直线,但对于接近竖直方向的直线,计算量会增大。
2. RANSAC算法:这是一种鲁棒性较强的参数估计算法,通过随机选择样
本点,拟合模型并计算误差,再根据误差进行模型更新和样本点选择,最终得到符合数据分布的模型参数。
在直线检测中,RANSAC算法可以通过随
机选择两个点,拟合直线模型并计算样本点到直线的距离来检测直线。
3. 边缘检测算法:这是一种常用的图像处理技术,通过寻找图像中灰度值变化较大的像素点,找到图像中的边缘。
由于直线是一种明显的边缘,因此可以通过边缘检测算法来检测直线。
常用的边缘检测算法包括Canny算法、Sobel算法和Laplacian算法等。
这些算法各有特点,可以根据具体的应用场景和需求选择合适的算法。
