Классификация изображений в питоне - PullRequest
16 голосов
/ 11 октября 2010

Я ищу метод классификации отсканированных страниц, которые в основном состоят из текста.

Вот подробности моей проблемы. У меня есть большая коллекция отсканированных документов, и мне нужно обнаружить наличие определенных типов страниц в этих документах. Я планирую «разбить» документы на страницы их компонентов (каждая из которых представляет собой отдельное изображение) и классифицировать каждое из этих изображений как «A» или «B». Но я не могу найти лучший способ сделать это.

Подробнее:

  • У меня есть многочисленные примеры изображений "A" и "B" (страницы), поэтому я могу заниматься под наблюдением.
  • Мне неясно, как наилучшим образом извлечь функции из этих изображений для обучения. Например. Что это за особенности?
  • Страницы иногда слегка поворачиваются, поэтому было бы неплохо, если бы классификация была несколько нечувствительной к повороту и (в меньшей степени) масштабированию.
  • Я бы хотел кроссплатформенное решение, в идеале в чистом Python или с использованием общих библиотек.
  • Я думал об использовании OpenCV, но это похоже на «тяжеловесное» решение.

EDIT:

  • Страницы "A" и "B" отличаются тем, что на страницах "B" есть формы с одинаковой общей структурой, включая наличие штрих-кода. Страницы "A" являются свободным текстом.

Ответы [ 4 ]

9 голосов
/ 11 октября 2010

Я отвечу в 3 частях, поскольку ваша проблема явно большая, и я очень рекомендую ручной метод с дешевой рабочей силой, если количество страниц не превышает 1000.

Часть 1: Извлечение функций - в поле обнаружения объекта вы можете выбирать из множества объектов. Поскольку одним из ваших требований является неизменность вращения, я бы порекомендовал класс функций SIFT / SURF. Вы также можете найти уголки Харриса и т.д. Решение о том, какие функции использовать, может потребовать экспертных знаний, и если у вас есть вычислительные мощности, я бы порекомендовал создать хороший набор функций и передать его через оценщик важности, основанный на обучении.

Часть 2: Выбор классификатора - я большой поклонник классификатора Random Forest . Концепция очень проста для понимания, она очень гибкая и непараметрическая. Для настройки требуется очень мало параметров, и вы также можете запустить ее в режиме выбора параметров во время контролируемой тренировки.

Часть 3: Реализация - Python по сути является клеевым языком. Чистая реализация Python для обработки изображений никогда не будет очень быстрой. Я рекомендую использовать комбинацию OpenCV для обнаружения признаков и R для статистической работы и классификаторов.

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

4 голосов
/ 11 октября 2010

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

OpenCV высоко оптимизирован, и ваша проблема не из легких.

[ГЛОБАЛЬНОЕ РЕДАКТИРОВАНИЕ: реорганизация моегоидеи]

Вот несколько идей о функциях, которые можно использовать:

  • Для определения штрих-кодов вам, возможно, следует попытаться выполнить дистанционное преобразование (DistTransform в OpenCV), еслиштрих-код изолирован.Возможно, вам удастся найти интерес с помощью match или matchShapes.Я думаю, что это возможно, потому что штрих-коды должны иметь одинаковую форму (размер и т. Д.).В качестве признака можно использовать оценку баллов интереса.

  • Здесь могут быть полезны моменты изображения, поскольку у вас есть различные типы глобальных структур.Этого может быть достаточно для различения страниц A & B (см. там для функции openCV) (кстати, вы получите инвариантные дескрипторы :))

  • Возможно, вам следует попытаться вычислить vertical gradient и horizontal gradient.Штрих-код - это определенное место, где vertical gradient == 0 и horizontal gradient! = 0.Это главное преимущество - низкая стоимость этих операций, поскольку ваша цель - только проверить, есть ли такая зона на вашей странице.Вы можете найти интересующую зону и использовать ее оценку как функцию

Как только у вас появятся ваши функции, вы можете попробовать supervised learning и проверить обобщение.Ваша проблема требует очень мало false negative (потому что вы собираетесь выбросить несколько страниц), поэтому вы должны оценить свою производительность с помощью кривых ROC и внимательно посмотреть на чувствительность (которая должна быть высокой).Для классификации вы можете использовать регрессию с лассо-штрафом, чтобы найти лучшие характеристики.Пост Whatnick также дает идеи товаров и другие дескрипторы (возможно, более общие).

3 голосов
/ 11 октября 2010

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

  1. извлечение элемента (компьютерное зрение): найти точки интереса или линии, которые будут характерными для штрих-кодов, а не текста.1008 *

  2. двоичная классификация (статистическое обучение): определите, имеется ли штрих-код, на основе извлеченных признаков.


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


О втором шаге наиболее полезные классификации будут основаны на:

  • k ближайших соседей
  • логистическая регрессия
  • случайный лес (действительно хорошо реализован в R, но я не знаю насчет Python)
0 голосов
/ 13 декабря 2016

Вы можете попробовать построить модель, загрузив данные о тренировках А и В в demo.nanonets.ai (бесплатно)

1) Загрузить данные о тренировках здесь:

demo.nanonets.ai

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

import requests
import json
import urllib
model_name = "Enter-Your-Model-Name-Here"
url = "https://cdn.pixabay.com/photo/2012/04/24/12/13/letter-39694_960_720.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": "A",
      "probability": 0.97
    },
    {
      "label": "B",
      "probability": 0.03
    }
  ]
}
...