سلام
من رسیدم به پارت 17 آموزش، جایی که برای اولین بار فریم به فریم خطوط رو روی ویدئو تشخیص دادیم.
اما کاری که من کردم وسط ویدئو که خط نارنجی ممتد تموم میشه و میرسه به خطوط نارنجی غیرممتد برنامه کرش میکنه! و ارور زیر رو میده و من دو سه بار کدم رو چک کردم و تفاوتی با کد شما پیدا نکردم:
E:\Anaconda3\lib\site-packages\numpy\lib\function_base.py:393: RuntimeWarning: Mean of empty slice.
avg = a.mean(axis)
E:\Anaconda3\lib\site-packages\numpy\core\_methods.py:161: RuntimeWarning: invalid value encountered in double_scalars
ret = ret.dtype.type(ret / rcount)
Traceback (most recent call last):
File "lanes.py", line 104, in <module>
averaged_lines = average_slope_intercept(frame, lines)
File "lanes.py", line 60, in average_slope_intercept
left_line = make_coordinates(image, left_fit_average)
File "lanes.py", line 68, in make_coordinates
slope, intercept = line_parameters
TypeError: cannot unpack non-iterable numpy.float64 object
سلام دوست عزیز
اگه لطف کنید و کد را اینجا قرار بدید بهتر میتونم مشکل را پیدا کنم، اما مشکل احتمالی:
رعایت نکردن Indent یا فاصله دقیق در تابع average_slope_intercept.
اگه باز هم درست نشد لطفا کدتون رو اینجا برای من قرار بدید تا بررسی کنم.
کد بنده:
def region_of_interest(image):
height = image.shape[0]
polygons = np.array([[(200, height), (1100, height), (550, 250)]])
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 = []
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)
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)
x2 = int((y2 - intercept) / slope)
return np.array([x1, y1, x2, y2])
cap = cv2.VideoCapture('test.mp4')
while cap.isOpened():
_, frame = cap.read()
canny_image = canny(frame)
cropped_image = region_of_interest(canny_image)
lines = cv2.HoughLinesP(cropped_image, 2, np.pi / 180, 100, np.array([]), 40, 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)
cv2.waitKey(1)
سلام مجدد
به نظر میرسه یکی از مشکلات کد شما این باشه که تابع make_coordinates رو بعد از تابع average_slope_intercept تعریف کردید . در حالی که از این تابع در تابع average_slope_intercept استفاده شده و قاعدتا باید قبل از این تابع تعریف بشه و بعد فراخوانی بشه.
از طرفی بهتره یه شرط None هم در تابع average_slope_intercept تعریف بشه.
در زیر کد جهت بررسی هر چه بیشتر عدم تطابق ها آورده شده است:
import numpy as np
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]]
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 canny(img):
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
kernel = 5
blur = cv2.GaussianBlur(gray,(kernel, kernel),0)
canny = cv2.Canny(gray, 50, 150)
return canny
def display_lines(img,lines):
line_image = np.zeros_like(image)
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 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
image = cv2.imread('test_image.jpg')
lane_image = np.copy(image)
lane_canny = canny(lane_image)
cropped_canny = region_of_interest(lane_canny)
lines = cv2.HoughLinesP(cropped_canny, 2, np.pi/180, 100, np.array([]), minLineLength=40,maxLineGap=5)
averaged_lines = average_slope_intercept(image, lines)
line_image = display_lines(lane_image, averaged_lines)
combo_image = cv2.addWeighted(lane_image, 0.8, line_image, 1, 0)
cap = cv2.VideoCapture("test2.mp4")
while(cap.isOpened()):
ret, frame = cap.read()
lane_canny = canny(frame)
cropped_canny = region_of_interest(lane_canny)
lines = cv2.HoughLinesP(cropped_canny, 2, np.pi/180, 100, np.array([]), minLineLength=40,maxLineGap=5)
averaged_lines = average_slope_intercept(image, lines)
line_image = display_lines(lane_image, averaged_lines)
combo_image = cv2.addWeighted(lane_image, 0.8, line_image, 1, 0)
cv2.imshow("image", combo_image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
کاملا تطابق دادم اما مشکل همچنان وجود داره!!
لطفا آخرین ورژن کد خود را قرار بدید
کد قبلی تفاوت های زیادی با کد درس داشت و به نظر کامل نمیومد
سلام
من هم همین مشکل رو داشتم. یعنی به محض اینکه به خط وسط غیر ممتد میرسید برنامه کرش میکرد. بعد اینطوری حلش کردم
۱- توی فانکشن canny بلور رو حذف کردم
۲- توی حلقه اصلی پارامترهای متد HoughLinesP رو به اینصورت تغییر بدین که پارامتر چهارم رو که برای ترشهولد یا سایز بین هست رو به ۵۰ تغییر بده و پارامتر maxLineGap رو که بیشترین فاصله بین دو پیکسل هست که بتونه یک خط رو تشکیل بده رو روی ۸۰ تنظیم کن.
مشکل من با این تغییرات تو کد اصلی رفع شد.