import numpy as np
from PIL import ImageGrab
import cv2
import time
import pyautogui
import matplotlib.pyplot as plt
def make_coords(img,line_param):
slope,intercept=line_param
y1 = img.shape[0]
y2 = int((y1*(3/5)))
x1 = int((y1-intercept)/slope)
x2 = int((y2-intercept)/slope)
try:
return np.array((x1,y1,x2,y2)) #HERE IS WHERE THE PROBLEM HAPPENS
except UnboundLocalError:
pass
def avg_slope(img,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)
try:
slope = parameters[0]
except TypeError:
slope = 0
try:
intercept = parameters[1]
except TypeError:
intercept = 0
if slope <0:
left_fit.append((slope,intercept))
else:
right_fit.append((slope,intercept))
if left_fit:
left_fit_avg=np.average(left_fit,axis=0)
left_line=make_coords(img,left_fit_avg)
if right_fit:
right_fit_avg=np.average(right_fit,axis=0)
right_line=make_coords(img,right_fit_avg)
return np.array((x1,y1,x2,y2))
def draw_lines(img, lines):
try:
for line in lines:
if line is not None:
coords = line[0]
cv2.line(img, (coords[0],coords[1]), (coords[2],coords[3]), [255,0,0], 3)
except:
pass
def roi(img):
vertices = np.array([[10,500],[10,300], [300,200], [500,200], [800,300], [800,500]], np.int32)
mask = np.zeros_like(img)
cv2.fillPoly(mask, [vertices], 255)
masked = cv2.bitwise_and(img, mask)
return masked
def process_img(image):
original_image = image
# convert to gray
processed_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# edge detection
processed_img = cv2.GaussianBlur(processed_img,(5,5),0) #new
processed_img = cv2.Canny(processed_img, threshold1 = 50, threshold2=150) #new
# processed_img = cv2.Canny(processed_img, threshold1 = 200, threshold2=300)
lines = cv2.HoughLinesP(processed_img, 1, np.pi/180, 180, np.array([]), minLineLength=15,maxLineGap=5)
avg_lines = avg_slope(processed_img,lines)
draw_lines(process_img,avg_lines)
processed_img = roi(processed_img)
return processed_img
def main():
last_time = time.time()
while True:
screen = np.array(ImageGrab.grab(bbox=(0,40,800,640)))
if screen is not None:
new_screen = process_img(screen)
print('Frame took {} seconds'.format(time.time()-last_time))
cv2.imshow('window', new_screen)
else:
pass
last_time = time.time()
# plt.imshow(new_screen)
#cv2.imshow('window',cv2.cvtColor(screen, cv2.COLOR_BGR2RGB))
# cv2.waitKey(0)
if cv2.waitKey(25) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
main()
终端显示:
avg_lines = avg_slope(processed_img,lines)
Frame took 0.12310576438903809 seconds
Traceback (most recent call last):
File "c:/Users/Nicole/Documents/Python Scripts/matetest.py", line 107, in <module>
main()
File "c:/Users/Nicole/Documents/Python Scripts/matetest.py", line 91, in main 91,
in main
new_screen = process_img(screen) 78, in process_img
File "c:/Users/Nicole/Documents/Python Scripts/matetest.py", line 78, in process_img 50, in avg_slope
avg_lines = avg_slope(processed_img,lines)
File "c:/Users/Nicole/Documents/Python Scripts/matetest.py", line 50, in avg_slope
return np.array((x1,y1,x2,y2))
UnboundLocalError: local variable 'x1' referenced before assignment
...即使我在做...
try:
return np.array((x1,y1,x2,y2))
except UnboundLocalError:
pass
您所说的错误实际上并没有发生。通过查看回溯,您可以看到函数avg_slope
中发生了错误。
可能是因为您使用return np.array((x1,y1,x2,y2))
,而在该函数中仅在if
语句中声明了这些值。如果将跳过if
块(当lines
为None
时),则该函数中未声明x1
,x2
,y1
和y2
。换句话说:可能是这些函数在函数内部永远不存在,因此您不能根据它们返回任何内容。解释器阻止您执行此操作。
通过仔细阅读错误消息,您可以学到很多东西。概括地说,分配前引用的局部变量简而言之。
您的问题在这里:
def avg_slope(img,lines):
left_fit =[]
right_fit=[]
if lines is not None:
for line in lines:
x1,y1,x2,y2=line.reshape(4)
如果lines
为“假”(空或None
,则您永远不会分配给x1
。