Распознавание QR и штрих-кодов с помощью OpenCV и Python

Python малиновый пирог Командная строка OpenCV
Распознавание QR и штрих-кодов с помощью OpenCV и Python

Эта статья была впервые опубликована вколонна Джижи


Введение: Эксперт по компьютерному зрению Адриан Роузброк недавно поделился тем, как использовать OpenCV и Zbar для написания программы сканирования, которая может распознавать QR-коды и штрих-коды в режиме реального времени, и, наконец, развернул ее на Raspberry Pi для успешного создания практичного штрих-кода и сканирования QR-кода. оборудование.

Недавно друг спросил меня (автор Adrian Rosebrock — прим. переводчика), есть ли в OpenCV какой-нибудь модуль, который может напрямую распознавать штрих-коды и QR-коды, К сожалению, ответ — нет. Но OpenCV может ускорить процесс чтения штрих-кодов и QR-кодов, включая загрузку изображений с жесткого диска, получение новых кадров из видеопотока и их обработку. Как только мы получим изображение или видеокадр, мы можем передать его в специальную библиотеку декодирования штрих-кода в Python, такую ​​как Zbar. Затем Zbar декодирует штрих-код или QR-код. Затем OpenCV может выполнять дальнейшую работу по обработке изображений и отображать результаты. Звучит сложно, но весь процесс довольно прост. Существует множество вариантов библиотеки Zbar, из которых мне больше всего нравится pyzbar.

В этой статье я научу вас читать штрих-коды и QR-коды с помощью OpenCV и Zbar. И я покажу, как развернуть этот сканер штрих-кода и QR-кода, который мы сделали, на Raspberry Pi! !

Создайте сканер штрих-кода и QR-кода, используя OpenCV и ZBar

Этот документ в основном разделен на четыре части.

  • В первой части я покажу вам, как установить библиотеку Zbar (привязки Python).
  • Библиотека Zbar используется вместе с OpenCV для сканирования штрих-кодов и QR-кодов.
  • Как только Zbar и OpenCV будут правильно настроены, я покажу, как использовать их для сканирования штрих-кодов и QR-кодов на изображении.
  • После первого распознавания штрих-кода и QR-кода на изображении мы перейдем к следующему этапу: чтение QR-кода и штрих-кода в реальном времени с помощью OpenCV и Zbar.
  • Наконец, я покажу, как развернуть встроенный сканер QR-кода и штрих-кода в реальном времени на Raspberry Pi.

Установите Zbar (с привязками Python) для декодирования штрих-кодов и QR-кодов.

Некоторое время назад Стайя Маллик опубликовала в блоге LearnOpenCV практическое руководство о том, как сканировать штрих-коды с помощью Zbar.

Часть этой статьи, посвященная установке Zbar, в основном основана на инструкциях из этого сообщения в блоге, но с небольшим улучшением, в основном касающимся установки части привязок Python Zbar, цель состоит в том, чтобы убедиться, что мы можем:

Используйте Python3 (официальная привязка Zbar Python поддерживает только Python 2.7) для точного обнаружения и обнаружения QR-кодов и штрих-кодов на изображениях.

Установите необходимое программное обеспечение всего за три простых шага.

Шаг 1. Установите Zbar из репозитория apt или brew.

Установите Zbar на Ubuntu или Raspberry Pi

$ sudo apt-get install libzbar0

Установите Zbar в MacOS

Также легко установить Zbar на macOS с помощью brew (при условии, что у вас установлен Homebrew):

$ brew install zbar

Шаг 2: Создайте виртуальную среду и установите OpenCV.

Здесь у вас есть два варианта: Использовать существующую виртуальную среду с установленным OpenCV (пропустите этот шаг и перейдите к шагу 3). Или создайте новую автономную виртуальную среду и установите OpenCV.

Виртуальные среды очень удобны для разработки Python, и я настоятельно рекомендую их использовать.

Я решил создать новую автономную виртуальную среду Python 3, затем установил OpenCV и назвал штрих-код среды:

$ mkvirtualenv barcode -p python3

Примечание. Если у вас уже установлен OpenCV, вы можете пропустить процесс компиляции OpenCV и просто связать свои привязки cv2.so с каталогом site-pakages в новой виртуальной среде Python.

Шаг 3: Установите Pyzbar Теперь у меня установлен Python 3

