Полтора года назад я просматривал блог одного из успешных российских фотографов-портретистов с узнаваемым стилем и в голову закралась мысль, а почему бы просто не поставить камеру на штатив, один раз поставить в студии свет, выставить все настройки камеры и сделать автоматическую обработку фотографий с заданным профилем? Фотографии в блоге были великолепные, но очень похожи друг на друга.  Так как я отношусь к людям, которые не умеют фотографировать на телефон и любят фотоаппараты, то идея мне очень понравилась. Да, я видел всякие фотобудки и фотостойки, но разработчики этих устройств даже не осилили сделать нормальные цвета. Я решил, что это из-за того что разработчики не разбирались в фотографии. Чтобы с этой идеей не произошло того же, что и с остальными (которые не сдвинулись с места или заглохли на начальном этапе). Я решил, что самое главное — сделать чтобы все работало целиком, а не полировать до блеска какой-то отдельный компонент. А так как времени на разработку у меня очень мало, после основной full-time работы остаются силы на 1-2 часа максимум, и немного больше в выходные, то нужно стараться не изучать ничего нового, по-максимуму пользоваться имеющимися знаниями. Хочу в этой статье рассказать, какие проблемы у меня возникали на пути и как я их решал. Небольшое объяснение по условиям съемки и оборудованию: рассматривал только фотоаппараты с матрицей APS-C минимум и профессиональные студийные вспышки, только так можно гарантированно обеспечить высокое качество снимков в любое время дня и ночи. Первое, что я с удивлением обнаружил, когда поставил камеру на штатив — что не так то просто влезть в кадр да еще и так, чтобы была хорошая композиция. Когда перемещаешься от камеры и к ней, то тоже вся композиция портится, если правильно ее поставить для конкретного человека стоящего в определенной точке. Да, можно поставить стул и сказать, что надо сидеть на стуле, но это будет не очень интересно. Еще можно обрезать фотографии, но тогда будет сильно ухудшаться качество. Ну и последний путь, который я выбрал — сделать чтобы камера наводилась автоматически. Здесь есть тоже 2 варианта. Правильный — оптическая ось всегда горизонтальна, камера смещается вверх и вниз и более простой в реализации — подстраивать положение камеры наклонами. В этом случае будут перспективные искажения, но они довольно неплохо исправляются при обработке если запоминать угол наклона камеры. Так как опыта изготовления всяких железных устройств я практически не имел, то попытался найти что-то максимально готовое к использованию. Нашел несколько устройств для панорамной съемки в пределах 1000$, все позволяли вручную управлять наклонами и поворотами, а также автоматически снимать панорамы. Но управлять с компьютера ими было нельзя. Также есть довольно много устройств для управления видеокамерами, для съемки с операторских кранов, например. Хорошие устройства, которые имеют намеки на цифровое управление стоят очень дорого, при этом совершенно непонятно, есть ли там какое-то доступное API. В итоге нашел вот такой девайс на популярном сайте:  Из электроники нет ничего. Год назад была доступна только версия с коллекторными двигателями (со встроенными редукторами), её я и купил. Надо было как-то этой штукой управлять с компьютера. На форуме нашего института подсказали, что самый доступный способ — это воспользоваться Arduino. Так я и сделал. Купил еще motor shield, так как двигатели там питаются от 12 вольт. После того, как я попытался это включить я ощутил всю боль которую могут причинить коллекторные двигатели человеку — их не только невозможно повернуть на заданный угол, просто "немного повернуть" тоже непросто. Первая мысль была — поставить туда шаговый двигатель. Я очень долго искал шаговый двигатель, который влезет в эту платформу вместо того, который там стоял, но так и не нашел. Потом стал продумывать, как туда можно прикрутить сервопривод, даже его купил но тоже ничего надежного придумать не смог. Следующая мысль была — прикрутить к платформе акселерометр и понемногу поворачивать платформу до заданного угла. Прикрутил акселерометр с гироскопом и компасом, но он уж очень сильно глючил и от этой идеи я тоже отказался (через месяц я понял, что в глюках акселерометра был виноват китайский блок питания для фотоаппарата, от которого шли неслабые наводки). И тут я случайно прочитал, как устроен сервопривод. Идея прикрутить резистор для измерения угла мне понравилась, но надо было как-то соединить его со шкивом. Пришлось освоить FreeCAD и впервые в жизни воспользоваться услугой 3D печати. Короче после обработки напильником все удалось собрать.  С программой для ардуино для установки заданного угла пришлось помучаться, так как у камеры на платформе большой момент инерции и останавливается она не сразу. Но в итоге получилось устанавливать угол с точностью около 1 градуса. Теперь про автоматическое наведение — идея простая сделать чтобы лицо было в верхней части кадра. Так что надо просто на каждой картинке из liveview находить лицо и подстраивать платформу. Про определение лиц я тогда ничего не знал, так что по тьюториалу воспользовался методом с использованием признаков Хаара (haar cascades). Выяснил, что для лиц этот метод не работает. Находит на каждом кадре еще кучу мусора кроме того что нужно и потребляет очень много процессорного времени. Потом нашел еще один пример, как использовать нейросети через OpenCV. Нейросети работают просто отлично! Но радовался я до того момента как запустил параллельно обработку фотографий. И линукс как-то плохо стал между тредом управления платформой и процессами обработки фото распределять процессорное время. Пошел по пути наименьшего сопротивления — стал делать определение лиц на видеокарте. Все стало работать отлично. Несмотря на то, что я не хотел углубляться в детали, все-таки провел небольшой тест. И еще купил Intel Neural Compute Stick 2 — попробовал на нем считать вместо видеокарты. Результаты у меня примерно такие (цифры — время обработки одного изображения размером 800x533) - Оказалось, что достаточно обрабатывать изображения размером 300 по меньшей стороне, чтобы надежно находилось лицо человека, стоящего в полный рост в кадре. На таких изображениях работает быстрее. Сейчас у меня используется GeForce GTX 1050. Уверен, можно сильно улучшить, но сейчас есть гораздо более серьезная проблема. Не секрет, что фотография должна быть правильно экспонирована. В моем случае это еще более важно, так как нет ретуши. Чтобы дефекты кожи были менее заметны, фото должно быть максимально светлое, на грани пересвета, но без пересветов. Яркость итоговой картинки при съемке со вспышкой зависит от следующих параметров: После того, как сделан кадр мы можем менять только последний параметр. Но менять его в широких пределах не очень хорошо, так как при большой положительной коррекции экспозиции темного кадра будут шумы, а в обратном случае может быть клиппинг в светлых участках. Для автоматического определения экспозиции во время съемки со вспышкой используется система TTL (Through The Lens). Работает следующим образом: Эта система отлично работает, когда есть возможность вручную подкорректировать снимки после съемки. Но для получения готового результата она работает неудовлетворительно. Если что — пробовал вспышки Profoto за >100т.р. У меня условия известные, вспышки должны стоять все время на одном месте. Так что можно просто рассчитать экспозицию по положению человека в пространстве. Возникает задача — как определить положение человека? Первая идея была просто брать расстояние до объекта фокусировки из EXIF и для первого кадра делать большую экспокоррекцию в рав-конвертере а для следующего подстраивать мощность вспышки или диафрагму. Очень большая вероятность, что человек будет делать много кадров, стоя на одном месте. Но оказалось, что расстояние в EXIF пишется сильно дискретное, чем дальше объект — тем больше шаг. Причем для разных объективов расстояние до объекта принимает разные наборы значений, а некоторые вообще его не измеряют. Следующая идея — использовать ультразвуковой дальномер. Этот прибор измеряет расстояние довольно точно, но только до метра и только если человек не одет во что-то, что поглощает звуковые волны. Если поставить дальномер на сервопривод и крутить его как радар, то становится чуть лучше — измеряет уже до 1.5 метров, что тоже очень мало (лучше всего люди получаются, если снимать их с расстояния 2 метра). Конечно я знал, что уже даже недорогие телефоны строят карты глубин и размывают фон выборочно. Но так не хотелось в это ввязываться. К сожалению, выбора не осталось. Сначала хотел купить 2 вебкамеры, объединить их и считать карту смещений с помощью OpenCV. Но, к счастью, нашел много камер глубины которые уже внутри себя это делают. Остановил выбор на Intel D435 (если кто-то захочет такую купить — она в линуксе в основной ветке ядра не поддерживается. В репозитории librealsense есть патчи для debian и ubuntu вроде. Для fedora пришлось их править).  Как только все подключил, написал тестовую программу, которая измеряет расстояние до небольшого квадрата в центре. Так до сих пор этот код и работает. И работает довольно неплохо. Конечно надо на картинке с RGB камеры искать лицо и вычислять расстояние от вспышки до этого лица. Но это планы на будущее. По положению человека в пространстве надо вычислить поправку к экспозиции. Сначала я придумал какую-то формулу, которая работала только для точечного источника света в вакууме (на самом деле имело значение отсутствие отражающих стен и потолка). Но потом просто сделал серию кадров с постоянной мощностью вспышки и в рав-конвертере на глаз откорректировал экспозицию, оказалось, что поправка практически линейно зависит от расстояния. У меня используется схема освещения Рембрандта, вспышка с софтбоксом стоит в плоскости камеры.  Но с поправкой экспозиции тоже что-то надо делать. В идеале надо менять мощность вспышки, но пока у меня меняется диафрагма и добавок <1/6Ev — в рав-конвертере. Синхронизатор моих вспышек может управляться по bluetooth с помощью приложения для телефона. Так что в будущем планирую разобраться, как там протокол устроен и менять мощность вспышек. Вот сравнение постоянной мощности вспышки с TTL и моим методом. Работает гораздо стабильнее и точнее TTL:  Когда девушка (или даже парень) приходит на фотосессию к фотографу она (или он) обычно хочет фото разного плана, более крупного, где только лицо и более общего — в полный рост или по пояс. Не все знают, но лучше всего план меняется сменой фокусного расстояния объектива. То есть человек всегда стоит на расстоянии скажем 2 метра, если нам надо снять в полный рост — накручиваем объектив 35мм, если только лицо — 135мм, а если по пояс — то 50мм или 85мм. Ну или не меняем объективы а ставим объектив с зумом. Предлагать пользователю руками крутить зум на камере, которая стоит на подвижной платформе, прорываясь через пучок проводов — звучит как-то не очень. Так что купил пачку запчастей на алиэкспрессе, взял сервопривод который мне не пригодился для управления платформой и сделал вот это:  А вот так оно работает: Результаты первого теста в фотостудии, прежде всего хотелось посмотреть, насколько разнообразные получится делать снимки, ничего не двигали и не перенастраивали во время съемки:  Видео процесса: Вот это одни из лучших кадров, которые получилось сделать: 
вроде у всех разрешение на публикацию спрашивали, если вы себя узнали и хотите убрать фото — напишите мне Для чего я это делал? Это штука которой еще не было, по-крайней мере я не нашел ничего похожего. Потенциально полезная — сейчас много специалистов, таких как психологи, бизнес-тренеры, спортивные тренеры, парикмахеры продают свои услуги через блоги, им нужно много фотографий, причем именно в таком виде, в каком им хочется, а не фотографу. Некоторые люди просто не любят, когда на них при съемке смотрит незнакомый человек (фотограф). Ну и самое простое — это отличное развлечение для корпоративов, выставок и других мероприятий. Не описал программную часть, как обрабатываются фотографии и про взаимодействие с пользователем, так как уже и так много текста, напишу позже вторую часть. Эти моменты уже довольно неплохо проработаны так, что системой могут пользоваться люди не знакомые с программированием.