Точная классификация бинарных изображений

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

Вход, который я получаю, подобен этому (это отдельные буквы):

enter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description here

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

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

Кто-нибудь знает, какой будет хороший алгоритм для этого?

Мои идеи были (после нормализации изображения):

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

Любая помощь будет оценена!

Ответ 1

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

Извлечение функций

С первого взгляда эта часть выделения компонентов выглядит как хороший сценарий для Hu-Moments. Просто вычислите моменты изображения, затем вычислите cv:: HuMoments от них. Тогда у вас есть 7-мерное вещественное пространственное пространство (один вектор функции на изображение). В качестве альтернативы вы можете опустить этот шаг и использовать каждое значение пикселя как отдельную функцию. Я думаю, что предложение в этом ответе идет в этом направлении, но добавляет сжатие PCA, чтобы уменьшить размерность пространства функций.

Классификация

Что касается части классификации, вы можете использовать почти любой алгоритм классификации, который вам нравится. Вы можете использовать SVM для каждой буквы (двоичная классификация да-нет), вы можете использовать NaiveBayes (какова максимальная вероятная буква), или вы можете использовать подход k-NearestNeighbor (kNN, минимальное пространственное расстояние в пространстве объектов) например flann.

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

Оценка

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


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

Ответ 2

Это проблема распознавания. Я лично использовал комбинацию PCA и технику машинного обучения (вероятно, SVM). Это довольно большие темы, поэтому я боюсь, что не могу слишком много выработать, но здесь самый простой процесс:

  • Соберите свои обучающие изображения (более одного на каждую букву, но не сходите с ума).
  • Обозначьте их (может означать много вещей, в этом случае это означает группировать буквы в логические группы - все изображения A → 1, все B-изображения → 2 и т.д.).
  • Обучите свой классификатор
    • Запустите все через разложение PCA
    • Проецируйте все ваши обучающие изображения в пространство PCA.
    • Запустите проецируемые изображения через SVM (если это одноклассный классификатор, делайте их по одному, в противном случае все они сразу).
    • Сэкономьте данные собственного собеседника PCA и SVM.
  • Выполнить распознавание
    • Загрузка в пространство PCA
    • Загрузите данные обучения SVM.
    • Для каждого нового изображения проецируйте его в пространство PCA и попросите SVM классифицировать его.
    • Если вы получите ответ (число), верните его в письмо (1 → A, 2 → B и т.д.).

Ответ 4

У меня была аналогичная проблема несколько дней назад. Но это было распознавание цифр. Не для алфавитов.

И я реализовал простое OCR для этого, используя kNearestNeighbour в OpenCV.

Ниже приведена ссылка и код:

OCR распознавания простого знака в OpenCV-Python

Внедрите его для алфавитов. Надеюсь, что это сработает.

Ответ 6

Вы можете попробовать создать модель, загрузив свои учебные данные (~ 50 изображений из 1s, 2s, 3s.... 9s) в demo.nanonets.ai (бесплатно использовать)

1) Загрузите данные для обучения здесь:

demo.nanonets.ai

2) Затем запросите API, используя следующий (код Python):

import requests
import json
import urllib
model_name = "Enter-Your-Model-Name-Here"
url = "http://images.clipartpanda.com/number-one-clipart-847-blue-number-one-clip-art.png"
files = {'uploadfile': urllib.urlopen(url).read()}
url = "http://demo.nanonets.ai/classify/?appId="+model_name
r = requests.post(url, files=files)
print json.loads(r.content)

3) ответ выглядит так:

{
  "message": "Model trained",
  "result": [
    {
      "label": "1",
      "probability": 0.95
    },
    {
      "label": "2",
      "probability": 0.01
    },

     ....

    {
      "label": "9",
      "probability": 0.005
    }
  ]
}

Ответ 7

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

С 5 образцов на письмо, вы уже можете иметь полный охват.

Я организовал свою работу, поставив отметку в начале имени файла изображения. Затем я мог бы сортировать по имени файла (= идентификатор). Проводник Windows позволяет просматривать каталог с включенными средними значками. Я получал бы идентификатор с помощью действия 'fake-rename' и копировал его в программу Python.

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

def getLetter(im):
    area = im.height * im.width
    white_area = np.sum(np.array(im))
    black_area = area - white_area
    black_ratio = black_area / area           # between 0 and 1
    if black_ratio == .740740740740740 or \
       black_ratio == .688034188034188 or \
       black_ratio == .7407407407407407:  
       return 'A'
    if black_ratio == .797979797979798:
       return 'T'
    if black_ratio == .803030303030303:
       return 'I'
    if black_ratio == .5050505050505051 or \
       black_ratio == .5555555555555556:
       return 'H'
    ############ ... etc.

    return '@' # when this comes out you have some more work to do

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