Connect with us

Разработка

Отслеживание угла горизонта на изображении с помощью фреймворка Vision

Отслеживание горизонта, изображенного на фотографии — одна из тех задач, которые можно решить с помощью анализа изображений в фреймворке Vision.

Опубликовано

/

     
     

Отслеживание горизонта, изображенного на фотографии — одна из тех задач, которые можно решить с помощью анализа изображений в фреймворке Vision.

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

Чтобы начать выполнение задачи, импортируйте фреймворк Vision.

Затем создайте функцию, которая принимает в качестве параметра UIImage и возвращает HorizonObservation:

detectHorizon(uiImage:) работает следующим образом:

  1. Преобразует переданный UIImage в CIImage.
  2. Запрашивает DetectHorizonRequest.
  3. ХранитHorizonObservation, полученный из обработанного изображения методом perform(on:orientation:).
  4. Возвращает результат.

HorizonObservation возвращает:

  • свойство angle — наблюдаемый горизонт в радианах;
  •  transformCGAffineTransform для применения к обнаруженному горизонту.

Прежде чем перейти к интеграции обнаружения горизонта, имейте в виду, что DetectHorizonRequest возвращает optional HorizonObservation . Этот проект был протестирован с 39 различными фотографиями, и обнаружил горизонт только на 47% из них, в основном возвращая nil на фотографиях с углом горизонта, равным 0.

Интеграция в SwiftUI

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

Отслеживание угла горизонта на изображении с помощью фреймворка Vision

Сначала создадим само представление.

HorizonLineView — это представление, отображающее красный прямоугольник прямо за изображением, и кнопку, включающую обнаружение горизонта. Оно использует GeometryReader для получения размера изображения и применения его, увеличенного на 10, к красному прямоугольнику — так, чтобы он был виден за фотографией.

Функция rotateThePicture(), вызываемая кнопкой, выполняет обнаружение горизонта.

Когда обнаружение будет выполнено, мы хотим, чтобы горизонт был наложен с 2 разными линиями:

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

Чтобы добиться такого результата, мы создаем пользовательский Shape, который будет рисовать линии.

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

Функция рисует линию в соответствии со следующей логикой:

  1. Получает центр прямоугольника рисования, к которому будет привязана линия.
  2. Вычисляет половину ширины прямоугольника, которая используется для продления линии в обе стороны от центра
  3. Объявляет переменные для горизонтального и вертикального смещения. dx и dy указывают, на какое расстояние нужно отступить от центра представления, чтобы нарисовать конечные точки линии. Подумайте вот о чем: если вы расположили линейку по центру области рисования, то эти смещения определяют, насколько нужно сдвинуть концы влево/вправо (dx) и вверх/вниз (dy) в зависимости от угла наклона горизонта. Они гарантируют, что независимо от наклона линии, она останется в центре, а ее конечные точки будут правильно расположены в соответствии с обнаруженным углом.
  4. Она вычисляет их:
    • если угол не равен нулю, они рассчитываются с помощью косинуса — чтобы определить, насколько влево или вправо нужно двигаться, — и синуса — насколько вверх или вниз нужно двигаться — от определенного угла;
    • Если угол равен нулю, он просто присваивает dx половину длины, а dy — ноль, в результате чего получается идеально горизонтальная линия, что и требуется для построения линии, работающей как направляющая.
  5. Определяет начальную и конечную точки линии горизонта: начальная точка линии устанавливается в (centerX - dx, centerY - dy) — перемещение влево — и конечная точка в (centerX + dx, centerY + dy) — перемещение вправо — Это гарантирует, что линия будет центрирована в поле зрения и правильно повернута в соответствии с обнаруженным углом горизонта.
  6. Перемещается к начальной точке и добавляет линию к конечной точке, чтобы окончательно нарисовать линию.

Отслеживание угла горизонта на изображении с помощью фреймворка Vision

Давайте интегрируем линии в представление.

Создайте 2 экземпляра HorizonLineShape, чтобы поместить их между изображением и кнопкой:

  1. Первая линия, красная, будет представлять обнаруженную линию горизонта сразу после анализа, проведенного Vision на фотографии;
  2. Вторая, зеленая, будет служить ориентиром для выделения разницы между обнаруженным и идеальным уровнем горизонта.

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

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

Теперь мы можем использовать это значение для поворота изображения.

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

CustomTransition соответствует протоколу Transition, производя поворот только тогда, когда красная линия полностью видна в представлении, используя свойство isIdentity.

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

Источник

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Telegram

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: