1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/qunshanhe-JLURoboVision

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

Визуальный код TARS-GO команды Университета Цзилина JLURoboVision


Благодарность

Сначала хотелось бы поблагодарить за помощь в создании этого кода открытые коды, предоставленные университетом Дуньцзинь в 2018 году, а также университетами Шэньчжэня и Шанхая в 2019 году. Надеемся, что этот код поможет другим командам достичь большего прогресса на сцене RM.


Введение

Этот код представляет собой алгоритмы видения для пехоты команды TARS-GO Университета Цзилина для сезона Robomaster 2020 года. Основные модули включают распознавание броневых плит, распознавание энергетического механизма большой ветряной мельницы, вычисление углов, управление камерой и сериальные порты/CAN-коммуникацию.


Содержание

1. Описание функций

Модуль Функция
Распознавание броневых плит Обнаруживает положение противников и распознаёт цифры на броневых пластинах
Распознавание энергетического механизма большой ветряной мельницы Обнаруживает положение целей для активации энергетического механизма большой ветряной мельницы
Вычисление углов По полученным данным вычисляет угол yaw, pitch относительно ствола и расстояние до цели
Управление камерой Интегрированный SDK камеры Dahua для управления параметрами камеры и сбора изображений
Сериальные порты/CAN-коммуникация Коммуникация с нижним уровнем машины для передачи информации о состоянии машины и обратной связи

2. Примеры работы

Распознавание броневых плит

Распознавание броневых плит осуществляется с помощью традиционных алгоритмов OpenCV для обнаружения местоположения плит, а SVM используется для распознавания цифр на этих плитах.

Учитывая реалии боевых действий, эффективная дальность стрельбы роботов составляет от 1 до 7 метров. В этом диапазоне распознавание броневых плит достигает 98%. Алгоритм определяет координаты четырех вершин и центра плиты на изображении.

**Цвет противника = Синий; Цифра цели = 1**
Рисунок 2.1 Распознавание броневых плит
**Цвет противника = Красный; Цифра цели = 2**
Рисунок 2.2 Распознавание броневых плит

При разрешении изображения 640x480 скорость обработки изображений может достигать около 340 fps, а после применения области интереса (ROI) — до 420 fps. Учитывая необходимость учета частоты кадров для достижения насыщения электронной механической задержки, было решено отказаться от использования области интереса (ROI), чтобы избежать проблем с недостаточной своевременной проверкой полей зрения после ее ввода. Это позволяет ускорить реакцию системы автоматической прицеливания.

640×480 (максимальная частота кадров до 340 Гц)
Рисунок 2.3 Временная частота кадров для распознавания брони
**320×240 (максимальная частота кадров до 1400 Гц)**
Рисунок 2.4 Временная частота кадров для распознавания брони

Для цифрового распознавания брони используется SVM. После того как двоичное изображение брони обрезается согласно информации о положении брони, применяется проективное преобразование, и затем это изображение передается в обученную модель SVM для распознавания. Точность распознавания цифр составляет 98%.

Рисунок 2.5 Цифровое распознавание брони

Распознавание энергетического механизма «Ветряная мельница»

Рисунок 2.6 Демонстрация распознавания ветряной мельницы

Вычисление угла

Для вычисления угла используются два метода, зависящие от расстояния между уровнями. Первый уровень использует алгоритм P4P, второй — PinHole, основанный на принципе малых отверстий.

Кроме того, были внедрены компенсация Y-координаты камеры относительно ствола и компенсация гравитационного поля.При тестировании с помощью эталона погрешность расстояния составила менее 10%, а угол был практически совпадающим с реальным значением.

Рисунок 2.7 Тестовое изображение для вычисления расстояния
Рисунок 2.7 Тестовое изображение для вычисления угла

3. Зависимости

Оборудование

Оборудование Модель Параметры
Вычислительная платформа Manifold2-G TX2
Камера Daheng Camera MER-050 Разрешение 640×480, экспозиция 3000–5000
Линза M0814-MP2 Фокусное расстояние 8 мм, диафрагма F4

Программное обеспечение

Тип программного обеспечения Модель
Операционная система Ubuntu 16.04 / Ubuntu 18.04
Интегрированная среда разработки Qt Creator - 4.5.2
Библиотека OpenCV - 3.4.0
DRIVE Galaxy SDK

4. Общая структура

