如何在Python的OpenCV中绘制霍夫空间?
我正在用Python做OpenCV的项目。
我在一张图片上使用了霍夫变换,成功找到了几条线。
现在我想看看霍夫空间里的结果,这样可以更好地理解这些线得到了多少投票,以及它们的位置。有没有人能帮我解决这个问题?
3 个回答
0
OpenCV的API并不具备这个功能。OpenCV的霍夫变换函数都不会把图像返回给调用者。
http://docs.opencv.org/modules/imgproc/doc/feature_detection.html#houghlines
如果你想为一条线设置一个最小的投票阈值,可以在调用霍夫变换方法时设置threshold
参数。
如果你想为了学习的目的可视化霍夫线投票空间的图像,你需要使用MATLAB的radon命令。或者你也可以自己实现一个。
1
其实,在ximgproc模块里有一个功能。你需要重新编译OpenCV,并且加上这个附加模块,具体可以查看这个链接:https://github.com/opencv/opencv_contrib
然后你就可以使用的功能是 cv::ximgproc::FastHoughTransform
,详细信息可以参考这个链接:https://docs.opencv.org/3.4.1/d9/d29/namespacecv_1_1ximgproc.html#a401697bbdcf6c4a4c7d385beda75e849
3
我在Github上找到一个可以计算的项目,然后我把它改成只显示霍夫空间。
Github链接: https://github.com/alyssaq/hough_transform
下面是我改过的代码:
import numpy as np
import imageio
import math
import matplotlib.pyplot as plt
def rgb2gray(rgb):
return np.dot(rgb[..., :3], [0.299, 0.587, 0.114]).astype(np.uint8)
def hough_line(img, angle_step=1, lines_are_white=True, value_threshold=5):
"""
Hough transform for lines
Input:
img - 2D binary image with nonzeros representing edges
angle_step - Spacing between angles to use every n-th angle
between -90 and 90 degrees. Default step is 1.
lines_are_white - boolean indicating whether lines to be detected are white
value_threshold - Pixel values above or below the value_threshold are edges
Returns:
accumulator - 2D array of the hough transform accumulator
theta - array of angles used in computation, in radians.
rhos - array of rho values. Max size is 2 times the diagonal
distance of the input image.
"""
# Rho and Theta ranges
thetas = np.deg2rad(np.arange(-90.0, 90.0, angle_step))
width, height = img.shape
diag_len = int(round(math.sqrt(width * width + height * height)))
rhos = np.linspace(-diag_len, diag_len, diag_len * 2)
# 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.uint8)
# (row, col) indexes to edges
are_edges = img > value_threshold if lines_are_white else img < value_threshold
y_idxs, x_idxs = np.nonzero(are_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 = diag_len + int(round(x * cos_t[t_idx] + y * sin_t[t_idx]))
accumulator[rho, t_idx] += 1
return accumulator, thetas, rhos
def show_hough_line(img, accumulator, thetas, rhos, save_path=None):
plt.imshow(accumulator, aspect='auto', cmap='jet', extent=[np.rad2deg(thetas[-1]), np.rad2deg(thetas[0]), rhos[-1], rhos[0]])
if save_path is not None:
plt.savefig(save_path, bbox_inches='tight')
plt.show()
if __name__ == '__main__':
imgpath = 'path_img.tif'
img = imageio.imread(imgpath)
if img.ndim == 3:
img = rgb2gray(img)
accumulator, thetas, rhos = hough_line(img)
show_hough_line(img,
accumulator,
thetas, rhos,
save_path='output.png')
我得到了正确的结果:
这是对应的图片: