Error with global variables are not defined in a thread function on python

半腔热情 提交于 2019-12-24 07:54:13

问题


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

回答1:


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)


来源:https://stackoverflow.com/questions/41501384/error-with-global-variables-are-not-defined-in-a-thread-function-on-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!