Есть ли эффективный алгоритм сегментации рукописного текста?

Я хочу автоматически разделить изображение древнего рукописного текста по строкам (и по словам в будущем).

Первая очевидная часть - это предварительная обработка изображения ...

Я просто использую простую оцифровку (на основе яркости пикселя). После этого я сохраняю данные в двумерном массиве.

Следующая очевидная часть - анализ двоичный массив.

  1. Мой первый алгоритм был довольно простым - если в строке массива больше черных пикселей, чем среднеквадратическое значение максимального и минимального значения , то эта строка является частью строки.

    После формирования списка строк я вырезал строки с высотой , которая меньше средней. В итоге получилась какая-то линейная регрессии, пытаясь свести к минимуму разницу между пустыми строками и текстовыми строками. (я предполагал этот факт) First results

  2. Моя вторая попытка - я пытался использовать GA несколько раз подряд функции. Хромосома содержала 3 значения - xo, x1, x2. xo [-1; 0] x1 [0; 0,5] x2 [0; 0,5]

Функция, которая определяет идентичность строки к строке (xo + α1 x1 + α2 x2)> 0 , где α1 - это масштабированная сумма черных пикселей в строке, α2 - среднее значение диапазонов между крайними черными пикселями в строке.(a1, a2 [0,1]) Еще одна функция, которую я пробовал, - это (x1 α2) и (1 / xo + [a1 x1] / [a2 x2])> 0 Последняя функция является наиболее эффективной. Results with GA Фитнес-функция - ( 1 / (HeigthRange + SpacesRange)

Где диапазон - это разница между максимумом и минимумом. Он представляет однородность текста. Глобальный оптимум этой функции - наиболее плавный способ разделить изображение на линии.

Я использую C # с моим самокодирующимся GA (классический, с двухточечным кроссовером, хромосомы с серым кодом, максимальная популяция 40, частота мутаций 0,05)

Теперь у меня закончились идеи, как разделить это изображение на строки с ~ 100 % точности.

Какой эффективный алгоритм для этого?


ОБНОВЛЕНИЕ: Исходное изображение Исходное изображение в формате BMP (1,3 МБ)


ОБНОВЛЕНИЕ2: Улучшенные результаты на этот текст на 100% Nev results

Как я это сделал:

  • исправлена ​​небольшая ошибка в счетчике диапазонов
  • изменена функция пригодности на 1 / (distanceRange + 1) * (heights Range + 1))
  • минимизирована функция классификации до (1 / xo + x2 / range)> 0 (точки в строке теперь не влияют на классификацию) (т. Е. оптимизировал входные данные и сделал оптимизацию фитнес-функций более явной)

Проблема:

Problem

GA неожиданно не смог распознать эту строку. Я посмотрел на отладочные данные функции «find rages» и обнаружил, что в «нераспознанном» месте слишком много шума. Код функции ниже:

public double[] Ranges()
{
            var ranges = new double[_original.Height];

            for (int y = 0; y < _original.Height; y++ )
            {
                ranges[y] = 0;
                var dx = new List();
                int last = 0;
                int x = 0; 

                while (last == 0 && x<_original.Width)
                {
                    if (_bit[x, y])
                        last = x;
                    x++;
                }

                if (last == 0)
                {
                    ranges[y] = 0;
                    continue;
                }

                for (x = last; x<_original.Width; x++)
                {
                    if (!_bit[x, y]) continue; 

                    if (last != x - 1)
                    {
                        dx.Add((x-last)+1);
                    }
                    last = x;
                }
                if (dx.Count > 2)
                {
                    dx.Sort();
                    ranges[y] = dx[dx.Count / 2];
                    //ranges[y] = dx.Average();
                }
                else
                    ranges[y] = 0;
            }

        var maximum = ranges.Max();
        for (int i = 0; i < ranges.Length; i++)
        {
            if (Math.Abs(ranges[i] - 0) < 0.9)
                ranges[i] = maximum;
        }
        return ranges;
}

Я использую некоторые хаки в этом коде. Основная причина - я хочу минимизировать интервал между ближайшими черными пикселями, но если пикселей нет, значение становится «0», и решить эту проблему с поиском оптимумов становится невозможно.Вторая причина - этот код меняется слишком часто. Я постараюсь полностью изменить этот код, но понятия не имею, как это сделать.

Q:

  1. Есть ли более эффективная фитнес-функция?
  2. Как найти более универсальную функцию определения?

33
задан Brock Adams 7 November 2011 в 03:05
поделиться