Закройте QR-сканер Python, если код не обнаружен, но продолжайте работать во время обработки кода

#python #opencv #python-multiprocessing

Вопрос:

Я создаю скрипт на python, который сканирует QR-коды, а затем обрабатывает информацию в коде. Python-скрипт будет запускаться каждые несколько секунд по таймеру в systemd на RBPI, но при сканировании кода — если за 5 секунд код не был обнаружен, скрипт должен завершиться. Однако, если код обнаружен, обработка должна продолжаться, и сценарий должен завершаться только после завершения обработки.

Это мой код:

 import cv2 import numpy as np from pyzbar.pyzbar import decode from multiprocessing import Process import time  def decoder(image):  gray_img = cv2.cvtColor(image,0)  barcode = decode(gray_img)    for obj in barcode:  points = obj.polygon  (x,y,w,h) = obj.rect  pts = np.array(points, np.int32)  pts = pts.reshape((-1, 1, 2))   barcodeData = obj.data.decode("utf-8")  barcodeType = obj.type  string = str(barcodeData)  cv2.destroyAllWindows()  # stop timeout on action_process and keep it running  # processMyQRCode(barcodeData) Demo:  i = 0  while i lt; 10:  print("processing code for "   str(i)   " seconds")  i  = 1  time.sleep(1)    print(string   " is processed")  exit()  def open_scanner():  #add cv2.CAP_DSHOW on windows while developing, remove on RBPI  cap = cv2.VideoCapture(0 , cv2.CAP_DSHOW)  while True:  ret, frame = cap.read()  decoder(frame)  cv2.imshow('My Title', frame)  code = cv2.waitKey(1)  if code == ord('q'):  exit()  if __name__ == '__main__':  action_process = Process(target=open_scanner)  action_process.start()  action_process.join(timeout=5)  action_process.terminate()  

Поэтому, когда код не обнаружен, тайм-аут 5 должен быть в порядке, но его следует игнорировать при выполнении цикла while внутри decoder(image)

Комментарии:

1. Из моего собственного опыта написания декодеров, декодер не может сказать: «должен быть код, позвольте мне продолжить поиск». Только в конце обработки он может определить, является ли кандидат истинным.

2. Просто я думал точно так же. Вероятно, будет решено установить counter = 0 в open_scanner() и выполнить counter = 1 и time.sleep(0.1) в while True цикле, а также передать счетчик функции декодера с if counter gt; 100 помощью : exit ()`, чтобы остановить сценарий, если через 10 секунд (действительный) код не был распознан.

Ответ №1:

После поисков в течение дня и с комментарием Ива по этому вопросу я пришел к выводу, что действовал неправильно. Поэтому теперь я добавил глобальный таймер, который отменяется, если начинается обработка QR — кода.

Теперь мой код выглядит так, и, похоже, он работает. Хотелось бы услышать, есть ли лучший способ, или если такое использование глобалов является плохой практикой.

 import cv2 import numpy as np from pyzbar.pyzbar import decode import time from threading import Timer import os   def decoder(image):  gray_img = cv2.cvtColor(image,0)  barcode = decode(gray_img)  for obj in barcode:   points = obj.polygon  (x,y,w,h) = obj.rect  pts = np.array(points, np.int32)  pts = pts.reshape((-1, 1, 2))   barcodeData = obj.data.decode("utf-8")  barcodeType = obj.type  process_code(barcodeData)  def process_code(barcodeData):  print("cancel timer")  myTimer.cancel()  i = 0  while i lt; 10:  print("processing code for "   str(i)   " seconds")  i  = 1  time.sleep(1)  print(str(barcodeData)   " is processed")  os._exit(0)()  def time_out_exit() :  print("No QR Code Found")  os._exit(0)()  def open_scanner():  myTimer.start()  #add cv2.CAP_DSHOW on windows while developing, remove on RBPI  cap = cv2.VideoCapture(0 , cv2.CAP_DSHOW)  #cap = cv2.VideoCapture(0)  while True:  ret, frame = cap.read()  decoder(frame)  #cv2.imshow('My Title', frame)  code = cv2.waitKey(1)  if code == ord('q'):  exit()  globals()['myTimer'] = Timer(10.0, time_out_exit) if __name__ == '__main__':  open_scanner()