# Логика отслеживания времени жизни объектов в eye

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


## Модель данных

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

![Database structure](https://a.yandex-team.ru/arc/trunk/arcadia/maps/wikimap/mapspro/services/mrc/eye/doc/eye_object_manger_tables.svg)

Таблицы можно разделить на следующие классы:
- входные:
    - frame
    - frame_location
    - detection_group
    - detection
- выходные:
    - object
    - object_location
    - object_relation
    - primary_detection_relation
    - object_missing_on_frame
- коммуникационные:
    - verified_detection_pair_match
    - verified_object_missing_on_frame
    - verified_detection_location

### Таблицы object, primary_detection_relation, object_location, object_relation

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

Связь объекта и соответствующего множества детекций реализована посредством выделения "главной" детекции, хранимой в поле `primary_detection_id`, и связей с остальными детекциями, хранимыми в таблице `primary_detection_relation`.

В таблице `object_missing_on_frame` содержатся ссылки на фотографии, которые подтверждают исчезновение объекта. Таким образом, "время жизни" объекта определяется как интервал от даты самой ранней его детекции до самой ранней даты снимка из `object_missing_on_frame`.

В таблице `object_location` сохраняется предполагаемое положение и направление объекта.

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


### Таблицы verified_detection_pair_match, verified_object_missing_on_frame, verified_detection_location

Таблицы предназначены для обмена информацией с внешними системами и содержат запросы и результаты верификации во внешних системах конкретных фактов об объектах:
- `verified_detection_pair_match` -- хранит результат проверки, что две детекции относятся к одному и тому же физическому объекту
- `verified_detection_missing_on_frame` -- хранит результат проверки, что объект, представленный детекцией `detection_id` отсутствует на фотографии `frame_id`
- `verified_detection_location` -- хранит верифицированные координаты и направление объекта.

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

Запросы на проведение верификаций размещаются в этих же таблицах.

## Процессы обработки данных

Вся логика по управлению временем жизни объектов, верификации содержимого кластеров объектов, а также верификации того, что объект исчез, локализована в `object_manager`.

### Политика верификации данных

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

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

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

Политику верификации фактов об объектах можно описать в виде массива кортежей из следующих параметров:
- `geo_id` -- идентификатор региона в геобазе
- `object_type` -- тип объекта
- `object_attrs_filter` -- булевая функция от атрибутов объекта, для более специфичной фильтрации, если потребуется
- `verify_object_detections` -- флаг, нужно ли верифицировать принадлежность детекций объекту
- `verify_object_duplication` -- флаг, что нужно верифицировать, что соседние однотипные объекты не соответствуют одному и тому же объекту из реального мира
- `verify_object_position` -- флаг, что нужно верифицировать положение и направление объектов
- `verify_object_missingness` -- флаг, что нужно верифицировать исчезновение объектов.

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

### Обработка обновлений таблиц `detection_group` `frame_location`

Задача `object_manager` при обработке изменений таблиц `detection_group`, `frame_location` состоит в том, чтобы обновить связи между объектами и детекциями,
обновить положение объектов, а также обновить предположения, что объект исчез на фрейме.

Пусть `frame_id` -- идентификатор фрейма, из обновленных таблиц.
Алгоритм обработки:
1. Загрузить из базы все фреймы из того же проезда, у которых есть соответствующая запись в талице `detection_group` с `type = DG.type`.
2. Загрузить детекции типа `DG.type`, соответствующие фреймам проезда.
3. Загрузить из таблицы `object` все объекты, находящиеся в потенциальной области видимости `DG.frame_id` и совпадающие по типу с `DG.type` и время жизни которых содержит дату съемки `DG.frame_id`.
4. Для каждого объекта загрузить его наиболее релевантные детекции -- детекции на фреймах, похожих по положению и времени дня и года к фреймам исходного проезда.
5. Сматчить между собой загруженные фреймы. В результате для некоторых пар фреймов будут получены фундаментальные матрицы, сопоставляющие точки одного фрейма с эпилиниями другого фрейма.
6. Загрузить верифицированные сопоставления детекций из таблицы `verified_detection_pair_match`. Загруженные детекции сопоставить и кластеризовать, в результате детекции проезда распределяются либо среди уже существующих объектов, либо формируют новые объекты. Обновляются оценки позиции у объектов, чьи связи с детекциями были изменены.
В результате обновляются таблицы `object`, `primary_detection_relation`, `object_location`.
7. Загрузить результаты верификаций исчезновения объекта из таблицы `verified_detection_missing_on_frame`. Выявить объекты, которые могли быть видны на фрейме `DG.frame_id`, но для которых не было обнаружено соответствующей детекции. Результаты сохранить в таблицу `object_missing_on_frame`.


### Верификация данных в Толоке и Янге

За обработку запросов на верификацию фактов об объектах ответственен отдельный процесс `verification_worker`. Каждому типу верицикации соответствует отдельный проект в Толоке и Янге. Процесс реагирует на создание записей в таблицах `verified_*` и отправляет задания на разметку через Toloka Manager. Связь между записями в `verified_*` и созданными заданиями в сохраняются в некоторых вспомогательных таблицах. Этот же процесс проверяет готовность ранее размещенных заданий и переносит результаты верификации в таблицы `verified_*`.


### Реагирование на результаты верификации в object_manager

`object_manager` реагирует на изменения в таблицах `verified_` и обновляет соответственно выходные таблицы.

#### Обработка verified_detection_pair_match

В `verified_detection_pair_match` содержится условно-достоверный результат процерки, что две детекции относятся к одному и тому же объекту реального мира. Алгоритм обработки результата:
1. Если текущее содержимое таблицы `primary_detection_relation` согласуется с результатом верификации, ничего изменять не надо.

2. В противном случае требуется перекластеризовать затронутые детекции. Для этого нужно загрузить фреймы проездов, к которым относятся рассматриваемые детекции.
3. Загрузить из таблицы `object` все объекты, находящиеся в потенциальной области видимости фреймов детекций и совпадающие по типу с `DG.type` и время жизни которых  содержит датами съемки фреймов, на которые ссылаются рассматриваемые детекции.
4. Для каждого объекта загрузить его наиболее релевантные детекции -- детекции на фреймах, похожих по положению и времени дня и года к исходным фреймам.
5. Сматчить между собой загруженные фреймы. В результате для некоторых пар фреймов будут получены фундаментальные матрицы, сопоставляющие точки одного фрейма с эпилиниями другого фрейма.
6. Загрузить верифицированные сопоставления детекций из таблицы `verified_detection_pair_match`. Загруженные детекции сопоставить и кластеризовать, в результате детекции проезда распределяются либо среди уже существующих объектов, либо формируют новые объекты. Обновляются оценки позиции у объектов, чьи связи с детекциями были изменены.
В результате обновляются таблицы `object`, `primary_detection_relation`, `object_location`.
7. Загрузить результаты верификаций исчезновения объекта из таблицы `verified_detection_missing_on_frame`. Выявить объекты, которые могли быть видны на исходных фреймах, но для которых не было обнаружено соответствующей детекции. Результаты сохранить в таблицу `object_missing_on_frame`.

#### Обработка verified_detection_missing_on_frame

В `verified_detection_missing_on_frame` содержится результат проверки, что фрейм подтверждает исчезновение объекта, и представляет собой кортеж из следующих полей:
- `place_is_visible` -- место расположения объекта находится в области видимости фрейма
- `detection_is_hidden` -- место расположения объекта скрыто другим объектом
- `detection_is_visible` -- объект, которому соответствует детекция, виден на фрейме.

Фрейм подтверждает исчезновение объекта только если выполняется условие: `place_is_visible == true && detection_is_hidden == false && detection_is_visible == false`.

Алгоритм обработки:
1. Загрузить объект, которому соответствует детекция.
2. Загрузить все завершенные `verified_detection_missing_on_frame`, соответствующие детекциям объекта.
3. Обновить запись в `object_missing_on_frame` в соответствии с мнением большинства из загруженных результатов верификации.
4. В случае, если в результате будет признано, что фрейм не подтверждает исчезновение объекта, необходимо перекластеризовать все детекции соответствующего типа в окрестности объекта, найденные на фреймах старше `object_missing_on_frame.frame_id`.

#### Обработка verified_detection_location

В таблице `verified_detection_location` содержатся верифицированные координаты и направления объекта.

Алгоритм обработки:
1. Загрузить все соответствующие `verified_detection_location` для этого объекта.
3. Выбрать значение позиции и направления из наиболее достоверного источника (Толока < Янг < Народная Карта), сохранить изменения в `object_location`.

