python 上的线程函数中未定义全局变量错误
Error with global variables are not defined in a thread function on python
我正在一个使用网络摄像头的 OCR 项目中工作。我定义了一个 capture()
函数来保存 frame,它在 3 秒内包含至少 20 个面积大于 60 像素的轮廓。我需要 main while 循环一直有效。所以我正在使用一个线程来调用 capture()
函数。当我 运行 代码 Python Shell 返回一个错误:NameError: global name frame, ln2 are not defined。第 13 行注释解决了变量 frame 的错误。这是否意味着我必须复制 while 循环内的所有代码?
我在 Windows 7.
上使用 python 2.7
代码如下:
import cv2
import time
import threading
cap = cv2.VideoCapture(0)
def capture():
global frame, ln2
if ln2 > 20:
cv2.imwrite("frame.jpg", frame)
time.sleep(3)
#ret, frame = cap.read() #it solves the error for variable 'frame'
child_t = threading.Thread(target = capture)
child_t.setDaemon(True)
child_t.start()
while(1):
a = []
ret, frame = cap.read()
img1 = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
_, img2 = cv2.threshold(img1, 127, 255, cv2.THRESH_BINARY)
(_, contornos, _) = cv2.findContours(img2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
ln = len(contornos)
for i in range (0, ln):
cn = contornos[i]
x, y, w, h = cv2.boundingRect(cn)
area = 2*(w+h)
if area > 60 and area < 1000:
cv2.rectangle(frame, (x,y), (x+w, y+h), (0, 255, 0), 2)
a.append(area)
ln2 = len(a)
print ln2
#here I want to call capture() function
cv2.imshow('Webcam', frame)
if cv2.waitKey(1) & 0xFF == ord('x'):
break
child_t.join()
cap.release()
cv2.destroyAllWindows()
给你。请注意,我使用 threading.Timer
而不是 threading.Thread
后跟 time.sleep
。
此外,您说您需要保存包含至少 20 个轮廓且面积大于 60 像素的帧,但是代码中的相关 if
语句没有那样做。所以我也添加了它。
消息 NameError: global name frame, ln2 are not defined 是因为线程甚至在 frame
被读取之前就已启动。同样适用于变量 ln2
。这也在下面的代码中得到修复。基本上我使用标志 writeToFile
来解决这个问题。
import threading
import cv2
writeToFile = False
exitTask = False
def threadTask():
global frame
if not exitTask:
threading.Timer(3.0, threadTask).start()
if writeToFile:
cv2.imwrite("Threads.jpg", frame)
print "Wrote to file"
cap = cv2.VideoCapture(0)
threadTask()
while(True):
areasList = []
try:
ret, frame = cap.read()
img1 = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
_, img2 = cv2.threshold(img1, 127, 255, cv2.THRESH_BINARY)
(_, contours, _) = cv2.findContours(img2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
nContours = len(contours)
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
area = 2*(w+h)
#if area > 60 and area < 1000:
if (nContours > 10) and (area > 20):
cv2.rectangle(frame, (x,y), (x+w, y+h), (0, 255, 0), 2)
areasList.append(area)
writeToFile = True
else:
writeToFile = False
#print len(areasList)
cv2.imshow('Webcam', frame)
if cv2.waitKey(1) & 0xFF == ord('x'):
raise KeyboardInterrupt
except KeyboardInterrupt:
exitTask = True
cap.release()
cv2.destroyAllWindows()
exit(0)
我正在一个使用网络摄像头的 OCR 项目中工作。我定义了一个 capture()
函数来保存 frame,它在 3 秒内包含至少 20 个面积大于 60 像素的轮廓。我需要 main while 循环一直有效。所以我正在使用一个线程来调用 capture()
函数。当我 运行 代码 Python Shell 返回一个错误:NameError: global name frame, ln2 are not defined。第 13 行注释解决了变量 frame 的错误。这是否意味着我必须复制 while 循环内的所有代码?
我在 Windows 7.
上使用 python 2.7代码如下:
import cv2
import time
import threading
cap = cv2.VideoCapture(0)
def capture():
global frame, ln2
if ln2 > 20:
cv2.imwrite("frame.jpg", frame)
time.sleep(3)
#ret, frame = cap.read() #it solves the error for variable 'frame'
child_t = threading.Thread(target = capture)
child_t.setDaemon(True)
child_t.start()
while(1):
a = []
ret, frame = cap.read()
img1 = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
_, img2 = cv2.threshold(img1, 127, 255, cv2.THRESH_BINARY)
(_, contornos, _) = cv2.findContours(img2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
ln = len(contornos)
for i in range (0, ln):
cn = contornos[i]
x, y, w, h = cv2.boundingRect(cn)
area = 2*(w+h)
if area > 60 and area < 1000:
cv2.rectangle(frame, (x,y), (x+w, y+h), (0, 255, 0), 2)
a.append(area)
ln2 = len(a)
print ln2
#here I want to call capture() function
cv2.imshow('Webcam', frame)
if cv2.waitKey(1) & 0xFF == ord('x'):
break
child_t.join()
cap.release()
cv2.destroyAllWindows()
给你。请注意,我使用 threading.Timer
而不是 threading.Thread
后跟 time.sleep
。
此外,您说您需要保存包含至少 20 个轮廓且面积大于 60 像素的帧,但是代码中的相关 if
语句没有那样做。所以我也添加了它。
消息 NameError: global name frame, ln2 are not defined 是因为线程甚至在 frame
被读取之前就已启动。同样适用于变量 ln2
。这也在下面的代码中得到修复。基本上我使用标志 writeToFile
来解决这个问题。
import threading
import cv2
writeToFile = False
exitTask = False
def threadTask():
global frame
if not exitTask:
threading.Timer(3.0, threadTask).start()
if writeToFile:
cv2.imwrite("Threads.jpg", frame)
print "Wrote to file"
cap = cv2.VideoCapture(0)
threadTask()
while(True):
areasList = []
try:
ret, frame = cap.read()
img1 = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
_, img2 = cv2.threshold(img1, 127, 255, cv2.THRESH_BINARY)
(_, contours, _) = cv2.findContours(img2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
nContours = len(contours)
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
area = 2*(w+h)
#if area > 60 and area < 1000:
if (nContours > 10) and (area > 20):
cv2.rectangle(frame, (x,y), (x+w, y+h), (0, 255, 0), 2)
areasList.append(area)
writeToFile = True
else:
writeToFile = False
#print len(areasList)
cv2.imshow('Webcam', frame)
if cv2.waitKey(1) & 0xFF == ord('x'):
raise KeyboardInterrupt
except KeyboardInterrupt:
exitTask = True
cap.release()
cv2.destroyAllWindows()
exit(0)