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)