Время прочтения: 8 мин.

Введение

Модели машинного обучения компьютерного зрения являются крайне актуальной задачей в современном мире, поскольку компьютерные системы, способные “видеть”, могут применяться во многих областях жизни. Одной из самых популярных областей применения моделей компьютерного зрения является распознавание объектов на изображениях и видео. Это может быть полезным, к примеру, для систем видеонаблюдения, автоматической сортировки на производстве, диагностирования медицинских изображений. Кроме того, модели машинного обучения используются при создании дополненной и виртуальной реальностях. Они позволяют создавать интерактивные пользовательские интерфейсы, а также обеспечивать визуализацию информации на основе видео и изображений.

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

Как же создать такую модель?

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

Этапы создания модели машинного обучения

Новички в этой области скажут, что самый сложный этап – это обучение модели и конечно же ошибутся, на то они и новички. Любой датасаентист скажет, что самый сложный и трудоемкий этап – это сбор и подготовка данных. Зачастую, этот процесс занимает до 80 процентов времени. Для большой точности модели, необходимо не только собрать огромное количество изображений, но и правильно их разметить. Сбор и подготовка данных подразумевает выделение частей изображения и добавление текстовой метки при решении задач классификации и распознавания образов. Задача классификации позволяет по заданному изображению определить к классу с какой текстовой меткой можно отнести данное изображений. Задача распознавания образов, наоборот, по заданной метке класса пытается найти изображение или его фрагмент. Для решения подобных задач “вручную” можно использовать Paint. Он позволяет просматривать изображения и выписывать координаты пикселей, выделять объекты прямоугольниками и многоугольниками, сохранять измененные изображения.

Paint – как инструмент для разметки графических данных

Высокой производительности с помощью такого подхода не добиться, так как для работы моделей требуется большое количество размеченных данных для обучения. Для решения подобных задач существуют специальные программы, например, ImgLab, LabelImg.

ImgLab – веб-приложение, позволяет загружать директории изображений, добавлять прямоугольники, многоугольники, точки и окружности.

Интерфейс приложения ImgLab

Минусы — использование веб приложений недопустимо при работе с изображениями, не предназначенными для размещения в сети интернет.

LabelImg – кроссплатформенное приложение, реализован выбор директории с файлами, есть возможность выделять объекты прямоугольниками и добавлять метки к изображениям.

Пример интерфейса LabelImg

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

Таким образом актуальной задачей является повышение качества и скорости работ при подготовке разметки графических данных для задач машинного обучения при работе данными не предназначенными для размещения в сети Интернет.

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

  1. Обрабатывать последовательно изображения из выбранной директории.
  2. Выделять прямоугольники и многоугольники на выбранных изображениях.
  3. Добавлять текстовые нотации, или метки, к элементам изображения.

Создание приложения

Для разработки приложения с графическим интерфейсом я использую tkinter – библиотеку python, для создания кроссплатформенных приложений с графическим интерфейсом. Одной из основных причин актуальности Tkinter является то, что она входит в стандартную поставку Python, что позволяет каждому разработчику использовать ее.

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

Импортирую модуль os для работы с файловой системой компьютера:

def walk_by_directory (self, root_dir_path):
        for dirpath, dirnames, filenames in os.walk(root_dir_path):
            for file in filenames:
                if any([file.endswith(end) for end in ('jpg', 'jpeg', 'png', 'svg', 'bmp')]):
                    yield os.path.join(root_dir_path, dirpath, file)

Данная функция возвращает путь к файлу из выбранной директории при каждом обращении к ней, если он имеет расширение изображения.

Путь к директории получу с помощью функции filedialog. Она открывает диалоговое окно, в котором можно выбрать любую папку.

def choose_directory(self):
        directory = filedialog.askdirectory(title='Открыть папку')
        return directory

Реализую возможность перемещаться по списку файлов в обе стороны.

