diff --git a/app/main/reports/README.md b/app/main/reports/README.md
index 18b4b5d3..d54bd128 100644
--- a/app/main/reports/README.md
+++ b/app/main/reports/README.md
@@ -1,6 +1,6 @@
# Запуск и тестирование
-Пререквизиты: `argparse`, `python-docx`, `docx2python`, `re`, `subprocess`. Для парсинга `.doc`-файлов потребуется
+Пререквизиты: `argparse`, `python-docx`, `docx2python`, `re`, `subprocess`, `markdown`. Для парсинга `.doc`-файлов потребуется
LibreOffice.
Здесь и далее считается, что корневая директория репозитория добавлена в `PYTHONPATH`.
@@ -65,9 +65,6 @@ Proof-of-concept парсинг файлов `.docx` с выводом стру
```bash
$ python3 -m app.main.mse22.pdf_document text_from_pages --filename path_to_file
```
-## `MD`
-
-Парсинг файлов `.md` с выводом структуры файла в текстовом виде в stdout.
```bash
$ python3 -m app.main.reports.md_uploader md_parser --mdfile path_to_md_file
diff --git a/app/main/reports/md_uploader/md_uploader.py b/app/main/reports/md_uploader/md_uploader.py
index 25346ffc..e3de1e51 100644
--- a/app/main/reports/md_uploader/md_uploader.py
+++ b/app/main/reports/md_uploader/md_uploader.py
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
'''Available checks for md-file:
pack "BaseReportCriterionPackMd"
@@ -82,10 +83,27 @@ def __init__(self, path_to_md_file):
self.inline_shapes = []
def upload(self):
+=======
+import markdown #installation: pip install markdown
+import re
+
+class MdUpload:
+ def __init__(self, path_to_md_file):
+ self.path_to_md_file = path_to_md_file
+ self.headers = []
+ self.chapters = []
+ self.paragraphs = []
+ self.html_text = ''
+ self.tables = []
+ self.chapter_with_text = []
+
+ def read_md_file(self):
+>>>>>>> master
with open(self.path_to_md_file, "r", encoding="utf-8") as f:
md_text = f.read()
return md_text
+<<<<<<< HEAD
def parse(self, md_text):
self.html_text = markdown.markdown(md_text)
self.paragraphs = self.make_paragraphs(self.html_text)
@@ -201,6 +219,29 @@ def find_images(self):
total_height += width
self.inline_shapes.append((width, height))
return self.inline_shapes
+=======
+ def get_html_from_md(self, md_text):
+ self.html_text = markdown.markdown(md_text)
+ self.paragraphs = self.html_text.split('\n')
+
+ def get_headers(self):
+ header_regex = "
(.*?)<\/h1>"
+ self.headers = re.findall(header_regex, self.html_text)
+
+ def get_chapters(self):
+ chapter_regex = "(.*?)<\/h2>"
+ self.chapters = re.findall(chapter_regex, self.html_text)
+
+ def get_chapter_with_text(self):
+ text = self.html_text
+ chapter_name = ''
+ for chapter in self.chapters:
+ self.split_chapter = text.split("" + chapter + "
")
+ self.chapter_with_text.append(chapter_name + self.split_chapter[-2])
+ chapter_name = chapter
+ text = self.split_chapter[-1]
+ self.chapter_with_text.append(chapter_name + text)
+>>>>>>> master
def get_tables_size(self):
count_table_line = 0
@@ -210,6 +251,7 @@ def get_tables_size(self):
count_table_line +=1
return round(count_table_line/count_paragraph, 4)
+<<<<<<< HEAD
def find_literature_vkr(self, work_type):
if not self.literature_header:
for header in self.make_chapters(work_type):
@@ -231,7 +273,21 @@ def parse_md_file(self):
self.find_literature_vkr(work_type="VKR")
return f"Заголовки:\n{self.headers_main}\n\nГлавы\n{self.chapters}\n\nИзображения:\n\n{self.inline_shapes}"
+=======
+ def parse_md_file(self):
+ md_text = self.read_md_file()
+ self.get_html_from_md(md_text)
+ self.get_headers()
+ self.get_chapters()
+ self.get_chapter_with_text()
+ self.get_tables_size()
+ return f"Заголовки:\n{self.headers}\n\nГлавы:\n{self.chapters}\n\nГлавы с текстом:\n{self.chapter_with_text}\n\nДоля таблиц в тексте:\n{self.get_tables_size()}"
+>>>>>>> master
def main(args):
md_file = MdUpload(args.mdfile)
print(md_file.parse_md_file())
+<<<<<<< HEAD
+=======
+
+>>>>>>> master
diff --git a/app/servants/pre_luncher.py b/app/servants/pre_luncher.py
index 31164022..9e1b3331 100644
--- a/app/servants/pre_luncher.py
+++ b/app/servants/pre_luncher.py
@@ -3,6 +3,7 @@
from db.db_methods import add_user, get_user, get_client, edit_user, save_criteria_pack
from main.check_packs.pack_config import BASE_PACKS, DEFAULT_REPORT_TYPE_INFO
+
from pymongo.errors import ConnectionFailure
from server import ALLOWED_EXTENSIONS
@@ -40,6 +41,7 @@ def init(app, debug):
user.criteria = BASE_PACKS[file_type].name
user.formats = list(ALLOWED_EXTENSIONS.get(file_type))
user.two_files = True
+
edit_user(user)
logger.info(f"Создан администратор по умолчанию: логин: {user.username}, пароль уточняйте у разработчика")
diff --git a/playground/md_parser/example.md b/playground/md_parser/example.md
new file mode 100644
index 00000000..d243a05d
--- /dev/null
+++ b/playground/md_parser/example.md
@@ -0,0 +1,158 @@
+# Описание бенчмарка для сравнения влияния алгоритмов выявления особых RGB-точек в изображении на точность локализации мобильного робота.
+
+Ключевые слова: алгоритмы выявления особых RGB-точек(признаков), визуальная одометрия, бенчмарк.
+
+## Аннотация
+
+В статье представлен обзор существующих алгоритмов выявлениях особых RGB-точек(признаков). Сформированы требования к бенчмарку для сравнения влияния алгоритмов выявления признаков на точность локализации мобильного робота. Кратко изложены этапы вычисления местоположения робота методом визуальной одометрии, которые будут использоваться в бенчмарке. Приведены инструменты для реализации бенчмарка.
+
+## Введение
+
+ С быстрым развитием области мобильной робототехники, возрастает необходимость в точной локализации роботов. Одним из методов отслеживания движения является визуальная одометрия, которая использует поток изображений с камеры робота. Выявление и описание признаков в изображении является одним из первых и важнейших этапов визуальной одометрии [2]. Необходимо провести исследования влияния алгоритмов выявления признаков в изображении на точность локализации мобильного робота.
+
+Целью данной работы является разработать архитектуру бенчмарка для исследования алгоритмов выявления особых RGB-точек(признаков) изображений на точность локализации мобильного робота.
+
+Для достижения цели были поставлены следующие задачи:
+
+1. Изучить существующие алгоритмы выявления признаков.
+2. Определить метод сравнения алгоритмов выявления признаков.
+3. Описать способ реализации бенчмарка алгоритмов выявления признаков.
+
+Объектом исследования являются алгоритмы выявления признаков.
+
+Предметом исследования являются влияния алгоритмов выявления признаков на точность локализации мобильного робота.
+
+## Обзор предметной области
+
+### Принцип отбора аналогов
+
+Для создания бенчмарка необходимо провести обзор существующих алгоритмов выявления признаков. Для поиска алгоритмов выявления признаков использовался следующий запрос: feature detection and description algorithms.
+
+#### SIFT
+
+Один из популярнейших алгоритмов выявления и описания признаков в изображении, предложенный в 2004 году[3]. Состоит из нескольких этапов:
+
+1. **Поиск особых точек.** Для достижения инвариантности относительно масштаба строятся пирамиды гауссианов. Гауссиан - это изображение после применения гауссового фильтра[4]. Далее из разностей соседних гауссианов в пирамиде получают пирамиду разности гауссиан. После ищутся локальные экстремумы в пирамиде разностей гауссиан.
+2. **Локализация ключевых точек.** Используется разложение масштабного пространства в ряд Тейлора для получения более точных значений экстремумов.
+3. **Поиск ориентации ключевых точек**. Для инвариантности к вращению ключевым точкам назначается ориентация. Направление ключевой точки находиться исходя из её окрестности - для соседних точек вычисляется величина и направление градиента.
+4. **Описание ключевой точки**. Описание (дескриптор) состоит из окрестности 16x16 вокруг ключевой точки. Также принимаются некоторые меры для обеспечения устойчивости к освещению, вращению и т.п.
+
+#### SURF
+
+Модификация SIFT, нацеленная на ускорение вычислений[5]. Вместо разности гауссианов используется коробчатый фильтр (Box Filter), уменьшающий количество вычислений и позволяющий выполнять их параллельно для разных масштабов. Также для обнаружения особых точек используется детерминант матрицы Гессе, что дополнительно снижает траты на вычисления. За счёт улучшений SURF требует гораздо меньше времени на вычисления, чем SIFT, но при этом немного теряет в устойчивости перед изменением освещения и сменой точки обзора.
+
+#### KAZE
+
+Метод выявления и описания признаков, работающий в нелинейном масштабном пространстве [6]. Построение нелинейного масштабного пространства происходит с помощью техник AOS[7]. Далее обнаруживаются максимумы с помощью детерминанта матрицы Гессе, нормализованный по масштабу. На последнем шаге вычисляется ориентация ключевых точек (как в SURF) и получают описание(дескриптор) размером 24x24. Алгоритм KAZE уменьшает шум и имеет более высокую точность (чем SIFT и SURF) за счёт небольшого увеличения вычислений.
+
+#### BRISK
+
+Был предложен в 2011 году как альтернатива SURF с более низкими вычислительными затратами[8]. Алгоритм основан на алгоритме обнаружения углов AGAST [9] (который является модификацией FAST[10]). Описание (дескриптор) состоит из бинарной битовой строки, соответствующей расстоянию Хэмминга, что позволяет ускорить вычисления.
+
+#### ORB
+
+Алгоритм основан на модификациях алгоритма выявления особых точек FAST[10] и алгоритма описания признаков BRIEF[11] и предложен в 2011 году[12]. Вычисляются особые точки с помощью алгоритма FAST, затем точки фильтруются алгоритмом обнаружения углов Харриса[13]. Далее вычисляется ориентация ключевой точки. После используется модифицированный алгоритм BRIEF - точки, предназначенные для сравнения, поворачиваются на угол ориентации ключевой точки (таким образом лишая недостатка BRIEF в неустойчивости к вращениям).
+
+### Сравнение аналогов
+
+Были выбраны следующие основные параметры сравнения:
+
+1. Повторяемость - среднее количество признаков, обнаруженных на изображениях после применения различных геометрических и фотометрических преобразований. В данном обзоре рассмотрены вращение и масштабирование. Высокое значение данного параметра позволяет говорить о том, что найденные признаки будут обнаружены и на других изображениях.
+2. Точность при сопоставлении изображений. Исключение выбросов увеличит точность локализации мобильного робота.
+3. Время выявления и описания признаков. Вычислительно эффективные алгоритмы позволяют обработать большее количество данных.
+
+В табл.1 представлено сравнение алгоритмов по данным из статьи[14].
+
+Таблица 1 - Сравнительный анализ алгоритмов по количественным критериям
+
+| Алгоритмы | Повторяемость, % | Повторяемость, % | Повторяемость, % | Повторяемость, % | Повторяемость, % | Процент ошибки, % | Процент ошибки, % | Процент ошибки, % | Процент ошибки, % | Процент ошибки, % | Среднее время выявления и описания признаков, c |
+| --------- | ---------------- | ---------------- | ---------------- | ---------------- | ---------------- | ----------------- | ----------------- | ----------------- | ----------------- | ----------------- | ----------------------------------------------- |
+| | Масштаб | Масштаб | Масштаб | Вращение | Вращение | Масштаб | Масштаб | Масштаб | Вращение | Вращение | |
+| | 50% | 150% | 200% | 30° | 60° | 50% | 150% | 200% | 30° | 60° | |
+| SIFT | 78 | 80 | 82 | 78 | 78 | 0 | 0 | 0 | 0 | 0 | 0.198 |
+| SURF | 81 | 77 | 83 | 73 | 72 | 0.08 | 0.18 | 0.22 | 0 | 0.01 | 0.138 |
+| KAZE | 70 | 70 | 73 | 88 | 88 | 0.17 | 0 | 0.3 | 0 | 0 | 0.242 |
+| BRISK | 81 | 83 | 85 | 82 | 84 | 0 | 0 | 0.2 | 0.01 | 0.01 | 0.045 |
+| ORB | 85 | 83 | 66 | 89 | 89 | 0.2 | 0.1 | 0.5 | 0.01 | 0.01 | 0.01 |
+
+
+
+В среднем повторяемость выше у BRISK и ORB, но при этом у ORB сильно снижается значения при увеличении масштаба более чем на 150%. У KAZE высокие значения для вращений. Самым точным алгоритмом является SIFT. ORB имеет наибольший процент ошибок. Самым вычислительно трудоёмким является KAZE, самым эффективным ORB, за ним по эффективности идёт BRISK.
+
+## Выбор метода решения
+
+Бенчмарк должен предоставлять выбор различных алгоритмов выявления и описания признаков. Пользователю предоставляется возможность загрузить набор изображений и файлы с эталонными значениям и местоположения. Пользователь может узнать промежуточные значения работы бенчмарка, например, количество найденных признаков. По набору изображений будут найдены признаки и их описание, далее на основе этих признаков бенчмарк будет определять текущее местоположение мобильного робота.
+
+Исходя из обзора алгоритмов, бенчмарк должен:
+
+1. Определять точность локализации мобильного робота. Бенчмарк выдаёт результат в виде графиков, по которым можно отследить ошибку определения местоположения.
+2. Предоставлять возможность применять геометрические и фотометрические преобразования над изображениями для оценивания инвариантности алгоритмов. Например, к части изображений может быть применён эффект размытия или добавлен шум.
+3. Рассчитывать время выполнения алгоритмов. По окончанию работы бенчмарк выдаёт общее время на расчёт определения местоположения.
+
+## Описание метода решения
+
+Для исследования влияния алгоритмов выявления признаков на точность локализации мобильного робота, необходимо воспользоваться методом визуальной одометрии и рассчитать местоположение робота. Метод визуальной одометрии, который будет реализован в бенчмарке, основывается на статьях [1] и [2]. Ниже приведены подробности данного метода:
+
+1. **Выявление и описание признаков**. На данном этапе работает один из алгоритмов, описанных в разделе "Cравнение аналогов". Для повышения точности дальнейших расчётов признаки должны быть равномерно распределены по всему изображению. Для этого изображения разбивают на сетку, в каждом фрагменте ищется определенное количество признаков.
+2. **Отслеживание признаков**. После обнаружения признаков на первом изображении, необходимо найти эти признаки на остальных изображениях, таким образом отслеживая перемещение признаков между изображениями. Одним из быстрых и эффективных методов отслеживания является трекер Канаде-Лукаса-Томаси[15].
+3. **Расчёт движения**. На основе информации о том, как менялись признаки на изображении, можно рассчитать движение самого мобильного робота. Для расчёта движения используется существенная матрица, описывающая геометрическую связь между двумя изображениями[16]. Из существенной матрицы можно получить значения вращение и перемещение между изображениями. На основании данной информации можно высчитать координаты перемещения.
+4. **Удаление выбросов**. Обычно в изображениях содержится множество выбросов, которые не учитываются алгоритмами выявления и описания признаков. С удалением выбросов хорошо справляется алгоритм RANSAC[17]. В данном случае для алгоритма RANSAC моделью является существенная матрица, а параметрами - признаки на изображении.
+5. **Оптимизация**. При расчёте местоположения со временем будет накапливаться ошибка("scale drift") [18]. Одной из оптимизаций является обнаружение циклов[19]. Для этого возвращаются к предыдущим признакам, которые давно не появлялись на изображениях, и сравнивают с текущими. Если признаки совпали, применяют глобальную оптимизацию и исправляют траекторию движения робота.
+
+В качестве результата выполнения приведенного выше метода, будут доступны график с вычисленной траекторией и настоящей, и график, показывающий накопления ошибки с течением времени. По данным графиков можно будет оценить степень влияния алгоритмов выявления признаков на точность локализации мобильного робота. Также отдельно будет выводиться время выполнения алгоритмов для оценки их эффективности.
+
+В качестве основного инструмента реализации бенчмарка была выбрана библиотека OpenCV[20]. В неё включены все приведенные в обзоре алгоритмы выявления и описания признаков, а так же в ней есть множество функций по обработке изображений, которые будут необходимы для вычисления местоположения мобильного робота. В качестве языка программирования был выбран Python, из-за простого синтаксиса языка.
+
+Бенчмарк будет представлять из себя консольное приложение. Пользователь может выбрать один из предложенных алгоритмов выявления и описания признаков и выбрать папку с набором изображений (если у пользователя нет набора изображений, программа может использовать свой внутренний). Далее пользователь может выбрать, будет ли данные изображения подвергаться различными преобразованиям (например, добавления в изображение размытия или шума). После начинает работу алгоритм, вычисляющий местоположение робота. По завершению бенчмарк выведет количество времени, потраченное на вычисления и создаст два файла с графиками.
+
+## Заключение
+
+В ходе работы был проведён обзор существующих алгоритмов выявления признаков(особых RGB-точек), в ходе которого были выявлены основные требования к бенчмарку. Был представлен метод сравнения алгоритмов выявления признаков - непосредственное вычисление методом визуальной одометрии местоположение робота и дальнейшее сравнение результатов для различных алгоритмов выявления признаков. Также были предложены инструменты для реализации бенчмарка и описан способ реализации бенчмарка - консольное приложение, принимающие на вход набор изображение и выдающее график с траекторией мобильного робота.
+
+В дальнейшем следует расширять возможности бенчмарка: добавить больше алгоритмов выявления признаков и увеличить количество различных преобразований над набором изображений. Также в дальнейших работах можно расширить существующее решение, чтобы исследовать влияние алгоритмов вычисления признаков на SLAM[21].
+
+
+
+## Список литературы
+
+[1] Fraundorfer, Friedrich ; Scaramuzza, Davide. Visual Odometry [Tutorial] // IEEE Robotics & Automation Magazine 18, 2011.
+
+[2] Fraundorfer, Friedrich ; Scaramuzza, Davide. Visual Odometry: Part II - Matching, Robustness, and Applications // IEEE Robotics & Automation Magazine 19, 2012.
+
+[3]David G. Lowe. Distinctive Image Features from Scale-Invariant Keypoints // International Journal of Computer Vision 60, 2004.
+
+[4]Mark Nixon, Alberto Aguado. Feature Extraction and Image Processing for Computer Vision, 2002, C.86-88.
+
+[5]Herbert Bay, Tinne Tuytelaars, Luc Van Gool. SURF: Speeded up robust features // Proceedings of the 9th European conference on Computer Vision - Volume Part I, 2006.
+
+[6]Pablo Fernández Alcantarilla. KAZE Features // European Conference on Computer Vision (ECCV), 2012.
+
+[7]J. Weickert; B.M.T.H. Romeny; M.A. Viergever. Efficient and reliable schemes for nonlinear diffusion filtering // IEEE, 1998.
+
+[8]Stefan Leutenegger,Margarita Chli, Roland Y.Siegwart. BRISK: Binary Robust Invariant Scalable Keypoints // IEEE International Conference on Computer Vision, 2011.
+
+[9]E. Mair,G. D. Hager,D. Burschka, M.Suppa, and G. Hirzinger. Adaptiveand generic corner detection based on the accelerated segment test // European Conference on Computer Vision, 2010.
+
+[10]Edward Rosten and Tom Drummond. Machine learning for high-speed corner detection // 9th European Conference on Computer Vision, 2006.
+
+[11]Michael Calonder, Vincent Lepetit, Christoph Strecha, Pascal Fua. "BRIEF: Binary Robust Independent Elementary Features" // 11th European Conference on Computer Vision (ECCV), 2010.
+
+[12]Ethan Rublee. ORB: an efficient alternative to SIFT or SURF // IEEE International Conference on Computer Vision, 2011.
+
+[13]Chris Harris, Mike Stephens. A Combined Corner and Edge Detector // Alvey Vision Conference, 1988.
+
+[14]Shaharyar Ahmed Khan Tareen, Zahra Saleem. A comparative analysis of SIFT, SURF, KAZE, AKAZE, ORB, and BRISK // 2018 International Conference on Computing, Mathematics and Engineering Technologies, 2018.
+
+[15]C. Tomasi and J. Shi, "Good features to track" // *Proc. CVPR*, 1994.
+
+[16]H. C. Longuet-Higgins. A computer algorithm for reconstructing a scene from two projections. // Nature, 293:133–135, 1981.
+
+[17]Martin A. Fischler and Robert C. Bolles. Random Sample Consensus: A Paradigm for Model Fitting with Applications to Image Analysis and Automated Cartography // Comm. Of the ACM, 1981.
+
+[18]L. Matthies and S. Shafer, "Error modeling in stereo navigation" // IEEE J. Robot. Automat., vol. 3, no. 3, 1987.
+
+[19] T. Bailey and H. Durrant-Whyte, "Simultaneous localisation and mapping (SLAM): Part II. State of the art" // IEEE Robot. Automat. Mag., vol. 13, no. 3, 2006.
+
+[20] OpenCV [Электронный ресурс]. URL: https://opencv.org/ (дата обращения 19.12.2022).
+
+[21] Alif Ridzuan Khairuddin, Mohamad Shukor Talib, Habibollah Haron. Review on simultaneous localization and mapping (SLAM) // IEEE International Conference on Control System, Computing and Engineering, 2015.
\ No newline at end of file
diff --git a/playground/md_parser/md_parser.py b/playground/md_parser/md_parser.py
new file mode 100644
index 00000000..0c6a1b95
--- /dev/null
+++ b/playground/md_parser/md_parser.py
@@ -0,0 +1,61 @@
+import markdown #installation: pip install markdown
+import re
+
+class MdParser:
+ def __init__(self, path_to_md_file):
+ self.path_to_md_file = path_to_md_file
+ self.headers = []
+ self.chapters = []
+ self.paragraphs = []
+ self.html_text = ''
+ self.tables = []
+ self.chapter_with_text = []
+ # self.literature_header = ''
+
+ def read_md_file(self):
+ with open(self.path_to_md_file, "r", encoding="utf-8") as f:
+ md_text = f.read()
+ return md_text
+
+ def get_html_from_md(self, md_text):
+ self.html_text = markdown.markdown(md_text)
+ self.paragraphs = self.html_text.split('\n')
+
+ def get_headers(self):
+ header_regex = "(.*?)<\/h1>"
+ self.headers = re.findall(header_regex, self.html_text)
+
+ def get_chapters(self):
+ chapter_regex = "(.*?)<\/h2>"
+ self.chapters = re.findall(chapter_regex, self.html_text)
+
+ def get_chapter_with_text(self):
+ text = self.html_text
+ chapter_name = ''
+ for chapter in self.chapters:
+ self.split_chapter = text.split("" + chapter + "
")
+ self.chapter_with_text.append(chapter_name + self.split_chapter[-2])
+ chapter_name = chapter
+ text = self.split_chapter[-1]
+ self.chapter_with_text.append(chapter_name + text)
+
+ def get_tables_size(self):
+ count_table_line = 0
+ count_paragraph = len(self.paragraphs)
+ for line in self.paragraphs:
+ if "|" in line:
+ count_table_line +=1
+ return round(count_table_line/count_paragraph, 4)
+
+ def parse_md_file(self):
+ md_text = self.read_md_file()
+ self.get_html_from_md(md_text)
+ self.get_headers()
+ self.get_chapters()
+ self.get_chapter_with_text()
+ self.get_tables_size()
+ return f"Заголовки:\n{self.headers}\n\nГлавы:\n{self.chapters}\n\nГлавы с текстом:\n{self.chapter_with_text}\n\nДоля таблиц в тексте:\n{self.get_tables_size()}"
+
+if __name__ == "__main__":
+ md_file = MdParser('playground/md_parser/example.md')
+ print(md_file.parse_md_file())
diff --git a/requirements.txt b/requirements.txt
index f29f2e0b..617a5755 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -27,5 +27,5 @@ pdfplumber==0.6.1
pytest~=7.1.2
filetype==1.2.0
language-tool-python==2.7.1
-markdown
md2pdf
+markdown==3.4.4