全局变量的错误没有在python的线程函数中定义 [英] Error with global variables are not defined in a thread function on python

查看:232
本文介绍了全局变量的错误没有在python的线程函数中定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用网络摄像头开展OCR项目。我定义了一个 capture()函数,用于保存,其中包含最少20个等值线,面积大于60像素,等待3秒。我需要主循环一直工作。所以我使用一个线程来调用 capture()函数。当我运行代码时,Python Shell返回一个错误: NameError:全局名称框架,ln2未定义。第13条注释行解决了变量框架的错误。这是否意味着我必须复制while循环中的所有代码?



我在Windows 7上使用python 2.7。



以下是代码:

 进口cv2 
进口时间
进口线程

cap = cv2.VideoCapture(0)

def capture():
全局框架,ln2
if ln2> 20:
cv2.imwrite(frame.jpg,frame)
time.sleep(3)

#ret,frame = cap.read()#it解决了

child_t = threading.Thread(target = capture)
child_t.setDaemon(True)
child_t.start()
$ b $ (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)

在范围内(0,ln):
cn = contornos [i]
x,y,w,h = cv2.boundingRect(cn)
area = 2 *(w + h)

if area> 60和面积< 1000:
cv2.rectangle(frame,(x,y),(x + w,y + h),(0,255,0),2)
a.append(area)

ln2 = len(a)
print ln2

#我想调用capture()函数

cv2.imshow('Webcam ',frame)

if cv2.waitKey(1)& 0xFF == ord('x'):
break
$ b child_t.join()

cap.release()
cv2.destroyAllWindows()


解决方案

请注意,我正在使用 threading.Timer ,而不是 threading.Thread 后跟一个时间。睡眠另外,你说你需要保存包含最少20个等值线的面积大于60像素的帧,但相关的如果代码中的语句没有这样做。所以我也添加了。



消息 NameError:全局名称框架,ln2未定义是因为线程甚至开始在读取 frame 之前。同样适用于变量 ln2 。这在下面的代码中也是固定的。基本上我用 writeToFile 来解决这个问题。

  import threading 
import cv2
$ b $ writeToFile = False
exitTask = False
$ b $ def threadTask():
全局框架
如果不是exitTask :
threading.Timer(3.0,threadTask).start()
if writeToFile:
cv2.imwrite(Threads.jpg,frame)
print写入文件


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)
(_,contour,_)= cv2.findContours(img2,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
nContours = len(contour)

为轮廓轮廓:
x,y,w,h = cv2.boundingRect(轮廓)
面积= 2 *(w + h)

#if区域> 60和面积<如果(nContours> 10)和(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'):
举起KeyboardInterrupt

,除了KeyboardInterrupt:
exitTask = True
cap.release()
cv2.destroyAllWindows ()
exit(0)


I'm working in a project with OCR using a webcam. I defined a capture() function for save the frame that contains minimum 20 contours with areas greater than 60 pixels in lapses of 3 seconds. I need that the main while cycle works all the time. So I'm using a thread to call capture() function. When I run the code the Python Shell returned an error: NameError: global name frame, ln2 are not defined. The 13th commented line solves the error for the variable frame. Does it means that I have to replicate all the code that is inside the while cycle?

I'm using python 2.7 on Windows 7.

Here is the code:

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

解决方案

Here you go. Note that I'm using threading.Timer instead of threading.Thread followed by a time.sleep.

Also, You said you need to save the frame that contains minimum 20 contours with areas greater than 60 pixels, but the related if statement in your code doesn't do that. So I've added that as well.

The message NameError: global name frame, ln2 are not defined is because the thread is started even before frame is being read. Same applies to the variable ln2 as well. This is also fixed in the code below. Basically I used the flag writeToFile to overcome this issue.

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)

这篇关于全局变量的错误没有在python的线程函数中定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