Сканирование QR-кода через zbar и Raspicam modul

Я хочу использовать модуль raspi cam mod для сканирования QR-кодов. Для обнаружения и декодирования qr-кодов я хочу использовать zbar. Мой текущий код:

import io import time import picamera import zbar import Image if len(argv) < 2: exit(1) # Create an in-memory stream my_stream = io.BytesIO() with picamera.PiCamera() as camera: camera.start_preview() # Camera warm-up time time.sleep(2) camera.capture(my_stream, 'jpeg') scanner = zbar.ImageScanner() scanner.parse_config('enable') pil = Image.open(argv[1]).convert('L') width, height = pil.size raw = pil.tostring() my_stream = zbar.Image(width, height, 'Y800', raw) scanner.scan(image) for symbol in image: print 'decoded', symbol.type, 'symbol', '"%s"' % symbol.data 

Как вы можете видеть, я хочу создать поток изображения, отправить этот поток в zbar, чтобы проверить, содержит ли код qr на картинке. Я не могу запустить этот код, эта ошибка является результатом:

Ошибка сегментации

—————— (программа вышла с кодом: 139) Нажмите кнопку возврата, чтобы продолжить

Я не нашел решения, как исправить эту ошибку, любую идею?

С уважением;

7 Solutions collect form web for “Сканирование QR-кода через zbar и Raspicam modul”

Недостаток всех других ответов заключается в том, что у них большое количество DELAY – например, то, что они сканируют, и отображение на экране было фактически кадром, снятым несколько секунд назад и так далее.

Это связано с медленным процессором малины Pi. Таким образом, frame-rate намного больше, чем скорость, которую наше программное обеспечение может читать и сканировать.

С большим трудом я, наконец, сделал этот код, у которого LITTLE DELAY . Поэтому, когда вы даете QRCode / BarCode, это даст вам результат менее чем за секунду.