Затем виртуальная среда с именем barcode активировала среду штрих-кода и установила pyzbar:

$ workon barcode
$ pip install pyzbar

Если вы не используете виртуальную среду Python, просто:

$ pip install pyzbar

Если вы хотите установить pyzbar в своей версии Python, убедитесь, что вы также используете команду sudo.

Декодирование штрих-кодов и QR-кодов на одном изображении с помощью OpenCV

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

Откройте новый файл с именем barcode_scanner_image.py и вставьте следующий код:

# 导入所需工具包
from pyzbar import pyzbar
import argparse
import cv2

# 构建参数解析器并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
 help="path to input image")
args = vars(ap.parse_args())

В строках 2-4 мы импортируем необходимый инструментарий.

pyzbar и cv2 (OpenCV) необходимо установить, следуя инструкциям в предыдущем разделе. Однако argparse включен в установку Python и отвечает за разбор аргументов командной строки.

Для этого скрипта у нас есть обязательный аргумент командной строки (--image), который анализируется в строках 7-10.

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

Теперь мы получаем входное изображение и запускаем pyzbar:

# 加载输入图像
image = cv2.imread(args["image"])

# 找到图像中的条形码并进行解码
barcodes = pyzbar.decode(image)

В строке 13 мы загружаем изображение по его пути (в нашем удобном каталоге args).

Отсюда мы вызываем pyzbar.decode для обнаружения и декодирования штрих-кода на изображении (строка 16).

Мы еще не закончили — теперь нам нужно проанализировать информацию, содержащуюся в переменной штрих-кода:

# 循环检测到的条形码
for barcode in barcodes:
 # 提取条形码的边界框的位置
 # 画出图像中条形码的边界框
 (x, y, w, h) = barcode.rect
 cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)

 # 条形码数据为字节对象,所以如果我们想在输出图像上
 # 画出来,就需要先将它转换成字符串
 barcodeData = barcode.data.decode("utf-8")
 barcodeType = barcode.type

 # 绘出图像上条形码的数据和条形码类型
 text = "{} ({})".format(barcodeData, barcodeType)
 cv2.putText(image, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX,
  0.5, (0, 0, 255), 2)

 # 向终端打印条形码数据和条形码类型
 print("[INFO] Found {} barcode: {}".format(barcodeType, barcodeData))

# 展示输出图像
cv2.imshow("Image", image)
cv2.waitKey(0)

Начиная со строки 19, мы перебираем обнаруженные штрих-коды. В этом цикле мы продолжаем:

Извлеките координаты ограничивающей рамки (x,y) из объекта barcode.rect (строка 22), что позволяет нам найти и определить текущую позицию штрих-кода на входном изображении.

Нарисуйте ограничивающую рамку на изображении вокруг обнаруженного штрих-кода (строка 23).

Декодируйте штрих-код в строку «utf-8», извлеките тип штрих-кода (строки 27 и 28). Вызов функции .decode("utf-8") для преобразования объекта из массива байтов в строку имеет решающее значение. Вы можете экспериментировать с результатами, удаляя или добавляя комментарии.

Отформатируйте и нарисуйте barcodeData и barcodeType на изображении (строки 31-33).

Наконец, выведите те же данные, введите информацию в терминал для отладки (строка 36).

Давайте протестируем встроенный сканер штрих-кода OpenCV. Отсюда откройте терминал и выполните следующую команду:

$ python barcode_scanner_image.py --image barcode_example.png
[INFO] Found QRCODE barcode: {"author": "Adrian", "site": "PyImageSearch"}
[INFO] Found QRCODE barcode: https://www.pyimagesearch.com/
[INFO] Found QRCODE barcode: PyImageSearch
[INFO] Found CODE128 barcode: AdrianRosebrock

Как вы видите в терминале, все 4 штрих-кода найдены и декодированы корректно!

Как показано, штрих-коды и QR-коды на изображении распознаются, помечаются красными прямоугольниками, и отображается содержащаяся в них информация.

Чтение штрих-кодов и QR-кодов в режиме реального времени с помощью OpenCV

В предыдущей части мы узнали, как создать сканер штрих-кода Python+OpenCV для одного изображения.

Наши сканеры штрих-кодов и QR-кодов отлично работают, но возникает вопрос, можем ли мы обнаруживать и декодировать штрих-коды + QR-коды в режиме реального времени?

