0

The below piece of code uses openCV module to identify lanes on road. I use the python 3.6 for coding (I use atom IDE for development. This info is being provided because stackoverflow isn't letting me post the info without unnecessary lines of info. so please ignore the comments in bracket) The code runs fine with a given sample video. But when I run it for another video it throws the following error:

(base) D:\Self-Driving course\finding-lanes>RayanFindingLanes.py
C:\Users\Tarun\Anaconda3\lib\site-packages\numpy\lib\function_base.py:392: RuntimeWarning: Mean of empty slice.
  avg = a.mean(axis)
C:\Users\Tarun\Anaconda3\lib\site-packages\numpy\core\_methods.py:85: RuntimeWarning: invalid value encountered in double_scalars
  ret = ret.dtype.type(ret / rcount)
Traceback (most recent call last):
  File "D:\Self-Driving course\finding-lanes\RayanFindinglanes.py", line 81, in <module>
    averaged_lines = average_slope_intercept(frame, lines)
  File "D:\Self-Driving course\finding-lanes\RayanFindinglanes.py", line 51, in average_slope_intercept
    right_line = make_points(image, right_fit_average)
  File "D:\Self-Driving course\finding-lanes\RayanFindinglanes.py", line 56, in make_points
    slope, intercept = line
TypeError: cannot unpack non-iterable numpy.float64 object

What does the error mean and how to solve it?

code:

import cv2
import numpy as np

def canny(img):
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    kernel = 5
    blur = cv2.GaussianBlur(gray,(kernel, kernel),0)
    canny = cv2.Canny(blur, 50, 150)
    return canny

def region_of_interest(canny):
    height = canny.shape[0]
    width = canny.shape[1]
    mask = np.zeros_like(canny)

    triangle = np.array([[
    (200, height),
    (550, 250),
    (1100, height),]], np.int32)

    cv2.fillPoly(mask, triangle, 255)
    masked_image = cv2.bitwise_and(canny, mask)
    return masked_image

def display_lines(img,lines):
    line_image = np.zeros_like(img)
    if lines is not None:
        for line in lines:
            for x1, y1, x2, y2 in line:
                cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),10)
    return line_image

def average_slope_intercept(image, lines):
    left_fit    = []
    right_fit   = []
    if lines is None:
        return None
    for line in lines:
        for x1, y1, x2, y2 in line:
            fit = np.polyfit((x1,x2), (y1,y2), 1)
            slope = fit[0]
            intercept = fit[1]
            if slope < 0: # y is reversed in image
                left_fit.append((slope, intercept))
            else:
                right_fit.append((slope, intercept))
    # add more weight to longer lines
    left_fit_average  = np.average(left_fit, axis=0)
    right_fit_average = np.average(right_fit, axis=0)
    left_line  = make_points(image, left_fit_average)
    right_line = make_points(image, right_fit_average)
    averaged_lines = [left_line, right_line]
    return averaged_lines

def make_points(image, line):
    slope, intercept = line
    y1 = int(image.shape[0])# bottom of the image
    y2 = int(y1*3/5)         # slightly lower than the middle
    x1 = int((y1 - intercept)/slope)
    x2 = int((y2 - intercept)/slope)
    return [[x1, y1, x2, y2]]

cap = cv2.VideoCapture("test3.mp4")
while(cap.isOpened()):
    _, frame = cap.read()
    canny_image = canny(frame)
    cropped_canny = region_of_interest(canny_image)
    lines = cv2.HoughLinesP(cropped_canny, 2, np.pi/180, 100, np.array([]), minLineLength=40,maxLineGap=5)
    averaged_lines = average_slope_intercept(frame, lines)
    line_image = display_lines(frame, averaged_lines)
    combo_image = cv2.addWeighted(frame, 0.8, line_image, 1, 1)
    cv2.imshow("result", combo_image)
    if cv2.waitKey(1) == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
3
  • seems like in slope, intercept = line line is a scalar (the return value of np.average() to be precise), so you cannot unpack it to two variables slope and intercept Commented Dec 16, 2019 at 13:53
  • to debug this, make sure a valid slope/intercept tuple is passed to make_points() Commented Dec 16, 2019 at 14:07
  • @MrFuppes. that doesn't seem to be the issue, the code runs for a sample video but not for a new video input. line is not scalar it is an array that has 2 dimensional inputs. I suspect the issue is because of sthg related to video. Commented Dec 16, 2019 at 17:59

2 Answers 2

1

In some of the frames all the slope are > 0 hence left_fit list is empty. Because of that you are getting error when you are calculating left_fit average. One of the way to solve this problem to use left_fit average from previous frame. I have solved it using the same approach. Please see the code below and let me know if it has solved your issue.

global_left_fit_average = []
global_right_fit_average = []
def average_slope_intercept(image, lines):
    left_fit = []
    right_fit = []
    global global_left_fit_average
    global global_right_fit_average

    if lines is not None:
        for line in lines:
            x1, y1, x2, y2 = line.reshape(4)
            parameters = np.polyfit((x1, x2), (y1,y2), 1)
            slope = parameters[0]
            intercept = parameters[1]
            if (slope < 0):
                left_fit.append((slope, intercept))
            else:
                right_fit.append((slope, intercept))
    if (len(left_fit) == 0):
        left_fit_average = global_left_fit_average
    else:
        left_fit_average = np.average(left_fit, axis=0)
        global_left_fit_average = left_fit_average

    right_fit_average = np.average(right_fit, axis=0)
    global_right_fit_average = right_fit_average
    left_line = make_corordinates(image, left_fit_average)
    right_line = make_corordinates(image, right_fit_average)
    return np.array([left_line, right_line])
Sign up to request clarification or add additional context in comments.

Comments

0

HoughLinesP returns a list and that can be an empty list and not necessarily None

So the lines in the function average_slope_intercept

if lines is None:
        return None

is not much of use.

You need to check len(lines) == 0

2 Comments

maybe better use if not lines instead of len(lines) == 0
both the syntaxes if line is None: and len(lines) work fine, there is no issue with it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.