Практический пример использования модели детекции изображений

от автора

Всем доброго дня. Совсем недавно я закончила продвинутый курс от Deep Learning School. Курс объемный, много свежей информации. Мне, как закончившей прикладную математику (нейросетки, генетика, fuzzy logics) было не сильно сложно, но мега-увлекательно за счет того, что ребята очень заинтересованные и рассказывали про свежие интересные модели, еще и на русском языке. Приятно видеть, что ИИ-сфера в нашей стране тоже не стоит на месте.

В качестве проекта на курсе мне хотелось сделать своими руками что-нибудь эдакое и полезное, и одновременно мега-современное, и вот что я придумала. У нас есть частный дом, там есть дворовые коты, которых надо кормить и в мое отсутствие. А так же есть еще птицы, кроты, чужие вездесущие собаки и другая живность, которых не стоит кормить, если не хотим, чтобы они у нас все поселились. Так вот, а что, если прикрутить модель детекции изображений к умной кормушке? Далее было бы здорово научиться использовать голосовые команды, например, на закрытие кормушки. Интересненько 🙂

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

Логика предполагалась следующая:

  1. Кот приходит к кормушке, его снимает рядом стоящая IP камера и отправляет снимок в телеграмм-бот.

  2. Бот обрабатывает сообщение, если это фото, то отправляет его в модель детекции.

  3. Модель детекции распознает кота или не распознает.

  4. Если это кот, бот посылает сигнал умной кормушке открыться и уведомляет об этом владельца.

  5. Умная кормушка открывается (и потом закрывается по таймеру, например).

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

  7. Команда из голосовой преобразуется в текст.

  8. Если будет обнаружена команда «закрыть кормушку», бот отправит сигнал на закрытие кормушки и сообщение владельцу, что принял команду.

Моделей детекции в современном мире тьма, в целях данной работы я выбрала Single Shot MultiBox Detector model for object detection (далее SSD-модель), разработанную компанией NVIDIA. Эта модель архитектуры глубоких нейронных сетей на основе модели ResNet-50 (победившей на соревнованиях ImageNet 2015 года), специально заточенная под детекцию изображений. Статья у нас практическая, не будем вдаваться в сложности архитектуры, только подчеркнем, что данная архитектура нейронных сетей стала практически стандартом качества и часто используется в задачах обнаружения объектов и сегментации изображений. SSD-модель заточена под быструю обработку и детекцию объектов даже в реальном времени, она обеспечивает высокую точность и быстроту обработки изображений.

1 часть: подготовка к работе

Писать будем на Python 3.11

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

pip install numpy scipy scikit-image matplotlib pip install pyTelegramBotAPI pip install SpeechRecognition pip install pydub pip install pydub[ffmpeg] pip install pydub opencv-python-headless opuslib 

Скачиваем и настраиваем выбранную модель: переводим ее в «боевой» режим. Расчеты следует производить на GPU или на CUDA, т.к. CPU будет считать очень долго и медленно. Я делала проект в Google Colab GPU

import torch precision = 'fp32' ssd_model = torch.hub.load('NVIDIA/DeepLearningExamples:torchhub',                             'nvidia_ssd', model_math=precision) utils = torch.hub.load('NVIDIA/DeepLearningExamples:torchhub',                         'nvidia_ssd_processing_utils') ssd_model.to('cuda') ssd_model.eval()

Монтируем google disk, на котором будем хранить все материалы

from google.colab import drive drive.mount('/content/drive') torch.save(ssd_model.state_dict(), 'ssd_model.pth')

Подгружаем необходимые библиотеки

import telebot import cv2 import torch import torch.nn as nn import torch.nn.functional as F import numpy as np  from matplotlib import pyplot as plt import matplotlib.patches as patches  import os import speech_recognition as sr  from pydub import AudioSegment import subprocess  import time

2 часть: реализация логики

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