def get_next_image_handler(self):
        if len(self.list_path_files) > 0 and self.now_num_file_generator + 1 < len(self.list_path_files):
            self.now_num_file_generator += 1
            img_path = self.list_path_files[self.now_num_file_generator]
            self.selected_file = img_path
            self.load_image_handler()

Проверю номер файла в сформированном списке файлов директории, если еще есть файлы, то и добавляю следующее изображение на форму.

    def get_before_image_handler(self):
        if len(self.list_path_files) > 0 and self.now_num_file_generator > 0 and self.now_num_file_generator < len(self.list_path_files):
            self.now_num_file_generator -= 1
            self.selected_file = self.list_path_files[self.now_num_file_generator]
            self.load_image_handler()

Таким же образом работает и получение предыдущего изображения.

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

Для работы с изображениями на языке python используется библиотека Pillow. С помощью этой библиотеки можно открывать, обрабатывать и сохранять изображения. Отрисовывать изображение будем с помощью Canvas. Canvas можно представить как холст, на который я приклею изображение и поверх будем наносить фигуры, чтобы выделить объект.

С помощью данной функции добавлю изображение в графический интерфейс.

def draw_image(self, new_image_path):
        self.im = Image.open(new_image_path)
        self.im2 = ImageTk.PhotoImage(self.im)
        self.imgtag = self.canv.create_image(0,0,anchor="nw",image=self.im2)

Создам функции добавления фигур в поверх изображения.

Сначала нарисую прямоугольник. Прямоугольник можно описать диагональю, то есть двумя точками, не имеющими общей стороны в прямоугольнике.

def create_rectangle(self, x0, y0):
     if self.first_point is not None:
          self.canvas.canv.create_rectangle(self.first_point[0],
                                             self.first_point[1],
                                             x0,
                                             y0,
                                             width=3,
                                             outline="#004D40",
                                             tags="rectangle")
          self.first_point = None
     else:
          self.canvas.canv.delete("rectangle")
          self.first_point = x0, y0

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

Создание многоугольника происходит похожим образом.

def create_polygon(self, x0, y0):
     if len(self.points) > 0 and self.full_figure_flag:
          self.canvas.canv.delete("many_pointes")
          self.full_figure_flag = False
          self.points = []
     elif len(self.points) > 0:
          self.canvas.canv.create_line(*self.points[-1], x0, y0, 
                                        fill="red", width=2, tags="many_pointes")
     if len(self.points) > 2 and self.points[0][0] - x0 < 5 and self.points[0][1] - y0 < 5:
          self.full_figure_flag = True
     else:
          self.points.append((x0, y0))

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

Далее, проверяю создана ли фигура. Минимальная фигура – треугольник, поэтому проверяю, что в списке точек не менее двух записей. Буду считать фигуру законченной, если новая точка находится не дальше 5 пикселей по каждой оси от первой точки. Если новая точка не является финальной, то добавляю её координаты в список точек.

После добавления к изображению необходимых меток, необходимо сохранить результат.

    def save_res(self, file_path, label):
        row = {'path': file_path, 'label': label}
        self.data = self.data.append(row, ignore_index=True)

Я использую dataframe pandas для хранения табличных данных. Передаю путь к файлу и метки, которые были добавлены – координаты фигуры или текстовая метка.

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

Готовое приложение

Рассмотрю приложение поближе.

Выберу папку с данными.

Открытие папки с изображениями

Интерфейс приложения с открытой картинкой котика

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

Виджет выбора типа разметки данных

Выберу каждый способ и попробую разметить изображение.

При добавлении тестовой метки необходимо просто ввести данные в текстовое поле.

Добавление метки самолет к изображению

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

Выделение объекта прямоугольником

И обведу человечка многоугольником.

Выделение объекта многоугольником

Посмотрю, как выглядит файл с метками, после обработки папки с данными.

Таблица с метками данных

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

Заключение

Таким образом, я разработал легкое в использовании и расширяемое c помощью дополнительных модулей приложение, которое позволило повысить качество и скорость работ при подготовке разметки графических данных для задач машинного обучения при работе данными не предназначенными для размещения в сети Интернет.