Количество снимков, которые мы все делаем на своих мобильных телефонах, просто невероятно, и это число растет по мере того, как камеры совершенствуются, на мобильных устройствах становится больше места, а облачные решения, такие как iCloud или Google Фото, синхронизируют их с серверной инфраструктурой.

Из пользовательской базы Storyo мы знаем, что в среднем пользователи имеют от 1000 до 1500 изображений на своих устройствах (iOS и Android), и если мы перейдем к 98-му процентилю, мы увидим, что 2% нашей пользовательской базы имеют больше, чем 20000 картинок.

Организация фотографий - это горячая тема, которой мы занимаемся с момента создания первой версии Storyo в июле 2014 года, которую мы теперь также сделали доступной в нашем родном SDK для iOS и Android.

Мы всегда рассматривали фотоорганизацию как состоящую из двух больших, относительно независимых областей:

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

Истории состоят из групп фотографий и могут быть показаны в самых разных организациях. Мы всегда выступали за организацию историй в хронологическом порядке с точки зрения сюжета, чтобы отображать хронологию пользовательских фотопленок. Наши пользователи подтвердили этот подход: почти 40% историй воспроизводятся в Storyo, начиная с нажатия на автоматическую историю.

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

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

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

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

Эта статья будет посвящена тому, как создать поток фото-курирования, который использует повествование и компьютерное зрение / глубокое обучение, на основе того, что мы создали в приложении Storyo и SDK Storyo для создания фотокниг и временной шкалы видео.

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

Фильтрация нежелательных изображений

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

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

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

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

Глубокое обучение развивается с невероятной скоростью, и количество инструментов, предлагаемых крупными игроками, такими как Google, Apple и Microsoft, разработчикам и не разработчикам, быстро растет.

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

Если вы хотите обучить свой собственный набор категорий с помощью подобной модели, вам просто нужно обучить последний слой (или слои), сопоставляющий эти общие функции с вашим контентом с очень небольшим набором изображений. Microsoft предлагает несколько сервисов через свою инфраструктуру Azure и, в частности, Cognitive Service, у Google есть свои мощные сервисы Firebase и недавно запустил Cloud AutoML для обучения пользовательских моделей, а Apple предлагает Create ML, созданный для работы на Mac и обучения моделей для своей экосистемы.

Как и во всех моделях глубокого обучения, размер имеет значение, и если вы хотите запускать модели локально, это может быть недостатком. Однако в iOS 12 Apple реализовала небольшой шаг, который позволит приложениям совершить гигантский скачок вперед с выполнением глубокого обучения на мобильных устройствах - они добавили базовую модель для классификации в пакет операционной системы.

Используя Apple Create ML для перетаскивания нескольких нежелательных изображений, таких как изображения документов, мы можем создать новую модель с небольшим набором байтов, который будет назначен приложению, вместо обычного масштаба в несколько МБ.

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

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

Группировать похожие фото

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

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

Теперь мы рассмотрим два изображения со косяком рыб, где рыбы постоянно движутся, ожидая, что корм упадет в воду (рис. 2). Ваш мозг сразу скажет вам, что эти фотографии представляют собой похожие изображения. Однако если вы хотите найти точки разрыва и сопоставить пиксели, у вас ничего не получится. На самом деле эти два изображения не совпадают и даже частично не совпадают.

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

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

Ранжировать изображения

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

Начнем с простого и обычно согласованного: наличия лиц. Вы можете определить, присутствует ли лицо на изображении, используя стандартные SDK, предлагаемые Android и iOS. Если лицо присутствует, вы можете использовать его, а также его размер, чтобы повлиять на относительный рейтинг. Обнаружение лиц теперь также переходит на глубокое обучение и, таким образом, является довольно мощным, а это означает, что нерезкие лица могут быть легко обнаружены! Мы вернемся к этому позже.

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

При обнаружении ориентиров по лицам важно не забывать, что в экосистеме iOS вы можете задействовать iCloud с Интернет-уровнем посередине. Если вы хотите повысить точность этих отметок, у вас может возникнуть нежелательная сетевая зависимость, которая может существенно повлиять на опыт, предлагаемый вашим пользователям.

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

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

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

Еще один хороший кандидат, который поможет нам в процессе ранжирования, - это эстетика. Поскольку эстетика по своей сути субъективна, глубокое обучение снова является хорошим кандидатом, чтобы оказать нам некоторую помощь. Мы протестировали несколько моделей, и одна из них, которая нас порадовала, была NIMA: Neural Image Assessment, которая предсказывает, какую гистограмму классификаций от 1 до 10 группа людей придаст определенному изображению.

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

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

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

