Введение

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

Фактически, большинство алгоритмов и формул, используемых в компьютерном зрении, основаны на восприятии человеческого глаза. Например, масштабирование серого изображения RGB, метод, который сокращает каналы изображения до 1 канала путем усреднения значений пикселей R, B и G, выполняется по следующей формуле: Серый ← 0,299⋅R + 0,587⋅G + 0,114 ⋅B [Ссылка на источник]. Примечание. Очевидно, это не то же самое, что усреднение значений пикселей R, G и B, как представлено формулой: Серый ← 0,33⋅R + 0,33⋅G + 0,33⋅B.

Но почему? Причина этого в том, что наши глаза более восприимчивы к яркости / яркости по сравнению с цветностью. Фактическая формула, используемая при градации серого изображения, аналогична вычислению значения яркости / яркости для данного пикселя. Примечание. Значение яркости - это значение Y в цветовом пространстве YUV и YCrCb [Ссылка на источник: посмотрите на RGB в YCrCb].

Автофокус - интересная особенность камеры. Он действительно может воспроизводить фокусирующую способность наших глаз. Для лучшей визуализации изобразите два объекта (бутылку с водой и розетку) в разных плоскостях, как показано слева. Теперь сфокусируйте взгляд на бутылке с водой. Бессознательно ваши глаза размывают розетку позади вас. Повторите то же самое для настенной розетки, и наши глаза автоматически размывают бутылку с водой. Теперь воспроизведите аналогичную настройку у себя дома и откройте приложение камеры на своем телефоне. При нажатии на область, на которой вы хотите сфокусироваться, камера автоматически размывает другой объект, как это делали наши глаза. Это волшебство автофокусировки камеры в действии. Сегодня существует множество алгоритмов, которые камера использует для фокусировки на изображении. Я остановлюсь на одном из основных алгоритмов автофокусировки: автофокусировка на основе контраста.

Как работает автофокусировка на основе контраста на высоком уровне?

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

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

Теперь камера перебирает различные положения объектива камеры, вычисляет контраст в изображении, а затем сравнивает и выбирает положения объектива камеры с наивысшим значением контрастности.

Как определить контраст?

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

Одним из основных методов присвоения значения контрастности изображению является Canny Edge Detection. Фактически, именно так OpenCV вычисляет оптимальное положение объектива камеры для автофокуса. Для каждого положения линзы мы рисуем края изображения и назначаем значение контрастности на основе резкости краев. Например, приведенная ниже последовательность изображений показывает результат после выполнения алгоритма Canny Edge Detection:

Как видите, чем менее сфокусировано изображение, тем менее резкими становятся края. Фактически, после установки настроек по умолчанию для алгоритма Canny Edge Detection вы заметите, что он не может обнаружить края для двух все более несфокусированных изображений слева. Очевидно, что, уменьшив минимальное пороговое значение для алгоритма, мы сможем увидеть края. Но ради автофокуса мы можем отбросить положения объектива камеры, которые не определяют края.

Если вы хотите подробнее изучить алгоритм автофокуса OpenCV, ознакомьтесь с их кодом по адресу: Ссылка на исходный код.

Вывод

Алгоритм автофокусировки на основе контраста требует множества вычислений - ›L * O (Контрастность), где L - количество возможных положений объектива камеры, а O (Контрастность) - сложность алгоритма, используемого для определения контраста в изображении. В приведенном выше примере сложность определения того, являются ли края резкими, потребует более O (m * n), где m и n - размеры кадра. Из-за этой высокой сложности многие компании, которые создают драйверы камеры (Qualcomm, Apple и т. Д.), Исследуют новые и более эффективные методы, чтобы определить, сфокусировано ли изображение. Некоторые из других распространенных алгоритмов включают PDAF, Laser и т. Д. Фактически, в качестве побочного эксперимента вы можете визуализировать разницу между Apple и Qualcomm, сравнив способность автофокусировки в приложении камеры Apple и телефона Samsung (телефоны Samsung используют Набор микросхем Qualcomm).

Расширение

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

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

Я начал с экспериментов с нейронной сетью прямого распространения, так как это намного проще реализовать. Я создал небольшую нейронную сеть из 4 слоев. В этой нейронной сети я добавил входной слой для 3-канального изображения размером 224 на 224 пикселя. Затем я сгладил размеры в одно измерение и добавил скрытый слой из 1024 нейронов. Вместо того, чтобы сразу переходить к последнему слою, я решил добавить еще один скрытый слой из 128 нейронов. Наконец, я закончил нейронную сеть с выходным слоем из 2 нейронов, чтобы указать сфокусированный или несфокусированный.

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

Это подтолкнуло меня к экспериментам со сверточной нейронной сетью (CNN), поскольку они, кажется, дают лучшие результаты для обнаружения объектов. Keras имеет множество предварительно обученных моделей CNN, и я решил настроить модель vgg16 для данной задачи. Я взял 5 сверточных блоков модели vgg16, а затем добавил слой глобального среднего пула, чтобы уменьшить размеры до 1, а также эффективно уменьшить количество обучаемых параметров. Наконец, я добавил выходной слой из 2 нейронов, чтобы представить сфокусированную или несфокусированную уверенность.

Точность этой модели была намного лучше, чем у нейронной сети прямого распространения, и я закончил 25 эпох с точностью проверки 0,76 и потерей проверки 0,49. Хотя эти цифры невелики, я считаю, что эти цифры отражают нехватку данных по обучению. Я использовал только 1400 обучающих изображений и чувствую, что моя точность значительно улучшится, если я увеличу это примерно до 6000–7000 изображений. Я протестировал свою модель на 6 изображениях, показанных на рисунке 2. Модель правильно пометила каждое изображение как сфокусированное или несфокусированное. Для получения дополнительной информации просмотрите исходный код по этой ссылке GitHub.