Дерево файлов```diff

JLURoboVision/ ├── AngleSolver │ └── AngleSolver.

### Общая схема алгоритма  
 <div align=center>
 <img src="https://gitee.com/qunshanhe/JLURoboVision/raw/master/Assets/Armor.png" width="800" alt="Рисунок 4.1 Схема алгоритма автоматической наводки"/>
 </div>  
 ---
## 5. Реализация  
### Определение бронелиста  
Определение бронелиста осуществляется с использованием традиционных методов OpenCV на основе выявления характеристик объекта. Центральная идея состоит в том, чтобы найти все красные/синие светящиеся полосы противника на изображении и использовать эти полосы для моделирования и отбора бронелиста.
Основные шаги включают в себя: **предварительную обработку изображения**, **выявление светящихся полос**, **соответствие бронелиста**, **распознавание цифр на бронелисте** и, наконец, **выбор целевого бронелиста**.
1. **Предварительная обработка изображения**
Для выявления красных/синих светящихся полос требуется выполнить цветовое разделение. Базовая концепция цветового разделения включает BGR, HSV и метод вычитания каналов.
Однако первые два метода требуют прохождения через все пиксели, что делает их более затратными по времени. Поэтому мы выбрали **метод вычитания каналов** для цветового разделения.
```Основной принцип заключается в том, что при **низкой экспозиции** (3000~5000) значение канала синего цвета (B) значительно превышает значение красного канала (R) в области синей ленты.```Вычитание значения B из R и последующее бинаризация позволяет выделить область синей ленты. Аналогично происходит и в обратном случае.Кроме того, мы выполняем операцию размытия маски размером 3x3 с эллиптической формой MORPH_ELLIPSE над бинарным изображением цветового выделения для снижения шума и соединения областей лент.

<div align=center>
<img src="https://gitee.com/qunshanhe/JLURoboVision/raw/master/Assets/src_binary.jpg" width="600" alt="Рисунок 5.1 Бинарное изображение цветового выделения"/>
</div>

2. **Обнаружение лент**

Процесс обнаружения лент начинается с поиска контуров (findContours) в предварительно подготовленном бинарном изображении. Затем после первичного отбора контуров по площади производится аппроксимация эллипса (fitEllipse). Полученный поворотный прямоугольник (RotatedRect) используется для создания объекта ленты (LightBar). После удаления лент с большим углом наклона они сортируются по центральной оси слева направо.

<div align=center>
<img src="https://gitee.com/qunshanhe/JLURoboVision/raw/master/Assets/Light_Monitor.jpg" width="600" alt="Рисунок 5.2 Изображение обнаружения лент"/>
</div>

3. **Сопоставление броневых панелей**Анализируя характеристики броневой панели, можно заметить, что она состоит из двух параллельных сторон одинаковой длины. Поэтому мы выполняем двойное сопоставление всех обнаруженных лент. Определение подходящей броневой панели осуществляется путём сравнения информации о положении двух лент: угол между лентами, угол смещения, процентное соотношение длин лент и процентное соотношение проекций лент по осям X и Y. Это позволяет установить, является ли данная броневая панель подходящей (isSuitableArmor).Затем все подходящие броневые панели помещаются в массив предварительно выбранных броневых панелей. Для исключения ошибочного сопоставления из-за одиночных лент, мы используем функцию `eraseErrorRepeatArmor` для обнаружения и удаления таких ошибочных броневых панелей.

```c++
/**
* @brief: Обнаружение и удаление ошибочной броневой панели, вызванной одиночной лентой
*/
void eraseErrorRepeatArmor(std::vector<ArmorBox>& armors)
{
   int length = armors.size();
   std::vector<ArmorBox>::iterator it = armors.begin();
   for (size_t i = 0; i < length; i++)
       for (size_t j = i + 1; j < length; j++)
       {
           if ((armors[i].l_index == armors[j].l_index || armors[i].l_index == armors[j].r_index ||
                armors[i].r_index == armors[j].l_index || armors[i].r_index == armors[j].r_index))
           {
               if (armors[i].getDeviationAngle() > armors[j].getDeviationAngle())
                   armors.erase(it + i);
               else
                   armors.erase(it + j);
           }
       }
}
```

### Распознавание цифровых значений бронелиста

После сопоставления бронелиста вырезаем его из двоичной картинки (серого уровня) исходного изображения, используя вершины бронелиста. Затем применяем преобразование проекций, чтобы привести изображение бронелиста к размеру, необходимому для модели SVM, после чего передаем его в модель SVM для распознавания цифр.

<div align=center>
<img src="https://gitee.com/qunshanhe/JLURoboVision/raw/master/Assets/NumClassifier.png" width="600" alt="Рисунок 5.3 Распознавание цифровых значений бронелиста"/>
</div>

**Выбор целевого бронелиста**На основе информации о бронелисте (координаты центра вершин, расстояние до точки прицела, площадь, цифры на бронелисте и соответствие операторского задания) выполняется взвешивание, чтобы выбрать лучший бронелист как конечную цель.

<div align=center>
<img src="https://gitee.com/qunshanhe/JLURoboVision/raw/master/Assets/Armor_Monitor.png" width="600" alt="Рисунок  Yöntem 5.4 Эффект распознавания бронелиста"/>
</div>

---
### Распознавание ветряной мельницы

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

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

По координатам целевого бронелиста и центральной буквы рассчитывается угол в полярной системе координат, что позволяет прогнозировать координаты точки удара (малый знак указывает на сам бронелист, большой — требует поворота).

Наконец, разница между координатами точки удара и центром изображения преобразуется в углы yaw и pitch, добавляется кольцо PID, которое отправляется на основной контроллер панорамы.

<div align=center>
<img src="https://gitee.com/qunshanhe/JLURoboVision/raw/master/Assets/windmill.png" width="600" alt="Рисунок 5.5 Распознавание ветряной мельницы"/>
</div>

---

Исправлено:
- "Рисунок  Yöntem 5.4" заменено на "Рисунок 5.4".
- Удалены лишние пробелы после некоторых слов.
- Корректно оформлены знаки препинания.### Вычисление угла

Для вычисления угла используются два типа моделей для расчета необходимого поворота yaw и pitch для направления ствола на целевой бронелист.

Первая модель называется **P4P**, вторая — **PinHole**.

Вспомним принцип работы камеры:

$$ s \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} r_{11} & r_{12} & r_{13} & t_x \\ r_{21} & r_{22} & r_{23} & t_y \\ r_{31} & r_{32} & r_{33} & t_z \end{bmatrix} \begin{bmatrix} X \\ Y \\ Z \\ 1 \end{bmatrix} $$

1. Принцип работы модели P4P

Из вышеупомянутого можно получить матрицу перемещения камеры относительно объекта:

$$ tVec = \begin{bmatrix} t_x \\ t_y \\ t_z \end{bmatrix} $$

Формула для расчета угла поворота:

$$ \theta = atan2(t_y, t_x) $$
$$ \tan pitch = \frac{t_y}{\sqrt{{t_y}^2 + {t_z}^2}} $$
$$ \tan yaw = \frac{t_x}{t_z} $$

---

## 2. Принцип малого отверстия  

Связь пикселей с координатной системой физического мира:

$$ x_{экран} = f_x\left(\frac{X}{Z}\right) + c_x $$
$$ y_{экран} = f_y\left(\frac{Y}{Z}\right) + c_y $$

Тогда формулы для вычисления угловых перемещений следующие:

$$ \tan pitch = \frac{X}{Z} = \frac{x_{экран} - c_x}{f_x} $$
$$ \tan yaw = \frac{Y}{Z} = \frac{y_{экран} - c_y}{f_y} $$

---

## 6. Коммуникационные протоколы

Логика взаимодействия между верхней и нижней платами реализуется через наш собственный коммуникационный протокол:

Протокол состоит из 16 байт, включая 1 байт для начала фрейма, 1 байт для контрольной суммы CRC, 12 байт данных и 2 байта для меток.Это позволяет удовлетворять требованиям связи между основным контроллером и верхним компьютером, при этом максимально уменьшая объём передаваемых данных для повышения скорости передачи.| Byte0 | Byte1 | Byte2 | Byte3 | Byte4 | Byte5 | Byte6 | Byte7 |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| 0xAA | CRC_8 | Yaw_data | Yaw_data | Yaw_data | Yaw_data | Pitch_data | Pitch_data |
| Byte8 | Byte9 | Byte10 | Byte11 | Byte12 | Byte13 | Byte14 | Byte15 |
| Pitch_data | Pitch_data | Dist_data | Dist_data | Dist_data | Dist_data | Target_num | Fire_cmd |

> * 0xAA — начало фрейма
> * Yaw_data: 8-битный символ — значение yaw, полученное из системы распознавания
> * Pitch_data: 8-битный символ — значение pitch, полученное из системы распознавания
> * (Изменено для передачи координат в системе  Yö 360°, X умножается на 10 для хранения одной десятичной цифры, расстояние передается как число, также с точностью до мм, начало фрейма 0XAA)
> * Dist_data: 8-битный символ — расстояние до цели, полученное из системы распознавания
> * Target_num: 8-битный символ — номер приоритетной цели (первые три цифры от 0 до 8, кроме 6) (STM32 -> PC)
> * Выбор режима — последние пять цифр (0 — нет обработки, 1-8 для выбора режима, STM32 -> PC, 1 — автоматическая наводка, 2 — большой вентиль)
> * Fire_cmd: 8-битный символ — сигнал для стрельбы (в случае, если система распознавания определяет, что камера направлена на цель в допустимом диапазоне ошибки; 0 — не стрелять, 1 — стрелять)

---
## 7. Настройка и отладка
### Установка рабочего окружения
1. Установка Qt (и Qt Creator)
2. Установка и конфигурация библиотеки OpenCV
3. Установка и конфигурация драйвера камеры Daheng### Отладка кода
1. Открыть JLURoboVision.pro в Qt Creator (или выполнить команду `make` в корневой директории)
2. Проверьте и измените пути к файлам `camera_params.xml` и `123svm.xml`
3. Скомпилировать и запустить### Отдельная модульная отладка
Для справки можно использовать следующий пример кода:

[JLUVision_Demos](https://gitee.com/qunshanhe/JLUVision_Demos) — различные демонстрационные программы
[Armor_Demo](https://gitee.com/qunshanhe/JLUVision_Demos/tree/master/Armor_Demo) — демонстрационная программа для распознавания броневых плит, работает на Linux (.pro) / Windows (.sln)
[AngleSolver_Armor_GxCamera](https://gitee.com/qunshanhe/JLUVision_Demos/tree/master/Anglesolver_Armor_GxCamera_Demo) представляет собой демонстрационную программу для работы с камерой Gx, распознаванием бронированной панели и вычислением углов, требует подключения камеры Gx для запуска в операционной системе Linux.

### Инструменты отладки
Код также содержит набор пользовательских функций для отладки, который позволяет визуализировать информацию о распознавании лент светоотражающих, бронированной панели и вычислении углов, а также контролировать некоторые параметры распознавания с помощью клавиатуры, что облегчает отладку и оптимизацию кода.````
// Параметры отладки для вывода информации о бронированной панели
// параметры:
//			1. showSrcImg_ON,		  показывать ли исходное изображение
//			2. bool showSrcBinary_ON,  показывать ли двоичное изображение
//			3. bool showLights_ON,	  показывать ли изображение лент светоотражающих
//			4. bool showArmors_ON,	  показывать ли изображение бронированной панели
//			5. bool textLights_ON,	  выводить ли информацию о лентах светоотражающих
//			6. bool textArmors_ON,	  выводить ли информацию о бронированной панели
//			7. bool textScores_ON,	  выводить ли информацию о точности попадания
//							   1   2   3   4   5   6   7
detector.showDebugInfo(0, 0, 0, 1, 0, 0, 0);

// Параметры отладки для вывода информации о расчетах углов // параметры: // 1. showCurrentResult, показывать ли текущий результат расчета // 2. bool showTVec, показывать ли координаты цели // 3. bool showP4P, показывать ли результаты расчета алгоритма P4P // 4. bool showPinHole, показывать ли результаты расчета алгоритма PinHole // 5. bool showCompensation, выводить ли информацию о компенсации // 6. bool showCameraParams, выводить ли параметры камеры // 1 2 3 4 5 6 angleSolver.showDebugInfo(1, 1, 1, 1, 1, 0);


---
## 8. Заключение и перспективы
### Заключение  
Настоящий код реализует два основных модуля: распознавание бронированной панели и распознавание "большого ветряного колеса". В сочетании с модулем расчета углов эти данные используются для управления поворачивающим устройством, после чего информация передается через последовательный порт на нижний уровень системы.
Модуль распознавания бронированной панели и "большого ветряного колеса" работает хорошо, его производительность и частота кадров удовлетворяют требованиям соревнований; модуль расчета углов был спроектирован таким образом, чтобы повысить точность и надежность.
При этом весь код был упакован, обеспечивая высокую переносимость.### Основные особенности  
1.  Обширные возможности отладки и визуализации данных  
Код оснащен множеством функций для отладки, позволяющих визуализировать результаты выполнения программы и параметры вычислений в реальном времени через изображения или консоль, что облегчает отладку и оптимизацию кода.
2.  Глубокая обработка изображений  
В предобработке использовался метод вычитания каналов для извлечения цвета, однако этот метод требует вызова функций `split` и `thresh`, что увеличивает время выполнения. После анализа особенностей алгоритма мы решили использовать указатель для прямого прохода по данным изображения, что значительно повысило скорость выполнения этого шага.```markdown
// Указатель проходит через все данные `srcImg`, аналогично разделению канала BGR
// Данные `Mat` BGR BGR BGR BGR
uchar* pdata = (uchar*)srcImg.data;
uchar* qdata = (uchar*)srcImg_binary.data;
int srcData = srcImg.rows * srcImg.cols;
if (enemyColor == RED)
{
    for (int i = 0; i < srcData; i++)
    {
        if (*(pdata + 2) - *pdata > armorParam.color_threshold)
            *qdata = 255;
        pdata += 3;
        qdata++;
    }
}
else if (enemyColor == BLUE)
{
    for (int i = 0; i < srcData; i++)
    {
        if (*pdata - *(pdata + 2) > armorParam.color_threshold)
            *qdata = 255;
        pdata += 3;
        qdata++;
    }
}
```

### Выбор целевой бронелистой панели с учётом весовых коэффициентов

Выбор целевой бронелистой панели осуществляется путём объединения указаний оператора относительно типа войск и реальных характеристик бронелистой панели (вектор перемещения от ствола оружия, площадь поражения) для взвешенного суммирования. В результате выбирается бронелистающая панель с максимальной степенью поражения.```markdown
/**
 *@brief: Сравнение a_armor с b_armor по расстоянию до последней бронелистой панели (если она существует, а не по умолчанию) и их площади и номеру бронелистой панели
 *		  Сравнение степени поражения между a_armor и b_armor, чтобы определить, является ли a_armor более подходящим для поражения (через совпадение номера бронелистой панели с номером цели, расстояние между бронелистой панелью и последней бронелистой панелью, а также размер площади поражения)
 */
bool armorCompare(const ArmorBox& a_armor, const ArmorBox& b_armor, const ArmorBox& lastArmor, const int& targetNum)
{
    float a_score = 0;  // степень поражения a_armor
    float b_score = 0;  // степень поражения b_armor
    a_score += a_armor.armorRect.area(); //оценка площади a_armor
    b_score += b_armor.armorRect.area(); //оценка площади b_armor
    // установка оценки номера бронелистой панели для a и b
    setNumScore(a_armor.armorNum, targetNum, a_score);
    setNumScore(b_armor.armorNum, targetNum, b_score);
    if (lastArmor.armorNum != 0) {  // если armorRect последней бронелистой панели не является стандартной, то есть в предыдущем кадре была цельная бронелистающая панель
```

```markdown
        float a_удаление = getPointsDistance(a_броня.center, lastБроня.center); //расстояние до последней брони (если существует)
        float b_удаление = getPointsDistance(b_броня.center, lastБроня.center); //расстояние до последней брони (если существует)
        a_оценка -= a_удаление * 2;
        b_оценка -= b_удаление * 2;
    }
    return a_оценка > b_оценка; //определение того, что a лучше b по их оценкам
}
```

### Перспективы
1. Прогнозирование с помощью фильтра Калмана
2. 
```Распознавание с использованием глубокого обучения
3. Улучшение производительности вычислительной платформы
```

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

**Визуальный код для роботов Robomaster в соревнованиях 2020 года от команды TARS-GO из Цзилиньского университета** *Текст запроса содержит фрагменты кода, которые невозможно перевести без контекста.* Развернуть Свернуть
MIT
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/qunshanhe-JLURoboVision.git
git@api.gitlife.ru:oschina-mirror/qunshanhe-JLURoboVision.git
oschina-mirror
qunshanhe-JLURoboVision
qunshanhe-JLURoboVision
master