# Распознавание QR-кода с захватом одного кадра

{% hint style="danger" %}
Вся информация ниже взята из первоисточника: <https://clover.coex.tech/ru/camera.html>
{% endhint %}

1. Откроем терминал и создадим пустой файл с расширением **.py**

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MdsHIbKvaFeQbZFFzrV%2F-MdsL5Rah5f9CQNkLHPC%2FcpHCNgz2298.jpg?alt=media\&token=b0e1ddf2-cd5c-41c1-a2bf-91233ab9fa83)

{% hint style="warning" %}
Для создания текстового файла используем команду **nano**
{% endhint %}

2\. Возьмем из официального гитбука шаблон по распознаванию qr-кода:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MdsHIbKvaFeQbZFFzrV%2F-MdsLfdh0MF572swTvNp%2F_y2JS1pcEPQ.jpg?alt=media\&token=762711a9-338d-43cd-a465-4e0b4468f6a8)

{% hint style="warning" %}
Официальный гитбук расположен по адресу: <https://clover.coex.tech/ru/>
{% endhint %}

3\. Скопируем его содержимое в наш файл:&#x20;

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MdsHIbKvaFeQbZFFzrV%2F-MdsMG9xrRVBE-EbMWQF%2FVNHZC-BYR0I.jpg?alt=media\&token=5ac4c6e7-8172-4906-94b1-779829c939d6)

{% hint style="warning" %}
Для быстрого копирования можно использовать комбинацию клавиш: CTRL+SHIFT+C (копировать) и   CTRL+SHIFT+V (вставка)
{% endhint %}

В целом, этот код уже способен распознавать qr-коды, однако, много лишней информации, которую мы никак не используем, поэтому удалим ее. Наш код примет вид:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-Me1OAZsOS8V1Ji3rB6X%2F-Me1QhhW7lon2sgn-nFZ%2Fimage.png?alt=media\&token=dbf63617-603b-4eb5-94ed-ff061e5c01be)

Давайте разберем построчно этот скрипт, поскольку, именно от него мы и будем отталкиваться при распознавании qr-кодов.

**import rospy                                                                                                                                                                  from pyzbar import pyzbar                                                                                                                                                                   from cv\_bridge import CvBridge                                                                                                                                                  from sensor\_msgs.msg import Image**

В этом блоке идет импорт, необходимых для нашей программы библиотек.

**bridge = CvBridge() -** вызов ROS-сервиса

**rospy.init\_node('barcode\_test')** - инициализация ноды с уникальным именем *barcode\_test*

{% hint style="info" %}
Подробнее про вышеперечисленные фрагменты кода можно изучить по ссылке: <https://clover.coex.tech/ru/ros.html>
{% endhint %}

**def image\_callback(data):** - объявляем процедуру (функцию) с именем image\_callback и задаем для нее единственный параметр data

**cv\_image = bridge.imgmsg\_to\_cv2(data, 'bgr8')** - захватываем изображение с камеры и кладем это изображение в переменную cv\_image

**barcodes = pyzbar.decode(cv\_image)** - расшифровка изображения, на котором есть qr-код. В результате получиться массив с именем barcodes (список элементов)

Отлично! Мы разобрали каждую строчку этого скрипта. Теперь давайте преобразуем этот код для захвата одного кадра. Для этого удалим параметр функции data и заменим этот аргумент на следующий:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MeFMyZ2ehWjKPq3gMsL%2F-MeFNeXjUanmQ2QJgq6L%2Fimage.png?alt=media\&token=7d55bbe0-f9a8-4672-8010-17b81af41e0b)

Эту строчку подставляем в это место вместо data:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MeFMyZ2ehWjKPq3gMsL%2F-MeFOGnkA2wgMTI1Pi4Q%2Fimage.png?alt=media\&token=28ddff4f-f7cc-43f1-a1be-28de708f2cdf)

ИТОГО, получим:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MeFMyZ2ehWjKPq3gMsL%2F-MeFOY5PPXMSlIaSL0IY%2Fimage.png?alt=media\&token=a4a87cee-f2ff-433b-bbff-3ffbe475218f)

Давайте добавим в конце кода строчку с выводом сообщения на экран с информацией о расшифрованном qr-коде.

Для этого добавьте в конец кода (во внутрь функции image\_callback) данную строчку:&#x20;

```python
print(barcodes)
```

{% hint style="info" %}
Данная программа будет работать только тогда, когда мы к камере поднесём изображение с QR-кодом
{% endhint %}