def filter(uri):     # Инициализация флага обнаружения объекта "cat"     is_detected_cat = 0          # Подготовка входных данных     inputs = [utils.prepare_input(uri)]          # Подготовка тензора для модели с учетом точности 'fp16'     tensor = utils.prepare_tensor(inputs, precision == 'fp16')      # Выполнение обнаружения объектов с использованием SSD-модели     with torch.no_grad():         detections_batch = ssd_model(tensor)      # Декодирование результатов обнаружения     results_per_input = utils.decode_results(detections_batch)          # Выбор лучших результатов с пороговой уверенностью 0.20     best_results_per_input = [utils.pick_best(results, 0.20) for results in results_per_input]          # Получение словаря с соответствием классов меткам     classes_to_labels = utils.get_coco_object_dictionary()      # Итерация по изображениям с лучшими результатами     for image_idx in range(len(best_results_per_input)):         # Создание графика для визуализации результатов         fig, ax = plt.subplots(1)                  # Отображение оригинального изображения         image = inputs[image_idx] / 2 + 0.5         ax.imshow(image)                  # Отображение прямоугольников вокруг обнаруженных объектов и меток с уверенностью         bboxes, classes, confidences = best_results_per_input[image_idx]         for idx in range(len(bboxes)):             left, bot, right, top = bboxes[idx]             x, y, w, h = [val * 300 for val in [left, bot, right - left, top - bot]]             rect = patches.Rectangle((x, y), w, h, linewidth=1, edgecolor='r', facecolor='none')             ax.add_patch(rect)                          # Проверка, является ли обнаруженный объект классом "cat"             class_cat = classes_to_labels[classes[idx] - 1]             if (class_cat == 'cat'):                 is_detected_cat = 1                          # Вывод метки класса и уверенности             ax.text(x, y, "{} {:.0f}%".format(classes_to_labels[classes[idx] - 1], confidences[idx]*100), bbox=dict(facecolor='white', alpha=0.5))         # Сохранение отфильтрованного изображения     plt.savefig("filtered_image.jpg")          # Возвращение флага обнаружения объекта "cat"     return is_detected_cat 

3 часть: создание телеграмм-бота

Бота создаем через @BotFather, в целях безопасности отдельно в файле сохраняем токен.

Пишем логику бота, наш бот будет уметь:

Здороваться

@bot.message_handler(commands=['start']) def start_message(message):     bot.send_message(message.chat.id, 'Привет! Пожалуйста, загрузи картинку.') 

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

Посылать сигнал на открытие кормушки при обнаружении кота

@bot.message_handler(content_types=['photo']) def process_image(message):      # Получаем информацию о картинке     file_id = message.photo[-1].file_id     file_info = bot.get_file(file_id)     file_path = file_info.file_path      # Скачиваем картинку     downloaded_file = bot.download_file(file_path)      # Сохраняем картинку на диск     with open('image.jpg', 'wb') as f:         f.write(downloaded_file)      is_detected_cat = filter("image.jpg")      # Отправляем пользователю преобразованное изображение     with open('filtered_image.jpg', 'rb') as f:         bot.send_photo(message.chat.id, f)      if is_detected_cat == True:         bot.reply_to(message, "Пришел твой кот. Кормушка открыта") 

Обрабатывать команды пользователя в виде голосовых сообщений, в нашем примере будет реагировать только на одну команду «закрой кормушку». Код ниже наверняка можно оптимизировать.

@bot.message_handler(content_types=['voice']) def process_voice_message(message):     # Получаем информацию о голосовом сообщении     file_id = message.voice.file_id     file_info = bot.get_file(file_id)     file_path = file_info.file_path      # Скачиваем голосовое сообщение     downloaded_file = bot.download_file(file_path)      # Сохраняем голосовое сообщение на диск     voice_file_path = 'voice_message.ogg'     with open(voice_file_path, 'wb') as f:         f.write(downloaded_file)      # Преобразование голосового сообщения в текст     input_file = 'voice_message.ogg'     audio = AudioSegment.from_file(input_file, format='ogg')      # Конвертация в формат WAV     output_file = 'audio.wav'     audio.export(output_file, format='wav')       recognizer = sr.Recognizer()     with sr.AudioFile(output_file) as source:         audio_data = recognizer.record(source)         text = recognizer.recognize_google(audio_data, language='ru')  # Здесь можно указать другой язык, если нужно         print(text)      # Отправляем текст пользователю     bot.reply_to(message, text)      # Удаляем временные файлы     os.remove(output_file)  

4 часть: запуск!

Напрямую в Google Colab можно запустить бота вот так:

bot.polling()

А можно выгрузить в облако, тогда бот будет работать круглосуточно и без необходимости держать открытым Google Colab. Например, в яндекс облако.

Вот такое интересное и практичное применение возможно моделям искусственного интеллекта, а не вот эти вот все скучные захваты мира))))

А что же дальше…

Главное — желание, а уж идеи найдутся. Например, можно дообучить модель. Собрать собственный датасет пользователя с его питомцем и оттюнинговать модель в целях повышения качества «узнавания» именно конкретно заданного домашнего питомца. Бескрайний простор работы с расширением функционала протокола взаимодействия с кормушкой и другими «умными» вещами, разнообразными датчиками и усложнение их логики. Подключение онлайн детекции питомца по потоковому видео.

Источники

SSD: Single Shot MultiBox Detector

Школа глубокого обучения ФПМИ МФТИ

Прыжок до небес: запускаем телеграм бота на Python в serverless облаке

Мой исходник на Github

Послесловие

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


ссылка на оригинал статьи https://habr.com/ru/articles/774850/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *