2017-01-06 1 views
1

웹캠을 사용하여 OCR 프로젝트에서 작업하고 있습니다. 나는 프레임을 저장하기위한 capture() 함수를 정의했다.이 함수는 최소 20 개의 등고선을 포함하고 있으며, 60 초 이상의 영역은 3 초가 걸린다. 주기가 항상 작동하는 동안 나는 그것을 필요로합니다. 그래서 capture() 함수를 호출하는 스레드를 사용하고 있습니다. 코드를 실행할 때 파이썬 쉘이 오류를 반환했습니다 : NameError : ln2 전역 이름 프레임이 정의되지 않았습니다. 13 번째 주석 행은 변수 프레임에 대한 오류를 해결합니다. while 순환 안에있는 모든 코드를 복제해야한다는 의미입니까?전역 변수의 오류가 파이썬의 스레드 함수에 정의되어 있지 않습니다.

여기
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() 
+0

저는 오늘도 처음으로 커피를 마셨지 만 상위 범위에서 전역을 선언하는 것을 보지 못합니다. 함수에서만. 함수 밖에서도이 작업을 수행해야합니다. 바이트 코드에서, 그것을 원한다면 STORE_GLOBAL로 표시하고 함수에는 LOAD_GLOBAL로 표시됩니다. 물론 STORE 및 LOAD는 실패하지 않습니다. –

답변

0

당신이가는 : 나는 여기

윈도우 7에 파이썬 2.7을 사용하고

는 코드입니다. threading.Thread 대신 threading.Timer을 사용하고 time.sleep을 사용하고 있습니다.

또한 은 최소 20 개의 윤곽선이 포함 된 프레임을 저장해야합니다.이 영역은 60 픽셀보다 큰 경우이지만 관련 코드 if 문은 그렇게하지 않습니다. 그래서 나는 그것을 덧붙였다.

메시지 이름 오류 : 전역 이름 프레임, ln2가 정의되지 않았습니다.은 스레드가 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) 
+0

잘 작동합니다! 나는 의심 스럽다. 코드가 매번 하나의 스레드로 시작하거나 메인과 동시에 실행되는 스레드를 하나만 생성합니까? –

+0

높은 수준의 퍼스펙티브에서, 메인 함수와 병렬로 실행되는 스레드는 오직 하나뿐입니다 만,'threading.Timer (3.0, threadTask) .start()'행을 자세히 보면, 기본적으로 3 초가 지난 후에'threadTask'를 실행하는 스레드를 생성합니다. –

+0

스레드가 시작되면'threadTask' 함수가 실행됩니다. 이 순간에, 우리는 스레드를 반복해서 시작하지 않거나'if' 문이 한 번만 실행되면 프레임이 저장되는 방식입니까? –

관련 문제