2
votes

Is there a way to detect lines which are not perfectly straight?

I have objects which represents rectangles but are slightly uneven because of the use of a wide angle camera distortion and bad quality preprocessing. Also I have to do a perspective transformation beforehand which is another factor for the poor line quality.

After detecting the edges with the canny filter, I get for example the following image: Object with not straight edges hough transform

I tried to find the edge lines with the hough lines algorithm. But because of the bad quality of the shape with a lot of bumpiness it is not possible to find the sloping edges.

I tried the normal hough line transform (red lines) and also with the Probabilistic Hough Line Transform (green lines), but the result is quite bad.

Are there any other options to detect something like that? Or is there a way to improve my image, so I get straight lines? The distortion of the lines is variable, so it is really hard to fix.

Here another example:

example 2 - edges example 2 - hough results

I'm using python 3.4 with opencv 3.2, numpy 1.12. Any input or hint for a possible new way to solve this would be awesome.

1

1 Answers

3
votes

Your edges are pretty clear -- definitely good enough for probabilistic Hough line transforms. I think you just need to play with the free parameters a bit more.

import numpy as np
import matplotlib.pyplot as plt
from skimage.transform import probabilistic_hough_line
from skimage import draw

def restore_lines(distorted):
    lines = probabilistic_hough_line(distorted,
                                     threshold=2,
                                     line_length=20,
                                     line_gap=15)

    restored = np.zeros_like(distorted, dtype=np.uint8)
    for line in lines:
        p0, p1 = line
        rr, cc = draw.line(p0[1], p0[0], p1[1], p1[0])
        restored[rr, cc] += 1
    return restored


# distorted = plt.imread('backslash.png')
distorted = plt.imread('tick.png')

# imread returns non-grayscale image in this case
distorted = distorted[:,:,0]

# restore
restored = restore_lines(distorted)

fig, axes = plt.subplots(1,2)
axes[0].imshow(distorted, cmap='gray', interpolation='none')
axes[1].imshow(restored, cmap='gray', interpolation='none')
axes[0].set_title('Original')
axes[1].set_title('Restored')
for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])

enter image description here

enter image description here