pythonopencvimage-processinghough-transformstraight-line-detection

I have an issue while drawing the lines over an image using pair of coordinates using opencv python


I have a set of coordinates from an image. Using those coordinates I wanted to plot the lines over an image. While trying I ended up with an error. Please help me with this issue. Below is the code.

[((line[0, 0], line[0, 1]), (line[1, 0], line[1, 1])) for line in lines[:nlines]]

print(lines[:lines])

for i in lines:
    x1,y1,x2,y2=i[0]
    cv2.line(image,(x1,y1),(x2,y2),(255,0,0),2)

cv2.imshow("Image",image)
cv2.waitKey(0)

Error:

x1,y1,x2,y2=line[0]

ValueError: not enough values to unpack (expected 4, got 2)

Points Output:

[[[1150  327]
  [1166  316]]

 [[1146  475]
  [1158  467]]

 [[ 903  322]
  [ 911  320]]

 ...

 [[ 364  403]
  [ 374  402]]

 [[ 644  570]
  [ 649  569]]

 [[ 249  645]
  [ 255  644]]]

Solution

  • The issue is that each line is defined by two points.

    From your printing, you can see the data arrangement.

    Example:

    a = [[[1150  327]
          [1166  316]]
    
         [[1146  475]
          [1158  467]]]
    

    The data arrangement above is: two arrays, containing two arrays containing two numerical values.
    The hierarchy is an array built of arrays of arrays (or list built of list of lists).
    Very confusing structure...

    As you can see there is an hierarchy of two "groups":

    Separating into sub-groups:

    Getting the numeric value: a[0][0][0] equals 1150.


    x1, y1, x2, y2=line[0] gives you an error because line[0] is built from two arrays/lists:
    You are trying to get 4 values, white there are only 2, so you are getting an error.

    Example:
    line[0] equals [[1150 327] [1166 316]]

    You can think about is as two points p0 and p1, and use the syntax:

    p0, p1 = line[0]
    

    Python allows a "weird" syntax - getting the values in two tuples:

    (x1, y1), (x2, y2) = line[0]
    

    Here is a sample code sample that iterates an NumPy array of lines, and draw the lines:

    import cv2
    import numpy as np
    
    # Array of lines:
    lines = np.array([[[1150, 327], [1166, 316]],
                      [[1146, 475], [1158, 467]],
                      [[ 903, 322], [ 911, 320]],                 
                      [[ 364, 403], [ 374, 402]],
                      [[ 644, 570], [ 649, 569]],
                      [[ 249, 645], [ 255, 644]]])
    
    # Create black image (resolution 1200x1000)
    image = np.zeros((1200, 1000, 3), np.uint8)
    
    # Iterate lines:
    for line in lines:
        (x1, y1), (x2, y2) = line
        cv2.line(image, (x1,y1), (x2,y2), (255,0,0), 2)
    
    cv2.imshow("Image", image)
    cv2.waitKey(0)
    

    Note:
    I took the "Points Output" from your post, and built a NumPy array.
    It could be that in your case you have to iterate lines[0] (it hard to tell from your post).