распознавание bar-кодов

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 13736
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

распознавание bar-кодов

Непрочитанное сообщение Olej » 25 авг 2018, 14:09

Автоматическое распознавание bar-кодов, bar-коды - это обобщённое название штрих кодов (линейных), QR кодов (2-мерных) ... и ещё кой каких того же типа (хотя меня лично на пока интересуют только QR коды).
Довольно много публикаций и программных пакетов для этого в последние времена.
Само изображение кода может попадать в систему самым разнообразным образом: как файл имидж-формата, записанный где-то в другом месте (по сети, с фотоаппарата-смартфона, со сканера...) или как непосредственно фрейм изображения, захваченный с WEB-камеры на USB.
Отрабатывать это лучше, думаю, на стационарном Linux, но потом бы заманчиво перенести и на одноплатные микрокомпьютеры, типа Orange Pi.
С большой вероятностью делать это лучше (проще, быстрее, наличие готового инструментария) на Python.

Аватара пользователя
Olej
Писатель
Сообщения: 13736
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: распознавание bar-кодов

Непрочитанное сообщение Olej » 25 авг 2018, 14:18

Olej писал(а): Довольно много публикаций и программных пакетов для этого в последние времена.
...
С большой вероятностью делать это лучше (проще, быстрее, наличие готового инструментария) на Python.
Сама генерация (это не сильно и интересно) и чтение (декодирование) изображения QR кода - в чистом виде дело пустяшное (в том смысле, что есть множество Python пакетов от разных умельцев ... поспешили ;-) ).
Но интерес состоит в том, что:
1. QR код нужно обнаружить, локализовать - он может быть частью какого-то крупного изображения, и местоположение егов изображении не фиксировано (нужно определить);
2. QR код может быть искажён:
- повёрнут на угол влево-вправо (не горизонтальный);
- снят под углом (не по нормали объектив) - то что называют искажения перспективы;
- какие-то ещё искажения... ?
- одновременно несколько из предыдущих видов;

Аватара пользователя
Olej
Писатель
Сообщения: 13736
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: распознавание bar-кодов

Непрочитанное сообщение Olej » 25 авг 2018, 14:52

Olej писал(а): Сама генерация (это не сильно и интересно) и чтение (декодирование) изображения QR кода - в чистом виде дело пустяшное (в том смысле, что есть множество Python пакетов от разных умельцев ... поспешили ;-) ).
Тема QR кодов уже обсуждалась здесь в форуме и не раз:
QR-код
ещё раз про QR-коды
Но это было а). давно и б). в потребительском смысле (как воспользоваться), а не в программистском.
Теперь это в разделе "Программирование"...

P.S. Пишу конспект своих действий по конкретной работе и для конкретного заказчика.
Может кому ещё попутно пригодится...
Кому не пригодится - просьба не беспокоить. ;-)

Аватара пользователя
Olej
Писатель
Сообщения: 13736
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: распознавание bar-кодов

Непрочитанное сообщение Olej » 25 авг 2018, 15:01

Olej писал(а): P.S. Пишу конспект своих действий по конкретной работе и для конкретного заказчика.
По структуре QR-кода вот более-менее внятное описание - QR-код (совсем просто, уровня "на пальцах").
Откуда для своих целей мы можем почерпнуть следующие полезности:
1. закодировать в QR можно любую символьно-числовую информацию;
2. это важно:
Максимальное количество символов, которые помещаются в один QR-код:
- цифры десятичной системы счисления — 7089;
- цифры десятичной системы счисления и буквы (латиница) — 4296;
- байты — 2953 (следовательно, около 2953 букв кириллицы в кодировке windows-1251 или около 1450 букв кириллицы в utf-8);
- иероглифы — 1817.
3. структура QR кода весьма сложная:
На QR-коде есть обязательные поля, они не несут закодированной информации, а содержат информацию для декодирования. Это:
- Поисковые узоры
- Выравнивающие узоры
- Полосы синхронизации
- Код маски и уровня коррекции
- Код версии (с 7-й версии)

4. ... да ещё с разночтениями многих несовместимых версий;
5. но влезать в это всё нет, в наших целях, никакого резона, поскольку есть в великом множестве кодеры-декодеры изображений QR а). онлайновые в Интернет (спешат наперегонки друг-другу) и б). библиотеки с программными API, в частности, во множестве на Python.

Аватара пользователя
Olej
Писатель
Сообщения: 13736
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: распознавание bar-кодов

Непрочитанное сообщение Olej » 25 авг 2018, 15:13

Olej писал(а):5. но влезать в это всё нет, в наших целях, никакого резона, поскольку есть в великом множестве кодеры-декодеры изображений QR а). онлайновые в Интернет (спешат наперегонки друг-другу) и б). библиотеки с программными API, в частности, во множестве на Python.
Для моей задачи нужно генерировать в некотором количестве чистых QR, чтобы потом подвергать их искажениям и восстановлениям...

Для генерации я воспользовался онлайн-генератором (но их великое множество) ГЕНЕРАТОР QR КОДОВ. Подготовил 2 тестовых QR с вот таким произвольным бессмысленно-русскоязычным (специально - проверка на вшивость с нелюбимым языком ;-) ) содержимым:
1-й тестовый QR код
2-й тестовый QR код: координаты угловых точек прямоугольника <x,y>
В качестве онлайн-декодера (для проверки чистых QR) использую вот этот декодер Распознавание QR кода.
Выберите файл с QR кодом, который хотите расшифровать:
Указываю файлы, сгенерированные выше, и получаю:
QR код успешно распознан:
1-й тестовый QR код
QR код успешно распознан:
2-й тестовый QR код: координаты угловых точек прямоугольника <x,y>
ОК, тестеры у меня уже готовы. ;-)
Вложения
qr1.gif
qr1.gif (2.19 КБ) 1696 просмотров
qr2.gif
qr2.gif (4.48 КБ) 1696 просмотров

Аватара пользователя
Olej
Писатель
Сообщения: 13736
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: распознавание bar-кодов

Непрочитанное сообщение Olej » 25 авг 2018, 15:43

Olej писал(а): Довольно много публикаций и программных пакетов для этого в последние времена.
...
С большой вероятностью делать это лучше (проще, быстрее, наличие готового инструментария) на Python.
Из свежих меня заинтересовала
An OpenCV barcode and QR code scanner with ZBar
by Adrian Rosebrock on May 21, 2018 in Image Processing, Raspberry Pi, Tutorials
Изображение
С той разницей, что: меня, пока, интересует не Rapsberry Pi (но это интересно на потом), а дистрибутивы Linux общего использования, в частности, RPM дистрибутивы...
A few weeks ago Satya Mallick from the LearnOpenCV blog posted a really great tutorial on using the ZBar library to scan barcodes.
The instructions to install ZBar in today’s post are largely based on his instructions, but with a few updates, the largest one being related to how we install the Python zbar bindings themselves, ensuring we can:

- Use Python 3 (the official zbar Python bindings only support Python 2.7)
- Detect and localize exactly where in the image the barcode is.
Installing the necessary software is an easy 3-step process.
Статью на которую ссылается автор нужно отметить особо - Barcode and QR code Scanner using ZBar and OpenCV
FEBRUARY 18, 2018 BY SATYA MALLICK 44 COMMENTS:

Аватара пользователя
Olej
Писатель
Сообщения: 13736
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: распознавание bar-кодов

Непрочитанное сообщение Olej » 26 авг 2018, 11:23

Olej писал(а): По структуре QR-кода вот более-менее внятное описание - QR-код (совсем просто, уровня "на пальцах").
Структура QR кода хорошо расписана здесь - Генерируем QR код сами:
Ничего не понятно? Мне тоже. Посмотрите на пример и всё станет ясно.
Изображение
Всё оставшееся свободное пространство на холсте разбивается на столбики: каждые 2 модуля, не важно что находится в этих модулях, кроме вертикильной полосы синхронизации, которая просто пропускается. Заполнение начинается с правого нижнего угла, идёт в пределах столбика справа налево, снизу вверх. Если текущий модуль занят (например полосой синхронизации или выравнивающим узором), то он просто пропускается. Если достигнут верх столбика, то движение продолжается с верхнего правого угла столбика, который расположен левее, и идёт сверху вниз. Достигнув низа, движение продолжается от нижнего правого угла столбика, который расположен левее, и идёт снизу вверх. И так далее, пока всё свободное пространство не будет заполнено.
Изображение
:lol:
Это всё до уровня ручной генерации пикселей изображения...
Но в наши задачи, к счастью, такой уровень детализации не входит! ;-)

Аватара пользователя
Olej
Писатель
Сообщения: 13736
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: распознавание bar-кодов

Непрочитанное сообщение Olej » 26 авг 2018, 13:40

Olej писал(а): Сама генерация (это не сильно и интересно) и чтение (декодирование) изображения QR кода - в чистом виде дело пустяшное (в том смысле, что есть множество Python пакетов от разных умельцев ... поспешили ;-) ).
Именно из-за этого + из-за того, что область новая, как составная часть вообще OpenCV и компьютерного зрения, и наличествует огромный зверинец пакетов и версий, и некоторые из них работают только с Python 2, а некоторые только с Python 3 ... - есть прямой резон потерять некоторое время, но установить виртуальные среды Python для установки и экспериментов с этими разноверсионными пакетами.

Аватара пользователя
Olej
Писатель
Сообщения: 13736
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: распознавание bar-кодов

Непрочитанное сообщение Olej » 04 сен 2018, 23:12

Olej писал(а): Из свежих меня заинтересовала
An OpenCV barcode and QR code scanner with ZBar
По мотивам, но не только это...
- Распознавалка QR-кодов (повёрнутых, искажённых перспективой и т.д.), которая позволяет не только распознать QR, но и детерминировать искажение:

Код: Выделить всё

# -*- coding: utf-8 -*- 
import numpy as np
import argparse
import imutils
from pyzbar import pyzbar
import cv2
import sys
import math
from common import *

ap = argparse.ArgumentParser()                               # construct the argument parse and parse the arguments
ap.add_argument( "-i", "--image", required=True, help="path to the image file" )
args = vars(ap.parse_args())

image  = cv2.imread( args[ "image" ], cv2.IMREAD_LOAD_GDAL ) # load the image from disk
if image.ndim > 2:
    image = cv2.cvtColor( image, cv2.COLOR_BGR2GRAY )        # convert image into grayscale

#thresh, n = thresh_opt( image, 70, 150, 10 )
thresh, n = thresh_opt( image, 50, 120, 10 )                 # find optimal p4qr1.jpg
#print( '{} => {}'.format( thresh, n ) )            
image = cv2.threshold( image, thresh, 255, cv2.THRESH_BINARY )[ 1 ]

barcodes = pyzbar.decode( image )                            # find the barcodes in the image 
n = len( barcodes )
print( '{} => {}'.format( thresh, n ) )
#print( barcodes[ 0 ].polygon )

image = cv2.bitwise_not( image )                             # convert to monochrome
show( image, 2000 )

def angles( bar ):
    def get_angl( p1, p2 ):
        x = p1.x - p2.x
        y = p1.y - p2.y
        a = math.atan2( y, x ) * 180 / math.pi  
        if abs( y ) > abs( x ): a -= 90
        else: a -= 180
        if a > 180:  a -= 360
        if a < -180: a += 360
        return a
    poly = bar.polygon
    return ( get_angl( poly[ 0 ], poly[ 3 ] ), get_angl( poly[ 1 ], poly[ 2 ] ) ) 

for angle in range( -45, 46, 5 ):                            # loop over the rotation angles
#    rotated = imutils.rotate( image, angle )
    rotated = imutils.rotate_bound( image, angle )
    rotated = cv2.bitwise_not( rotated )
    barcodes = pyzbar.decode( rotated )                      # find the barcodes in the image 
    for barcode in barcodes:
        qa = angles( barcode )
        print( '{:+04d}: {}\t<{:.2f}|{:.2f}>°'.format( angle, barcode.polygon, qa[ 0 ], qa[ 1 ] ) ) 
    if 0 == len( barcodes ):
        print( '{:+04d}: .................'.format( angle ) ) 
    key = show( rotated, 2000 )
    if key == 27 or key == ord( 'q' ): 
        sys.exit() 

Всего то ... ;-)

Код: Выделить всё

