TypeError: cannot unpack non-iterable numpy.float64 object

蹲街弑〆低调 提交于 2021-02-11 14:40:46

问题


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()

回答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])



回答2:


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



来源:https://stackoverflow.com/questions/59357940/typeerror-cannot-unpack-non-iterable-numpy-float64-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!