How to draw a line captured by the Hough Transform?

Hi, I’m trying to learn the hough transform and for that, I’d like to build some functions which perform that transformation. Here they are:

def hough_peaks(H, num_peaks):
    H_values_sorted = np.sort(np.unique(H))
    H_values_num_peaks = H_values_sorted[-num_peaks:]
    
    peak_indexes = []
    
    for pi in H_values_num_peaks:
        indexes = np.argwhere(H == pi)
        for find_indexes in indexes: 
            peak_indexes.append(list(find_indexes))
        
    return np.array(peak_indexes[0:num_peaks])

def hough_lines_draw(image, peaks):
    x = np.arange(0, image.shape[0])
    H = np.zeros(image.shape)
    
    for i in range(peaks.shape[0]):
        d = peaks[i, 0]
        theta = peaks[i, 1]
        
        y = ((d - x*np.cos(theta))/np.sin(theta)).astype(int) 
        H[x, y] = 1
        
    return H

#It is possible to change the resolution of the Theta axis
#The resolution of the rho axis is 1
def hough_lines_acc(edge_image, Theta=np.arange(0, 181)):
    num_rhos = int((np.sqrt(2)/2)*(edge_image.shape[0] + edge_image.shape[1]))
    H = np.zeros((num_rhos, len(Theta)))
    
    for i in range(edge_image.shape[0]):
        for j in range(edge_image.shape[1]):
            if edge_image[i, j] == 1:
                d = (i*np.cos(np.deg2rad(Theta))+j*np.sin(np.deg2rad(Theta))+0.5).astype(int) #Approximation nearest integer
                H[d, Theta] += 1
                
    return H, np.arange(0, num_rhos), Theta

Basically, the three functions performs the steps necessary during the Hough Transform - Creating the accumulator, selecting the peaks and drawing the lines. For me the accumulator and the peak selector are corrects, but when I try to draw the lines, the y vector generates some values that are bigger than the image size (256x256). So, how could this happen?
Here is how I’m calling the functions:

H, rhos, thetas = hough_lines_acc(edge_img_float)
peaks = hough_peaks(H, 7)
plt.imshow(H)
plt.plot(peaks[:, 1], peaks[:,0], ‘ro’)
plt.show()
lines_images = hough_lines_draw(edge_img_float, peaks)
print(lines_images)

I’d appreciate any help. Thanks.

Hi,
you don’t have any restriction for y so it can take pretty much any value (depending on theta, d of course). Imagine for example an almost vertical line: For a small change in x the y value can become huge.
For practical drawing purposes you can simply restrict drawing to the points (x,y) for which both x and y are within the image range.
There is by the way also a convenient drawing function in scikit-image: skimage.draw.line

2 Likes