Давайте попробуем. Откройте новый файл, назовите его barcode_scanner_video.py и вставьте следующий код:

# 导入所需工具包
from imutils.video import VideoStream
from pyzbar import pyzbar
import argparse
import datetime
import imutils
import time
import cv2

# 创建参数解析器,解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-o", "--output", type=str, default="barcodes.csv",
 help="path to output CSV file containing barcodes")
args = vars(ap.parse_args())

В строках 2-8 мы импортируем необходимый инструментарий. Вспоминая приведенное выше объяснение, вы должны распознать pyzbar, argparse и cv 2. Мы будем использовать VideoStream для эффективной и однопоточной обработки полученных видеокадров. Если imutils не установлен в вашей системе, просто используйте следующую команду:

$ pip install imutils

Затем мы анализируем необязательный аргумент командной строки --output, который содержит путь к выходному CSV-файлу. Этот файл будет содержать метки времени и полезные данные штрих-кодов, обнаруженных и проанализированных из видеопотока. Если этот параметр не указан, то CSV-файл заменяется нашим текущим рабочим каталогом с именем «barcodes.csv» (строки 11-14).

Здесь мы инициализируем видеопоток, открывая файл CSV:

# 初始化视频流,让摄像头热热身
print("[INFO] starting video stream...")
# vs = VideoStream(src=0).start()
vs = VideoStream(usePiCamera=True).start()
time.sleep(2.0)

# 打开输出CSV文件,用来写入和初始化迄今发现的所有条形码
csv = open(args["output"], "w")
found = set()

В строках 18-19 мы инициализируем и запускаем видеопоток, вы можете: использовать свою собственную веб-камеру USB (строка 18 без комментариев и строка 19 с комментариями) или, если вы используете Raspberry Pi (и я то же самое), вы можете использовать PiCamera ( строка 19 без комментариев и строка комментариев 18).

Я решил использовать свою камеру Raspberry Pi PiCamera, о которой будет рассказано в следующем разделе.

Затем ждем несколько секунд, пока камера прогреется (строка 20).

Мы запишем все найденные штрих-коды и QR-коды на жесткий диск в виде CSV-файла (следите за тем, чтобы не было дубликатов). Это всего лишь пример записи штрих-кодов, конечно можно делать как угодно, например, после обнаружения штрих-кодов считать их как:

  • сохранить его в базе данных SQL
  • отправить его на сервер
  • загрузить его в облако
  • Отправить электронное письмо или текстовое сообщение

Фактическая операция не является обязательной, мы просто используем CSV-файл в качестве примера.

Открываем CSV-файл для записи на диск в строке 24. Если вы изменили код для добавления в файл, вы могли бы просто изменить второй параметр с «w» на «a» (но тогда вы сможете искать дубликаты файлов только наоборот).

Мы также инициализируем набор для найденного штрих-кода. Этот набор будет содержать уникальные штрих-коды для предотвращения дублирования.

Приступаем к получению и обработке видеокадров:

# 循环来自视频流的帧
while True:
 # 抓取来自单线程视频流的帧, 
 # 将大小重新调整为最大宽度400像素
 frame = vs.read()
 frame = imutils.resize(frame, width=400)

 # 找到视频中的条形码,并解析所有条形码
 barcodes = pyzbar.decode(frame)

В строке 28 мы запускаем цикл, продолжая захватывать и изменять размер кадров из видеопотока (строки 31 и 32).

Здесь мы вызываем pyzbar.decode для обнаружения и декодирования всех штрих-кодов и QR-кодов в кадре.