В конечном счете, мы считаем, что хорошей стратегией ранжирования изображений является использование индекса, который использует все ранее описанные переменные. Однако это выходит за рамки данной статьи. Мы можем раскрыть, как мы это делаем в Storyo SDK, в другой статье, посвященной этой конкретной теме, в ближайшем будущем.

Повествование, основанное на времени и пространстве

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

Например, если у вас есть 100 разных фотографий (что легко может произойти в контексте путешествия) и вы хотите показать свои фотографии в виде слайд-шоу с ровно 60 секундами для публикации в Instagram, как вы это сделаете? Если мы предположим, что видео не должно показывать более одного изображения за раз и что каждое изображение должно быть видно в течение 2 секунд, как нам выбрать 30 фотографий из уже отобранных 100?

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

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

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

Затем процесс кластеризации продолжается, рекурсивно применяя один и тот же метод к каждому кластеру до тех пор, пока не будут достигнуты некоторые критерии остановки. Например, ограничивающая рамка находится ниже x км или временной диапазон ниже определенного диапазона.

Представьте себе, что кто-то путешествует из Нью-Йорка в Европу и перед его путешествием сделал 3 разных снимка в аэропорту имени Джона Кеннеди. Затем этот человек посещает Рим, где делается 30 разных снимков, а затем Венеция с 50 разными фотографиями. Затем пользователь садится на самолет в Париж, и путешествие заканчивается 17 непохожими картинками.

Поскольку существует огромный географический разрыв между США, Италией и Францией, первая кластерная сегментация происходит по странам: первый узел представляет фотографии, сделанные в JFK, вторая группа фотографий, сделанных в Италии, а третья - в Париже.

Фотографии JFK очень ограничены во времени и пространстве, и на этом процесс кластеризации заканчивается. Теперь представьте, что пользователь провел один день в Риме, два дня в Венеции и еще один день в Париже.

Узел Италии разделен по доминирующим географическим регионам: Рим находится в первом узле, а Венеция - во втором. За день, проведенный в Риме, пользователь сделал 10 разных фотографий рано утром, 5 днем ​​и 15 во время ужина с несколькими местными друзьями. Поскольку времени было мало, пользователь мало двигался по городу, и разделение на кластеры закончилось, во многом благодаря временному промежутку между тремя наборами фотографий (утром, днем ​​и ужином).

Хотя они провели в Венеции два дня, пользователь не тратил много времени на съемку, сделав только 30 фотографий в первый день и 20 во второй день. В этом сценарии кластеризация завершилась в листовом узле для дня 1 и другом листовом узле для дня 2.

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

Теперь, когда у нас есть скелет, мы должны его использовать! Для этого мы возьмем наши заранее определенные 60 секунд и поместим их в корень дерева в потоке делегирования времени представления.

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

Давайте посмотрим, как 60-секундный поток делегирования может быть выполнен в корневом узле, предварительно отправив время на узлы JFK, Италия и Париж соответственно. Помните, что у нас есть следующая пропорция 3: 80: 17 разных фотографий с 2 ​​секундами в качестве нашей единицы. Если мы назначим 2 секунды JFK, 48 секунд - Италии и 10 секунд - Парижу, мы сохраним разумные пропорции и предположим, что первая делегация действительно преуспела.

Теперь мы должны предварительно делегировать время представления в узлах Италии и Франции независимо друг от друга. Мы начинаем с Италии, где мы теряем 48 секунд до Рима и Венеции в соотношении 30:50 и можем сохранить успех, делегируя 18 секунд Риму и 30 секунд Венеции.

Продолжая в Италии, мы попытаемся делегировать 18 секунд в Риме на утро, полдень и ужин в соотношении 10:5:15. Это дает прямое разделение на 6, 3 и 9 секунд соответственно. 3 и 9 не делятся на 2, поэтому нам нужно найти баланс. Хорошая возможность - убрать 1 секунду из обеда и отдать ее после полудня, получив разделение на 6, 4 и 8 секунд соответственно. Поскольку детей больше нет, делегирование в римском филиале на этом заканчивается.

Венеция - следующий город, которому предстоит управлять делегацией. 30 секунд будут разделены на день 1 и день 2 с соотношением 30:20, что дает успешное делегирование 18 секунд для дня 1 и 12 секунд для дня 2. Опять же, дочерние элементы отсутствуют, и делегирование прекращается.

Нам все еще предстоит управлять делегацией Парижа, которой оставалось 10 секунд, разделив их на 7:10 и получилось примерно 4 секунды на обед и 6 секунд на ужин.

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

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

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

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