I am getting this error and cant understand why the issue is appearing. Below will be the code and error.
The result of the last printable workout
[-8.54582258e-01 9.83741381e+02] left
[ 0.776281243 -160.77584028] right
The code error happens in make_coordinates
and the line is
slope, intercept = line_parameters
Here's the full code:
import cv2
import numpy as np
vid = cv2.VideoCapture('carDriving.mp4')
def processImage(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5,5), 0)
canny = cv2.Canny(blur, 50, 150)
return canny
def region_of_interest(image):
height = image.shape[0]
polygons = np.array([
[(200,height), (1200,height), (750,300)]
])
mask = np.zeros_like(image)
cv2.fillPoly(mask, polygons, 255)
masked_image = cv2.bitwise_and(image, mask)
return masked_image
def display_lines(image, lines):
line_image = np.zeros_like(image)
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line.reshape(4)
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 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))
left_fit_average = np.average(left_fit, axis=0)
right_fit_average = np.average(right_fit, axis=0)
print(left_fit_average, 'left')
print(right_fit_average, 'right')
left_line = make_coordinates(image, left_fit_average)
right_line = make_coordinates(image, right_fit_average)
#return np.array([left_line, right_line])
def make_coordinates(image, line_parameters):
slope, intercept = line_parameters
y1 = image.shape[0]
y2 = int(y1*3/5)
x1 = int(y1 - intercept)/slope
x1 = int(y2 - intercept)/slope
return np.array([x1, y1, x2, y2])
while True:
ret, frame = vid.read()
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
processed_image = processImage(frame)
cropped_image = region_of_interest(processed_image)
lines = cv2.HoughLinesP(cropped_image, 2, np.pi/180, 100, np.array([]), minLineLength=40, maxLineGap=5)
averaged_lines = average_slope_intercept(grayFrame, lines)
line_image = display_lines(cropped_image,lines)
combo_image = cv2.addWeighted(grayFrame, .6, line_image, 1, 1)
cv2.imshow('result', combo_image)
print(lines)
if cv2.waitKey(30) & 0xFF == ord('q'):
break
vid.release()
cv2.destroyAllWindows()
and the complete error message:
Message=cannot unpack non-iterable numpy.float64 object
Source=C:\Users\Andre\source\repos\SelfDrivingCarTest\SelfDrivingCarTest\SelfDrivingCarTest.py
StackTrace:
File "C:\Users\Andre\source\repos\SelfDrivingCarTest\SelfDrivingCarTest\SelfDrivingCarTest.py", line 52, in make_coordinates
slope, intercept = line_parameters
File "C:\Users\Andre\source\repos\SelfDrivingCarTest\SelfDrivingCarTest\SelfDrivingCarTest.py", line 47, in average_slope_intercept
left_line = make_coordinates(image, left_fit_average)
File "C:\Users\Andre\source\repos\SelfDrivingCarTest\SelfDrivingCarTest\SelfDrivingCarTest.py", line 65, in <module>
averaged_lines = average_slope_intercept(grayFrame, lines)
Now receiving another error, line 27, first error was fixed
Message=integer argument expected, got float
Source=C:\Users\Andre\source\repos\SelfDrivingCarTest\SelfDrivingCarTest\SelfDrivingCarTest.py
StackTrace:
File "C:\Users\Andre\source\repos\SelfDrivingCarTest\SelfDrivingCarTest\SelfDrivingCarTest.py", line 27, in display_lines
cv2.line(line_image, (x1, y1), (x2, y2), (255,0,0), 10)
File "C:\Users\Andre\source\repos\SelfDrivingCarTest\SelfDrivingCarTest\SelfDrivingCarTest.py", line 76, in <module>
line_image = display_lines(cropped_image,averaged_lines)
I change line 27 to cv2.line(line_image, int(x1, y1), int(x2, y2), (255,0,0), 10)
and get the following error
Message='numpy.float64' object cannot be interpreted as an integer
Source=C:\Users\Andre\source\repos\SelfDrivingCarTest\SelfDrivingCarTest\SelfDrivingCarTest.py
StackTrace:
File "C:\Users\Andre\source\repos\SelfDrivingCarTest\SelfDrivingCarTest\SelfDrivingCarTest.py", line 27, in display_lines
cv2.line(line_image, int(x1, y1), int(x2, y2), (255,0,0), 10)
File "C:\Users\Andre\source\repos\SelfDrivingCarTest\SelfDrivingCarTest\SelfDrivingCarTest.py", line 76, in <module>
line_image = display_lines(cropped_image,averaged_lines)
There's a case in your code where line_parameters
can be a single value, np.nan
, instead of a pair of (slope, intercept)
values. If the slope of your fits is always > 0
, then left_fit
will end up being an empty list []
:
if slope < 0:
left_fit.append((slope, intercept))
else:
right_fit.append((slope, intercept))
The output of np.average
run on an empty list is NaN:
np.average([])
# output: np.nan
# also raises two warnings: "RuntimeWarning: Mean of empty slice." and
# "RuntimeWarning: invalid value encountered in double_scalars"
Thus, in some cases left_fit_average = np.average(left_fit) == np.average([]) == np.nan
. np.nan
has a type of numpy.float64
. Your code then calls:
left_line = make_coordinates(image, line_parameters=left_fit_average)
Thus, when the call to make_coordinates
gets to the line:
slope, intercept = line_parameters
it's possible for line_parameters
to be np.nan
, in which case you get the error message about:
TypeError: 'numpy.float64' object is not iterable
You can fix the bug by making sure that sensible values get assigned to slope
and intercept
even if line_parameters=np.nan
. You can accomplished this by wrapping the assignment line in a try... except
clause:
try:
slope, intercept = line_parameters
except TypeError:
slope, intercept = 0,0
You'll have to decide if this behavior is correct for your needs.
Alternatively, you could prevent the average_slope_intercept
function from calling make_coordinates
in the first place when one of the x_fit
values doesn't have anything interesting in it:
if left_fit:
left_fit_average = np.average(left_fit, axis=0)
print(left_fit_average, 'left')
left_line = make_coordinates(image, left_fit_average)
if right_fit:
right_fit_average = np.average(right_fit, axis=0)
print(right_fit_average, 'right')
right_line = make_coordinates(image, right_fit_average)
As per @tel answer, I like to add some,
try:
slope, intercept = line_parameters
except TypeError:
slope, intercept = 0.001, 0 // It will minimize the error detecting the lane (putting 0, give you a math error)
Again, you can increase the value of maxLineGap to catch the lane when there is so much distance between lanes
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With