15

Can a sample implementation code or a pointer be provided for implementing LSD with opencv 3.0 and python? HoughLines and HoughLinesP are not giving desired results in python and want to test LSD in python but am not getting anywhere.

I have tried to do the following:

LSD=cv2.createLineSegmentDetector(0) lines_std=LSD.detect(mixChl) LSD.drawSegments(mask,lines_std)

However when I draw lines on the mask I get an error which is: LSD.drawSegments(mask,lines_std) TypeError: lines is not a numerical tuple

Can someone please help me with this? Thanks in advance.

user1996684
  • 265
  • 1
  • 3
  • 8

4 Answers4

19

You can use cv2.drawSegments function like this:

#Read gray image
img = cv2.imread("test.png",0)

#Create default parametrization LSD
lsd = cv2.createLineSegmentDetector(0)

#Detect lines in the image
lines = lsd.detect(img)[0] #Position 0 of the returned tuple are the detected lines

#Draw detected lines in the image
drawn_img = lsd.drawSegments(img,lines)

#Show image
cv2.imshow("LSD",drawn_img )
cv2.waitKey(0)

You can check OpenCV documentation.

flaviussn
  • 1,305
  • 2
  • 15
  • 33
  • By any chance, do you know the contents of `lsd.detect(img)[1]`? Are they the descriptors? – eshirima Jun 13 '17 at 16:16
  • So if I want to send the width of the detected lines to the function it doesn't returned the lines which its width is equal or greater but it returned all the lines ? lines = lsd.detect(warped, 10, 10) so do you know how to detect only the lines that their width is greater than specific width ? – sara Jan 28 '18 at 16:37
  • You can apply a filter to delete all the lines lower than 10px – flaviussn Jan 29 '18 at 15:08
  • 1
    What does `0` in `cv2.createLineSegmentDetector(0)` mean? Thanks. – mrtpk May 10 '19 at 06:38
  • 0 is the line detector mode for no refinement. The enum is defined here: https://docs.opencv.org/4.x/dd/d1a/group__imgproc__feature.html#gad092a7362b8afb8a905238a41898d98c – erikreed Feb 05 '22 at 18:56
6

I was able to draw the lines in OpenCV 3.2.0 with the following:

lsd = cv2.createLineSegmentDetector(0)
dlines = lsd.detect(gray_image)
  for dline in dlines[0]:
    x0 = int(round(dline[0][0]))
    y0 = int(round(dline[0][1]))
    x1 = int(round(dline[0][2]))
    y1 = int(round(dline[0][3]))
    cv2.line(mask, (x0, y0), (x1,y1), 255, 1, cv2.LINE_AA)

I am not sure why all of the extra [0] indirection, but that seems to be what it takes to extract the coordinates.

When unpacking OpenCV returns, I have found it helpful to just print the thing on the console. In this case, I did

print(dlines)

From all of the nested square brackets, I can often work out a solution without having to worry too much about the why and wherefore of it all.

I had previously used a Windows DLL version of LSD that I compiled from the authors' source and called with ctypes.

3

old implementation is not available. Now it is available as follows:

fld = cv2.ximgproc.createFastLineDetector() lines = fld.detect(image)

Hacklavya
  • 1,275
  • 8
  • 8
1

The accepted answer works just fine if all you're after is drawing the lines. However, if you want a finer grain control over the lines and their drawing, you can loop over the lines and deal with them individually as suggested. Just a cleaner version would be:

mask = np.zeros((img.shape),np.uint8)
lsd = cv2.createLineSegmentDetector(0)
lines = lsd.detect(img)[0]
for l in lines:
    x0, y0, x1, y1 = l.flatten()
    //do whatever and plot using:
    cv2.line(mask, (x0, y0), (x1,y1), 255, 1, cv2.LINE_AA)