Программа ищет на фотографии Finder Pattern'ы у QR-кодов.
Описание работы алгоритма:
- Считываем изображение с помощью OpenCV и переводим изображение в черно-белый вариант. (метод ReadImage)
- Ищем Finder Pattern'ы и если находим, то выделяем их. (метод Detector)
Как мы ищем Finder Pattern'ы (метод find): Стоит заметить, что Finder Pattern'ы имеют соотношение 1:1:3:1:1. Это ключевое,
на что мы будем обращать внимание. Наша программа проходит через каждую строку и смотрит на количество белых и
черных пикселей. Каждый раз наша программа находится в 1 из 5 состояниях:
0 - черные пиксели (один край черного ободка Finder Pattern)
1 - белые пиксели (один край белого ободка Finder Pattern)
2 - черные пиксели (центральный квадрат Finder Pattern)
3 - белые пиксели (другой край белого ободка Finder Pattern)
4 - черные пиксели (другой край черного ободка Finder Pattern)
Поэтому мы идем по пикселям и проверяем верную последовательность (состояние 0 -> состояние 1 -> состояние 2 -> состояние 3 -> состояние 4). Как только пришли в состояние 4, мы проверяем соотношение 1:1:3:1:1 (метод CheckRatio) и дополнительные проверки (метод HandlePossibleCenter).
Как мы будем проверять соотношение (метод CheckRatio): Считаем полную ширину в пикселях полученного среза возможного Finder Pattern.
Она не может быть меньше 7 (любой Finder Pattern минимум 7 пикселей) и не одно из компонент ширины не может равняться 0 (0 пикселей - это значит, что не хватает компонента возможного Finder Pattern). Далее определяем ширину одной компоненты среза, то есть делим обший объем на 7. Но так как изображения могут быть под разными углами, то это ширина может иметь "ход". Определим этот ход, как половину одной компоненты среза. Далее просто преверяем, чтобы модель разности полученных компонент и высчитанных компонен был не меньше нашего "хода". Если все ок - возвращаем true. Теперь опишем дополнительные проверки (метод HandlePossibleCenter):
Будем делать 3 проверки: по вертикали, по горизонтали и по диагонали. В каждом из 3 случаем мы будем проверять соотношение, а так же улучшая положение центра нашего Finder Pattern (для последующего его выделения).
- Как работает вертикальная проверка: от полученной точки мы идем вверх и в циклах while считаем количество пикселей, которые являются белыми и черными. В случае выхода за границу возвращаем -1. Далее делаем тоже самое, но идем вниз от центра, пока не ударимся в нижнюю границу. После всего проверяем соотношение 1:1:3:1:1. Если все ок, то возвращаем новый центр, если нет, то -1.
- Как работает горизонтальная проверка: идея та же. От полученного нового центра мы идем сначала вправо и считаем белые и черные пиксели. Потом идем влево. В конце проверяем соотношение 1:1:3:1:1.
- Как работает диагональная проверка: также, только идем из центра в правый верхний угол.
Далее по полученным центрам и размерам Finder Pattern обводим его красным квадратом.
- Сохраняем картинку с обведенными Finder Pattern'ами в ту же директорию.
Результаты работы алгоритма:
- В среднем, процент ошибки состовляет ~30%.
- Столь высокий процент появляется из-за разных наклонов, теней и пр.