Вступление в мир разработки игр

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Немного о нас

Я профессионально занимаюсь машинным обучением (МЛ) и активно участвовал в соревнованиях на Kaggle. Это позволяет мне развивать навыки и исследовать новые решения, но Kaggle занимает много времени и не приносит дохода. Из-за этого я и мои друзья решили создать что-то свое, что, возможно, превратится в стартап в будущем (как говорится, "каждое хобби должно заканчиваться стартапом"). Наша команда состоит из двух специалистов по машинному обучению и одного фронтенд-разработчика. Специалисты по МЛ работают над бэкендом, в то время как фронтенд-разработчик занимается своими прямыми обязанностями.

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

Наш первый проект

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

На одном из подкастов я узнал, что эффективная стратегия для старта — это создание MVP (минимально жизнеспособного продукта) для Android, и если проект приживется, тогда расширяться на iOS, заложив основу для мультиплатформенности с самого начала.

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

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

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

Вот наш первый проект

Как мы искали нужные кадры из фильма

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

Предварительно мы рассматривали использование нейросетевой модели YOLO для выявления объектов в кадрах. Однако, несмотря на высокую точность YOLO в классификации и идентификации объектов, мы столкнулись с проблемой излишней фильтрации важных кадров. Например, в известной сцене из фильма "Форрест Гамп" с летящим пером, важные для сюжета кадры не содержали распознаваемых объектов, что привело к их исключению. В результате отказались от использования YOLO в пользу более традиционных методов выбора кадров, которые лучше справлялись с задачей сохранения визуально значимых моментов.

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

Ниже приведен фрагмент кода, демонстрирующий основные шаги обработки видео:

def scene_change_detection(movie_path, output_folder, threshold=30.0, frames_per_scene=3):
    """
    Detects scene changes and extracts n random frames from each scene.
    Uses OpenCV for frame processing and scene change detection.

    :param movie_path: Path to the movie file.
    :param output_folder: Folder to save the extracted frames.
    :param threshold: Threshold for detecting scene changes based on frame differences.
    :param frames_per_scene: Number of random frames to extract from each scene.
    """
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    cap = cv2.VideoCapture(movie_path)
    if not cap.isOpened():
        print("Error: Could not open video.")
        return

    ret, prev_frame = cap.read()
    if not ret:
        print("Error: Could not read the first frame.")
        return

    prev_frame_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
    frame_buffer = []
    scene_count = 0
    
    while True:
        ret, curr_frame = cap.read()
        if not ret:
            break

        frame_buffer.append(curr_frame)
        curr_frame_gray = cv2.cvtColor(curr_frame, cv2.COLOR_BGR2GRAY)
        frame_diff = cv2.absdiff(curr_frame_gray, prev_frame_gray)
        diff_score = np.mean(frame_diff)

        if diff_score > threshold:
            if len(frame_buffer) > frames_per_scene:
                scene_count += 1
                selected_frames = random.sample(frame_buffer, frames_per_scene)
                for idx, frame in enumerate(selected_frames):
                    frame_name = f"scene_{scene_count}_frame_{idx}.jpg"
                    cv2.imwrite(os.path.join(output_folder, frame_name), frame)
            frame_buffer.clear()

        prev_frame_gray = curr_frame_gray

    cap.release()
    print(f"Scene detection complete. {scene_count} scenes detected.")

На подготовленном датасете мы обучили нейронную сеть, используя архитектуру EfficientNetV2 M, известную своей эффективностью в задачах классификации изображений. Сеть помогала нам отличать "хорошие" кадры от "плохих", опираясь на способность модели выявлять важные визуальные особенности, даже если прямо в кадре не было объектов, таких как люди или заметные предметы. Например, в сцене из фильма "Форрест Гамп" важным может быть кадр с парящим пером, хотя и не содержит персонажей.

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

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

Интересные факты

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

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

Ключевой аспект нашей работы заключался в оптимизации промптов, что требовало детального понимания возможностей и ограничений ChatGPT. Например, мы начали с базовых запросов типа "Расскажи интересный факт о фильме [название фильма]", и постепенно добавляли уточнения и контекст для улучшения результатов. Тестирование различных формулировок промптов позволило максимально эффективно использовать модель для генерации точной и полезной информации.

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

Дизайн приложения

Поскольку в нашей команде не было профессиональных дизайнеров, мы решили использовать нейронные сети для создания дизайна приложения. Мы выбрали MidJourney и DALL-E для этой задачи, что позволило нам автоматизировать процесс и получить качественные результаты без привлечения специалистов в области дизайна.

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

Работа с публикацией

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

Постскриптум

Также интересен опыт сотрудничества: если у вас есть идеи или опыт в области разработки игр, предлагаю объединить усилия для создания чего-то действительно впечатляющего. Давайте вместе реализуем что-то уникальное!

Источник: https://habr.com/ru/articles/811155/


Интересные статьи

Интересные статьи

Американский стартап Cognition представил нейросеть под названием Devin. В компании утверждают, что этот проект способен более самостоятельно осуществлять полный цикл разработки ПО и даже заменить инж...
Следующий аспект оригинальной игры - тайлы местности, которые создают как раз неповторимый дизайн каждого уровня. В оригинальной BATTLE CITY пять видов местности, которые сильно отличаются по сво...
В телепередачах и кинофильмах мы часто видим эффектный взлет истребителей в ночное небо, как из сопла двигателей рвется раскаленное пламя с температурой выше 1100 градусов и не задумываемся, какие же ...
Сегодня стартуют продажи Яндекс Станции 2 — нашего новейшего устройства, которое станет центральным элементом в умном доме с Алисой. Мы полностью переосмыслили и внутренний, и внешний дизайн, доба...
Привет, Хабр! Уже более 5 лет мы используем численное моделирование в качестве метода решения различных инженерных задач: определение параметров технологических процессов, которые ...