[olej@xenix barcode-scanner]$ python2 rotate_doc.py -i ../QR1/qr1.gif
50 -> 1
60 -> 1
70 -> 1
80 -> 1
90 -> 1
100 -> 1
110 -> 1
80 => 1
-045: [Point(x=32, y=156), Point(x=155, y=280), Point(x=279, y=156), Point(x=156, y=33)]	<-44.77|-45.00>°
-040: [Point(x=33, y=146), Point(x=145, y=279), Point(x=278, y=167), Point(x=166, y=32)]	<-40.60|-40.10>°
-035: [Point(x=32, y=132), Point(x=132, y=275), Point(x=275, y=175), Point(x=175, y=32)]	<-34.97|-34.97>°
-030: [Point(x=31, y=119), Point(x=119, y=270), Point(x=270, y=183), Point(x=183, y=31)]	<-30.07|-29.95>°
-025: [Point(x=30, y=104), Point(x=105, y=263), Point(x=262, y=189), Point(x=189, y=31)]	<-24.66|-25.24>°
-020: [Point(x=30, y=90), Point(x=89, y=254), Point(x=253, y=194), Point(x=194, y=30)]	<-20.10|-20.10>°
-015: [Point(x=28, y=73), Point(x=73, y=242), Point(x=242, y=196), Point(x=196, y=28)]	<-15.00|-15.23>°
-010: [Point(x=27, y=57), Point(x=57, y=229), Point(x=229, y=199), Point(x=199, y=27)]	<-9.89|-9.89>°
-005: [Point(x=25, y=40), Point(x=40, y=215), Point(x=215, y=199), Point(x=199, y=25)]	<-4.93|-5.22>°
+000: [Point(x=23, y=23), Point(x=23, y=198), Point(x=199, y=199), Point(x=198, y=23)]	<0.00|0.33>°
+005: [Point(x=25, y=199), Point(x=199, y=215), Point(x=215, y=40), Point(x=40, y=25)]	<4.93|5.22>°
+010: [Point(x=27, y=199), Point(x=198, y=228), Point(x=229, y=57), Point(x=57, y=27)]	<9.89|10.28>°
+015: [Point(x=28, y=196), Point(x=196, y=242), Point(x=242, y=73), Point(x=73, y=28)]	<15.00|15.23>°
+020: [Point(x=30, y=194), Point(x=192, y=251), Point(x=254, y=89), Point(x=90, y=29)]	<19.98|20.94>°
+025: [Point(x=31, y=189), Point(x=189, y=263), Point(x=263, y=105), Point(x=105, y=30)]	<24.96|25.10>°
+030: [Point(x=31, y=183), Point(x=183, y=270), Point(x=270, y=119), Point(x=119, y=31)]	<30.07|29.95>°
+035: [Point(x=32, y=175), Point(x=176, y=275), Point(x=275, y=132), Point(x=132, y=32)]	<34.97|34.70>°
+040: [Point(x=32, y=166), Point(x=167, y=278), Point(x=279, y=145), Point(x=146, y=33)]	<40.60|40.10>°
+045: [Point(x=33, y=156), Point(x=156, y=279), Point(x=280, y=155), Point(x=156, y=32)]	<44.77|-45.00>°
Вложения
rotate_doc.py
(2.14 КБ) 58 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 13736
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: распознавание bar-кодов

Непрочитанное сообщение Olej » 04 сен 2018, 23:14

Olej писал(а): Всего то ... ;-)
Да ... и используемые функции - common.py:

Код: Выделить всё

# -*- coding: utf-8 -*- 
from pyzbar import pyzbar
import cv2
import imutils

def show( img, tout = 0 ):
    frame = imutils.resize( img, width = 400 )    # resize it to have a maximum width of 400 pixels
    cv2.imshow( '', frame )                       # show the output image    
    return cv2.waitKey( tout ) & 0xFF             # wait for key pressed

def thresh_opt( img, tb = 50, tf = 90, ts = 4 ):
    nmax = 0;
    for t in range( tb, tf, ts ):
        mimg = cv2.threshold( img, t, 255, cv2.THRESH_BINARY )[ 1 ]
        show( mimg, 1000 )
        n = len( pyzbar.decode( mimg ) )
        print( '{} -> {}'.format( t, n ) )
        if n > nmax:
            nmax = n
            thr = t
            continue
        if n < nmax:
            return ( thr + t - ts ) / 2 , nmax
    return ( thr + t ) / 2 , nmax
Вложения
common.py
(824 байт) 51 скачивание

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 3 гостя