В связи с этим добавим функции взлета и полета в точку с QR-кодом для его распознавания. Наша поле для полетов выглядит следующим образом:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-Me1UbMFaWZb7ZkImKyj%2F-Me1WS7pcVp2RD2mDPd-%2Fimage.png?alt=media\&token=676ca7ba-2d7c-428e-af90-2bd1c7b200c4)

Я выдели красным маркером место взлета. Расстояние до каждого соседнего объекта - 1 метр. Видно, что ближайший QR-код находится на расстояние 1 метр по оси Y. Совершим полет в эту точку и зависнем на высоте не более 1 метра.&#x20;

Если забыли как это делать, можно освежить память по ссылке ниже:

{% content-ref url="../programmirovanie-poleta/sozdanie-avtonomnoi-programmy-programmy" %}
[sozdanie-avtonomnoi-programmy-programmy](https://lahmeneffa.gitbook.io/docs-tkuik/programmirovanie-poletov/programmirovanie-poleta/sozdanie-avtonomnoi-programmy-programmy)
{% endcontent-ref %}

Фрагмент с полетом должен выглядеть примерно так:

```python
navigate(x=0, y=0, z=1.5, speed=0.5, frame_id='body', auto_arm=True)
rospy.sleep(4)
navigate(x=0, y=1, z=1, speed=0.5, frame_id='aruco_map')
rospy.sleep(4)


land()

```

Не забудьте, чтобы эти строчки могли работать необходимо добавить импорт необходимых библиотек и вызов соответствующих сервисов:

```python
from clover import srv
from std_srvs.srv import Trigger

navigate = rospy.ServiceProxy('navigate', srv.Navigate)

land = rospy.ServiceProxy('land', Trigger)
```

Итоговый код примет вид:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MeFVTrzCjmoKOirOMac%2F-MeFVlX-6c1RBelxeXgD%2Fimage.png?alt=media\&token=a4f31f1a-14f2-4a9e-8b86-7893190bb3cc)

Сохраним и запустим данный файл.&#x20;

{% hint style="warning" %}
Для того, чтобы выйти из редактора с сохранением всех изменений нажмите последовательно следующие клавиши: ctrl+x, затем Y, после чего нажмите клавишу Enter.
{% endhint %}

{% hint style="warning" %}
Для запуску файла используйте команду python qr.py. Где qr.py - это название файла, который необходимо запустить
{% endhint %}

В результате ваш квадрокоптер успешно взлетит, совершит пролет до нашего QR-кода и приземлиться. Никакого распознавания не будет. Это происходит по тому, что функцию мы лишь объявили и никак ее не вызвали.&#x20;

Давайте добавим строчку вызова функции:

```python
image_callback()
```

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MeFWAqBOo5JulDIC6V0%2F-MeFWkBIBMDO-v7NyWap%2Fimage.png?alt=media\&token=2272ef9b-9e5d-454e-aef1-003b5455b82f)

В результате получим следующее:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MeFWAqBOo5JulDIC6V0%2F-MeFXO_uWuL9WtouOk2l%2Fimage.png?alt=media\&token=04b53bcd-d7c3-4cdf-a138-d28e68978be4)

Это пустой массив. Это означает, что QR-код он увидел, но ничего прочитать не смог. Давайте вызовем функцию еще 2 раза, тогда наверняка, хотя бы один раз он QR-код прочтет:

```python
image_callback()
image_callback()
image_callback()
```

В результате получим:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MeFWAqBOo5JulDIC6V0%2F-MeFXrPOFzNMqhEqBMRo%2Fimage.png?alt=media\&token=0036d035-688a-482f-866a-65c0e6e97a7e)

Отлично, мы прочитали наш QR-код. Причем мы его прочитали ровно столько раз, сколько мы и хотели.

{% hint style="info" %}
Если у вас на экране ошибка, то решение можно увидеть по ссылке ниже:
{% endhint %}

{% content-ref url="raspoznavanie-qr-koda-cherez-podpisku-na-topik/polet-po-tochkam-ispolzuya-koordinaty-iz-qr-koda" %}
[polet-po-tochkam-ispolzuya-koordinaty-iz-qr-koda](https://lahmeneffa.gitbook.io/docs-tkuik/programmirovanie-poletov/raspoznavanie-qr-kodov/raspoznavanie-qr-koda-cherez-podpisku-na-topik/polet-po-tochkam-ispolzuya-koordinaty-iz-qr-koda)
{% endcontent-ref %}

Все выражение в квадратных скобках — это массив:

```python
[Decoded(data='2.5 1.5 1 1 0 4', type='QRCODE', rect=Rect(left=133, top=92, width=45, height=48), polygon=[Point(x=133, y=92), Point(x=133, y=140), Point(x=178, y=139), Point(x=178, y=93)])]
```

Внутри массива перечислен один элемент. Этот элемент имеется индекс ноль.&#x20;

{% hint style="success" %}
Подробнее про массивы в python можно ознакомиться по ссылке: <https://pythonru.com/uroki/massivy-uroki-po-python-dlja-nachinajushhih>
{% endhint %}

Давайте обратимся к этому элементу и выведем на экран этот элемент. Для этого наша строчка с выводом на экран примет вид:

```python
print(barcodes[0])
```

Наш код примет следующий вид:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MeFYgv_F0fIDFAoDVqK%2F-MeFYrPV9FA7KPC6kNnu%2Fimage.png?alt=media\&token=bfd49cfb-b08e-48cc-a774-8e9b0c45dd47)

Сохраним и запустим код. В результате в терминал выведется сообщение:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MeFYgv_F0fIDFAoDVqK%2F-MeFZ-c9Zzs4bMNlEGE2%2Fimage.png?alt=media\&token=302c81df-2cd9-44d9-9df7-279370ff19c2)

Как видим, результат тот же, только уже без квадратных скобок по краям. Эта вся информация которая хранится в любом QR-коде. Элемент представляет собой кортеж с именем Decoded.&#x20;

{% hint style="success" %}
Подробнее про кортежи в python по ссылке: <https://pythonworld.ru/tipy-dannyx-v-python/kortezhi-tuple.html>
{% endhint %}

Можно заметить, что весь кортеж логически поделен на отдельные фрагменты, отделяемые запятой. Каждый фрагмент имеет свое имя и значение. Ниже я представлю эти фрагменты в виде столбца для удобного восприятия:

```python
data='2.5 1.5 1 1 0 4', 
type='QRCODE', 
rect=Rect(left=114, top=85, width=85, height=88), 
polygon=[Point(x=114, y=85), Point(x=114, y=173), Point(x=199, y=173), Point(x=199, y=85)])

```

В элементе кортежа **data** хранится зашифрованный текст QR-кода.&#x20;

В элементе кортежа **type** хранится тип зашифрованного изображения.&#x20;

В элементе кортежа **rect** хранится кортеж с именем Rect. В кортеже Rect хранятся геометрические размеры изображения в пикселях.

В элементе кортежа **polygon** имеется массив с именем Point. В этом массиве отображены координаты углов изображения в пикселях.

Давайте выведем в терминал только зашифрованный текст QR-кода. Следовательно, наша строчка с выводом на экран примет вид:

```python
 print(barcodes[0].data)
```

В результате получим:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-Me5GpHujgls08hUjP2z%2F-Me5HafvguU8N6yiSIOm%2Fimage.png?alt=media\&token=5c3d76b3-cef5-4de6-896d-2930d3f4e373)

Отлично, теперь только текст, который зашифрован в QR-коде.

Теперь давайте выведем только тип зашифрованного изображения, для этого укажем имя элемента кортежа **type**:

```python
print(barcodes[0].type)
```

В результате получим:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-Me5IPbhAnVQtMCQSKOQ%2F-Me5JlF0AbpJq9li7vnK%2Fimage.png?alt=media\&token=586c89b2-269e-4217-a68d-bc5a6dd1fcdb)

Отлично, теперь получился только тип зашифрованного изображения.

К остальным элементам можно обратиться аналогичным способам.  Однако, мы рассмотрим способ вывести на экран координаты углов изображения в пикселях. Для этого обратимся к элементу **polygon:**

```python
 print(barcodes[0].polygon)
```

В результате получим массив с 4-мя элементами:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MeBb2rh1kkVUctEv1Yp%2F-MeBbqBlSw0BRw36JNbW%2Fimage.png?alt=media\&token=a8c87aef-b7d9-4a37-bf6a-67edaa17902b)

Нумерация элементов начинается с нуля. Элемент под номером ноль - это координаты левого нижнего угла изображения; номер 1 - координаты левого верхнего угла; 2 - правый верхний; 3- правый нижний.&#x20;

Выведем в терминал координаты правого нижнего угла изображения:

![](https://2176758188-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdqITQbWJUL8n4CbfRn%2F-MeBb2rh1kkVUctEv1Yp%2F-MeBfWIaVKFSWpoT6ZgL%2Fimage.png?alt=media\&token=354c4852-a6cf-490b-8b3d-9d15ed4680a2)

**ЗАДАНИЯ НА САМОСТОЯТЕЛЬНУЮ РАБОТУ:**

1. **Измените код, чтобы появился топик в web-сервисе**
2. **Вызовите функцию распознавания QR-кода 10 раз, используйте при этом цикл.**
