Извлечение свойств рукописных цифр для закрепления алгоритма ближайшего соседа - PullRequest
0 голосов
/ 22 октября 2019

У меня есть 1024-битное двоичное представление трех рукописных цифр: 0, 1, 8. В основном, в битовой карте 32x32 цифры, строки объединяются, чтобы сформировать двоичный вектор.

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

Например, я знаю, что когда сравнивается битовая карта (размер: 1024 бита) из цифр '8' и '0'. Мы должны иметь 1 в середине вектора цифры '8', поскольку там цифра 8 визуально выглядит как комбинация двух нулей, помещенных в столбец. Таким образом, наш алгоритм будет искать пересечение двух нулей (это будет середина цифры.

). Так я и хочу работать. Я хочу преобразовать низкоуровневое представление (глядя на вектор 1024 битовых карт) впредставление высокого уровня (состоящее из двух свойств, извлеченных из растрового изображения).

Любое предложение? Надеюсь, вопрос несколько ясен для аудитории.

1 Ответ

1 голос
/ 22 октября 2019

Идея 1: Flood fill

Эта идея не использует 50 паттернов, которые у вас есть на цифру: она основана на идее, что обычно «1» соединяет все 0 битов вокруг этой «1»shape, в то время как «0» отделяет 0-бит внутри него от тех, что снаружи, а «8» имеет две такие закрытые области. Таким образом, подсчет соединенных областей 0-битных данных определит, какой из трех он является.

Таким образом, вы можете использовать алгоритм заливки флудом , начиная с любого 0-битного вектора, и установить всеэти соединенные 0-биты к 1. В одномерном массиве вы должны позаботиться о том, чтобы правильно идентифицировать подключенные биты (либо по горизонтали: 1 позиция друг от друга, но не пересекая 32 границы, либо вертикально ... 32 позиции друг от друга). Конечно, эта заливка уничтожит изображение, поэтому обязательно используйте копию. Если после одного такого заполнения до сих пор осталось 0 битов (которые, следовательно, не были связаны с теми, которые вы превратили в 1), выберите один из них и начните второе заполнение там. Повторите при необходимости.

Когда все биты были установлены в 1 таким образом, используйте количество выполненных вами заливок, как указано ниже:

  1. Одна заливка? Это «1», потому что все 0 битов связаны.
  2. Два заполнения? Это «0», потому что форма нуля разделяет две области (внутри / снаружи)
  3. Три заливки? Это «8», потому что эта форма разделяет три области соединенных 0-битов.

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

enter image description here

.. тогда она не будет обозначена как "8", но" 0 ". Эта конкретная проблема может быть решена путем определения «свободных концов» в 1 бит («линия», которая останавливается). Если у вас есть два из них на небольшом расстоянии, увеличьте число, полученное в результате подсчета заливки, на 1 (как если бы эти два конца были соединены).

Аналогично, если «0» случайно имеетмаленький второй цикл, как здесь:

enter image description here

... он будет обозначен как «8» вместо «0». Вы могли бы предотвратить эту конкретную проблему, потребовав, чтобы каждая заливка находила минимальное количество 0-бит (например, не менее 10 0-бит), чтобы считаться одним.

Идея 2: вектор вероятности

Для каждой цифры сложите 50 примерных векторов, которые у вас есть, так что для каждой позиции у вас будет счет от 0 до 50. У вас будет один такой вектор «вероятности» на цифру, так что prob0, prob1 и prob8. Если prob8 [501] = 45, это означает, что весьма вероятно (45/50), что вектор «8» будет иметь 1-битный индекс 501.

Теперь преобразуем эти 3 вектора вероятности следующим образом: вместо сохранения количества на позицию сохраняйте позиции в порядке уменьшения количества (вероятности). Таким образом, если prob8 [513] имеет наибольшее значение (например, 49), то этот новый массив должен начинаться как [513, ...]. Давайте назовем эти новые векторы A0, A8 и A1 (для соответствующей цифры).

Наконец, когда вам нужно сопоставить заданный входной вектор, одновременно проходите через A0, A1 и A8 (всегда просматривая один и тот же индексв трех векторах) и сохранить 3 балла. Когда входной вектор имеет 1 в положении, указанном в A0 [i], тогда прибавьте 1 к Score0. Если он также имеет 1 в позиции, указанной в A1 [i] (то же самое i ), то добавьте 1 к Score1. То же самое для Score8. Увеличьте i и повторите. Остановите эту итерацию, как только у вас будет явный победитель, т. Е. Когда наивысший балл среди оценок 0, 1 и 8 превысит пороговую разницу со вторым по величине среди них. В этот момент вы знаете, какая цифра представляется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...