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