Затем мы перебираем обнаруженные штрих-коды:

 # 循环检测到的条形码
 for barcode in barcodes:
  # 提取条形码的边界框位置
  # 绘出围绕图像上条形码的边界框
  (x, y, w, h) = barcode.rect
  cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)

  # 条形码数据为字节对象,所以如果我们想把它画出来
  # 需要先把它转换成字符串
  barcodeData = barcode.data.decode("utf-8")
  barcodeType = barcode.type

  # 绘出图像上的条形码数据和类型
  text = "{} ({})".format(barcodeData, barcodeType)
  cv2.putText(frame, text, (x, y - 10),
   cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

  # 如果条形码文本目前不在CSV文件中, write
  # 就将时间戳+条形码 to disk and update the set
  if barcodeData not in found:
   csv.write("{},{}\n".format(datetime.datetime.now(),
    barcodeData))
   csv.flush()
   found.add(barcodeData)

Если вы посмотрите предыдущий раздел о петлях, то увидите, что эта петля очень похожа на предыдущую.

По сути, строки 38-52 аналогичны предыдущему скрипту для распознавания одиночного изображения. Подробное объяснение этой части кода см. в разделе «Обнаружение и сканирование штрих-кода одиночного изображения».

Строки 56-60 относительно новые. В этих строках кода мы проверяем, не найден ли уникальный (ранее не найденный) штрих-код (строка 56).

Если это так, мы записываем метку времени и данные в файл CSV (строки 57-59). Кроме того, barcodeData может быть добавлен к найденному набору как простой способ борьбы с дубликатами файлов.

В оставшихся строках кода скрипта сканирования живого штрих-кода мы отображаем видеокадр, проверяем экранирование и очищаем:

 # 展示输出帧
 cv2.imshow("Barcode Scanner", frame)
 key = cv2.waitKey(1) & 0xFF

 # 如果按下”q”键就停止循环
 if key == ord("q"):
  break

# 关闭输出CSV文件进行清除
print("[INFO] cleaning up...")
csv.close()
cv2.destroyAllWindows()
vs.stop()

В строке 63 мы показываем выходной кадр.

Затем в строках 64-68 мы проверяем, была ли нажата «q», выполняя основной цикл.

Наконец, мы выполняем очистку строк 72-74.

Разверните сканеры штрих-кода и QR-кода на Raspberry Pi

Я решил создать свой собственный сканер штрих-кода в реальном времени, используя Raspberry Pi, сенсорный экран и внешний аккумулятор.

На картинке ниже показан результат моей сборки. Если вы хотите сделать его самостоятельно, вот необходимые детали:

  • Raspberry Pi 3 (вы также можете использовать последнюю версию 3 B+)
  • Модуль камеры Raspberry Pi
  • Pi Foundation 7-дюймовый сенсорный экран
  • Банк питания RAVPower 22000 мАч

Его легко собрать.

Здесь откройте терминал на Raspberry Pi и запустите приложение с помощью следующей команды (для этого шага вам понадобится клавиатура/мышь, но позже она вам не понадобится):

$ python barcode_scanner_video.py
[INFO] starting video stream...

Как только все будет готово, вы можете показать штрих-код на камеру, вы можете открыть файл barcode.csv (или, если хотите, вы можете выполнить tail -f barcodes.csv на другом терминале, чтобы увидеть данные при открытии файла CSV ).

Сначала я показал камере QR-код на черном фоне, и Збар легко его обнаружил:

Затем я нашел еще один QR-код с этой настройкой на своей кухне:

Это сработало! И он может сканировать и идентифицировать QR-коды под разными углами.

Теперь давайте попробуем QR-код, содержащий данные json-blob:

Наконец, я попробовал традиционные 1D-штрих-коды:

Одномерные штрих-коды немного сложнее для нашей системы, потому что камера не поддерживает автофокус. Но в итоге штрих-код был успешно обнаружен и расшифрован.

Гораздо лучше, если вы используете веб-камеру USB с автофокусом.

Эпилог

В этой статье мы обсудили, как создать сканер штрих-кода и QR-кода с использованием OpenCV и библиотеки Python Zbar.

После установки Zbar и OpenCV мы создали два скрипта Python:

  • Первый предназначен для сканирования штрих-кодов и QR-кодов на одном изображении.
  • Второй — для считывания штрих-кодов и QR-кодов в режиме реального времени. В обоих случаях мы использовали OpenCV для ускорения процесса.

Наконец, мы развернули созданную программу на Raspberry Pi и успешно распознали штрих-коды и QR-коды в режиме реального времени.

Вы можете попробовать сделать такой сканер штрих-кода и QR-кода самостоятельно,Загрузка исходного кода проекта

Использованная литература:www.pyimagesearch.com


0806 «Искусственный интеллект — от нуля до мастера» со скидкой, ограниченной по времени!

Нажмите здесь, чтобы узнать подробности

Болтать и смеяться Онлайн-программирование Узнать об этом?

(Первые 25 студентов также могут получить купон на 200 иен)