Трюк, который я использую, объясняется в коде.

 import cv2 import cv2.cv as cv import numpy import zbar import time import threading ''' LITTLE-DELAY BarCodeScanner Author: Chen Jingyi (From FZYZ Junior High School, China) PS. If your pi's V4L is not available, the cv-Window may have some error sometimes, but other parts of this code works fine. ''' class BarCodeScanner(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.WINDOW_NAME = 'Camera' self.CV_SYSTEM_CACHE_CNT = 5 # Cv has 5-frame cache self.LOOP_INTERVAL_TIME = 0.2 cv.NamedWindow(self.WINDOW_NAME, cv.CV_WINDOW_NORMAL) self.cam = cv2.VideoCapture(-1) def scan(self, aframe): imgray = cv2.cvtColor(aframe, cv2.COLOR_BGR2GRAY) raw = str(imgray.data) scanner = zbar.ImageScanner() scanner.parse_config('enable') #print 'ScanZbar', time.time() width = int(self.cam.get(cv.CV_CAP_PROP_FRAME_WIDTH)) height = int(self.cam.get(cv.CV_CAP_PROP_FRAME_HEIGHT)) imageZbar = zbar.Image(width, height,'Y800', raw) scanner.scan(imageZbar) #print 'ScanEnd', time.time() for symbol in imageZbar: print 'decoded', symbol.type, 'symbol', '"%s"' % symbol.data def run(self): #print 'BarCodeScanner run', time.time() while True: #print time.time() ''' Why reading several times and throw the data away: I guess OpenCV has a `cache-queue` whose length is 5. `read()` will *dequeue* a frame from it if it is not null, otherwise wait until have one. When the camera has a new frame, if the queue is not full, the frame will be *enqueue*, otherwise be thrown away. So in this case, the frame rate is far bigger than the times the while loop is executed. So when the code comes to here, the queue is full. Therefore, if we want the newest frame, we need to dequeue the 5 frames in the queue, which is useless because it is old. That's why. ''' for i in range(0,self.CV_SYSTEM_CACHE_CNT): #print 'Read2Throw', time.time() self.cam.read() #print 'Read2Use', time.time() img = self.cam.read() self.scan(img[1]) cv2.imshow(self.WINDOW_NAME, img[1]) cv.WaitKey(1) #print 'Sleep', time.time() time.sleep(self.LOOP_INTERVAL_TIME) cam.release() scanner = BarCodeScanner() scanner.start() 

В линии

scanner.scan (изображение)

вы используете переменную, которая раньше не появлялась в коде. Поскольку zbar написан на C, он не понимает, что переменная не определена, и библиотека пытается читать данные мусора, как если бы это был образ. Следовательно, segfault. Я предполагаю, что вы имели в виду my_stream вместо изображения.

Я использую QR-декодирование на малине для моего проекта. Я решил это, используя модуль subprocces. Вот моя функция для QR-декодирования:

 import subprocess def detect(): """Detects qr code from camera and returns string that represents that code. return -- qr code from image as string """ subprocess.call(["raspistill -n -t 1 -w 120 -h 120 -o cam.png"],shell=True) process = subprocess.Popen(["zbarimg -D cam.png"], stdout=subprocess.PIPE, shell=True) (out, err) = process.communicate() qr_code = None # out looks like "QR-code: Xuz213asdY" so you need # to remove first 8 characters plus whitespaces if len(out) > 8: qr_code = out[8:].strip() return qr_code 

Вы можете легко добавить параметры для таких функций, как img_widt и img_height, и изменить эту часть кода

 "raspistill -n -t 1 -w 120 -h 120 -o cam.png" 

в

 "raspistill -n -t 1 -w %d -h %d -o cam.png" % (img_width, img_height) 

если вы хотите разный размер изображения для декодирования.

Прочитав это , я смог придумать питоновское решение с участием OpenCV.

Сначала вы создаете OpenCV на Pi, следуя этим инструкциям . Это, вероятно, займет несколько часов.

Теперь перезагрузите Pi и используйте следующий скрипт (если у вас установлен python-zbar), чтобы получить данные QR / barcode:

 import cv2 import cv2.cv as cv import numpy import zbar class test(): def __init__(self): cv.NamedWindow("w1", cv.CV_WINDOW_NORMAL) # self.capture = cv.CaptureFromCAM(camera_index) #for some reason, this doesn't work self.capture = cv.CreateCameraCapture(-1) self.vid_contour_selection() def vid_contour_selection(self): while True: self.frame = cv.QueryFrame(self.capture) aframe = numpy.asarray(self.frame[:,:]) g = cv.fromarray(aframe) g = numpy.asarray(g) imgray = cv2.cvtColor(g,cv2.COLOR_BGR2GRAY) raw = str(imgray.data) scanner = zbar.ImageScanner() scanner.parse_config('enable') imageZbar = zbar.Image( self.frame.width, self.frame.height,'Y800', raw) scanner.scan(imageZbar) for symbol in imageZbar: print 'decoded', symbol.type, 'symbol', '"%s"' % symbol.data cv2.imshow("w1", aframe) c = cv.WaitKey(5) if c == 110: #pressing the 'n' key will cause the program to exit exit() # p = test() 

Примечание. Мне пришлось поворачивать объектив Raspi Camera против часовой стрелки около 1/4 – 1/3 оборота, прежде чем zbar смог обнаружить QR / штрих-коды.

С приведенным выше кодом, когда zbar обнаруживает QR / штрих-код, декодированные данные печатаются в консоли. Он работает непрерывно, останавливается только при нажатии клавиши n

Для тех, кто все еще ищет решения для этого … Этот код уродливый, но он работает с обычной веб-камерой довольно хорошо, еще не пробовал камеру Pi. Я новичок в python, так что это лучшее, что я мог придумать, работая как на Python2, так и на 3.

Создайте скрипт bash с именем kill.sh и сделайте его исполняемым … (chmod -x)

  #kill all running zbar tasks ... call from python ps -face | grep zbar | awk '{print $2}' | xargs kill -s KILL 

Затем выполните системный вызов из python, например …

 import sys import os def start_cam(): while True: #Initializes an instance of Zbar to the commandline to detect barcode data-strings. p=os.popen('/usr/bin/zbarcam --prescale=300x200','r') #Barcode variable read by Python from the commandline. print("Please Scan a QRcode to begin...") barcode = p.readline() barcodedata = str(barcode)[8:] if barcodedata: print("{0}".format(barcodedata)) #Kills the webcam window by executing the bash file os.system("/home/pi/Desktop/kill.sh") start_cam() 

Надеюсь, это поможет людям с теми же вопросами в будущем!

Довольно поздний ответ, но я столкнулся с рядом проблем, пытаясь заставить Zbar работать. Хотя я использовал веб-камеру USB, но мне пришлось установить несколько библиотек, прежде чем я смогу установить zbar. Я установил fswebcam, python-zbar, libzbar-dev и, наконец, запустил setup.py.

Что еще более важно, zbar из sourceforge не сработал для меня, но для меня работал один из github, у которого есть обертка Python.

Я задокументировал свои шаги по http://techblog.saurabhkumar.com/2015/09/scanning-barcodes-using-raspberry-pi.html, если это может помочь

Просто небольшое изменение от Dan2theR, потому что я не хочу создавать другой файл оболочки.

 import sys import os p = os.popen('/usr/bin/zbarcam --prescale=300x300 --Sdisable -Sqrcode.enable', 'r') def start_scan(): global p while True: print('Scanning') data = p.readline() qrcode = str(data)[8:] if(qrcode): print(qrcode) try: start_scan() except KeyboardInterrupt: print('Stop scanning') finally: p.close() 
 
Interesting Posts for Van-Lav

Преобразование двоичного кода в список цифр Python

HTML для строки RTF с использованием Python

Обнаружить, скорее всего, слова из текста без пробелов / комбинированных слов

Python: аргументы для использования itertools для разбиения списка на группы

Как отправить значение из Arduino на Python, а затем использовать это значение

получить заголовок внутри тега ссылки в HTML с помощью beautifulsoup

Смешивание категориальных и непрерывных данных в классификаторе Naive Bayes с использованием scikit-learn

Программировать ввод данных стиля слияния в существующие таблицы Excel?

Будет ли настоящий путь.py, пожалуйста, встаньте?

проблема подклассификации встроенного типа

Как написать регулярное выражение для замены слова, но сохранить его в Python?

Получение unittest Python приводит к методу tearDown ()

bufsize должен быть целочисленной ошибкой, а grepping message

что означает «|» в строке типа numpy?

изменение цвета элементов ttk.Progressbar в xpnative теме – python

Python - лучший язык программирования в мире.