图2
答案:C
理由:
1、空间坐标系的直线转换到霍夫空间是点,因为直线的参数确定,确定的参数在霍夫空间里面就是点;m相同,b不同
2、b= -xm+y,两个及以上的(x,y)可以确定一个(m,b),所以笛卡尔坐标系里面的2条直线可以对应到霍夫空间里面的2个点。
题2:
下图中,图像空间中的点对应于霍夫空间中的什么?
图4
答案:A
解释:
1、空间坐标系的点转换到霍夫空间是直线,因为经过这个点有无穷个直线,每个直线对应的(m,b)不同,都经过同一个点。
2、b= -x0m+y0,是一条确定的直线。
题3:
下图中,图像空间中两点在霍夫空间中的表示是什么?
图5
答案:C
解释:
1、图像空间中,任意2点都能经过一条直线,所以霍夫空间里面2条直线必有一个交点,即为共线的直线的参数;
2、b= -x1m+y1,b= -x2m+y2, 0> -x1 > -x2, y1 < y2
题4:
下图中,霍夫空间中两条线的交点在图像空间中对应什么?
图6
答案:A
解释:
1、霍夫空间中,两条直线代表图像空间的两个点,两条直线都经过(m0,b0),说明图像空间的两个点在参数为(m0,b0)的直线上;
2、m0 > 0,b0 > 0,说明斜率为正、截距为正。
图7
由于垂直线的斜率是无限大的,不利于计算,因此我们需要一个新的参数表达——通过极坐标重新定义直线,如图8所示。
ρ表示直线到原点的垂直距离,θ表示直线的垂线与横轴的夹角。
可以得到 x0=ρ0*cosθ0 y0=ρ0*sinθ0 → x0*cosθ0 + y0*sinθ0 = ρ0
图8
因为 x0*cosθ + y0*sinθ = ρ
现在图像空间中的每个点对应于霍夫空间中的一条正弦曲线。
假设x0和y0是(1,1)的情况下,x0*cosθ + y0*sinθ = ρ 如下图所示,可以看出是三角函数。
如果我们取一整条点,它会转化为霍夫空间中的一大堆正弦曲线。类比直线的情况,这些正弦曲线在霍夫空间中的交点,为图像空间直线的参数。
图9
题5:
如果我们在正方形图像上运行霍夫变换会发生什么? 霍夫空间中的对应图会是什么样子?
图10
答案:C
解释:
1、图像空间有4条直线,说明霍夫空间有4个交点;
2、4个点(θ,ρ)为(0,ρ1)、(0,ρ2)、(π/2,ρ1)、(π/2,ρ2),可以看出,四个点。
x0*cosθ0 + y0*sinθ0 = ρ0 → y = ρ0 - (cosθ0/ sinθ0) * x
2、 霍夫变换在车道线检测中的应用
车道线检测涉及更详细的车道线属性,例如长线、短线、弯曲线、虚线等。
在使用Canny function提取边缘的图像中,使用OpenCV的函数HoughLinesP( )。(相关资料可以参考OpenCV_Hough Line Transform和不用OpenCV求解Hough Transform的方法。)
HoughLinesP如下:
lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]), min_line_length, max_line_gap)
-- 附录--
1、进一步理解霍夫变换
笛卡尔坐标系下的直线如下所示。
在笛卡尔图像空间中共线的点将在m-b(gradient-intercept)参数空间中相交。若图像空间所有点都在同一条直线上,表示相交在参数空间中的同一个点处。 参数空间中的公共点 (m, b) 表示图像空间中的线。如下图所示,图像空间中某一点(x1,y1)处可能存在的所有的直线(蓝色)的(m,b),对应到参数空间中蓝色直线 b= -mx1+y1 中的(m,b)的值。
gradient-intercept参数空间中的斜率会无限大,所以转换到angle-distance参数空间——极坐标系。将笛卡尔坐标系中的 <span id="MathJax-Span-250" class="mrow"><span id="MathJax-Span-251" class="mi">y<span id="MathJax-Span-252" class="mo">=<span id="MathJax-Span-253" class="mi">m<span id="MathJax-Span-254" class="mi">x<span id="MathJax-Span-255" class="mo">+<span id="MathJax-Span-256" class="mi">b 的(m,b)参数,转为极坐标系的参数 <span id="MathJax-Span-265" class="mrow"><span id="MathJax-Span-266" class="mo">(<span id="MathJax-Span-267" class="mi">ρ<span id="MathJax-Span-268" class="mo">,<span id="MathJax-Span-269" class="mi">θ<span id="MathJax-Span-270" class="mo">),如下所示
ρ = x cos θ + y sin θ
算法步骤:
(1)边缘检测的图像(0/1二值图)作为输入;
(2)ρ和θ的范围设置,ρ最大为图片对角线长度;
(3)θ 与 ρ 的霍夫累加器Hough accumulator, 它是一个二维数组,行数等于 ρ 值的数量,列数等于 θ 值的数量;
(4)在累加器中投票, 对于每个边缘点和每个 θ 值,找到最接近的 ρ 值并在累加器中增加该索引,每个元素都告诉有多少点/像素为具有参数 (ρ,θ) 的潜在候选线贡献了“投票”。
(5)找峰值。 累加器中的局部最大值表示输入图像中最突出的线条的参数。 通过应用阈值或相对阈值(等于或大于全局最大值的某个固定百分比的值),可以最容易地找到峰值。
Python下的霍夫算法
import numpy as np def hough_line(img): # Rho and Theta ranges thetas = np.deg2rad(np.arange(-90.0, 90.0)) width, height = img.shape diag_len = np.ceil(np.sqrt(width * width + height * height)) # max_dist rhos = np.linspace(-diag_len, diag_len, diag_len * 2.0) # Cache some resuable values cos_t = np.cos(thetas) sin_t = np.sin(thetas) num_thetas = len(thetas) # Hough accumulator array of theta vs rho accumulator = np.zeros((2 * diag_len, num_thetas), dtype=np.uint64) y_idxs, x_idxs = np.nonzero(img) # (row, col) indexes to edges # Vote in the hough accumulator for i in range(len(x_idxs)): x = x_idxs[i] y = y_idxs[i] for t_idx in range(num_thetas): # Calculate rho. diag_len is added for a positive index rho = round(x * cos_t[t_idx] + y * sin_t[t_idx]) + diag_len accumulator[rho, t_idx] += 1 return accumulator, thetas, rhos
算法调用
# Create binary image and call hough_line image = np.zeros((50,50)) image[10:40, 10:40] = np.eye(30) accumulator, thetas, rhos = hough_line(image) # Easiest peak finding based on max votes idx = np.argmax(accumulator) rho = rhos[idx / accumulator.shape[1]] theta = thetas[idx % accumulator.shape[1]] print "rho={0:.2f}, theta={1:.0f}".format(rho, np.rad2deg(theta))
结果
rho=0.50, theta=-45