Учимся распознавать капчу. Убираем шум.

В конце первой статьи про работу с графикой в php я приводил в качестве примера небольшую функцию для генерации шума. На самом деле, я ее привел не случайно :)
В большинстве капч используется очень много методов, которые затрудняют ее распознавание скриптом. И шум является один из таких методов.

Все кто часто пользуется Интернетом, наверняка, повидали немало разных капч. У всех них есть свои методы защиты. И для каждого метода защиты есть свои методы распознавания капч :)

Задачу распознавания любого образа (в том числе и капчи) можно разделить на несколько этапов:

  1. Восприятие образа
  2. Предварительная обработка
  3. Выделение характеристик
  4. Классификация

На первом этапе, в нашем случае, надо будет просто считать картинку в память.

На втором этапе удаляются шумы, производится перевод изображения в черно-белый цвет, удаляются ненужные части изображения.

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

А на четвертом этапе уже приходят к выводу, что же все-таки изображено на картинке.

Шум.

Начать я решил с точечного шума.
У точечного шума есть несколько характеристик:

  1. Цвет
  2. Процент зашумления (плотность шума)

Цвет обычно делают таким же, как и цвет шрифта, которым написан значимый текст (текст который надо распознать).
Если цвет шума не совпадает с цветом текста, то шум убирается элементарно – на картинке оставляют только те пиксели, которые имеют цвет шрифта.

Более детально нужно рассмотреть удаление шума, когда его цвет такой же, как и у текста.

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

Ну ладно, суть понятна короче.
Приступим к практическим занятиям :)

Предположим у нас есть такая вот картинка.

Добавим текст, который нужно будем потом распознать.
Получим такую картинку.

Такая картинка создается скриптом:

<?php
    header("Content-type: image/gif");
    $img   = imagecreate(200, 100);
    $white = imagecolorallocate($img, 255, 255, 255);
    $black = imagecolorallocate($img, 0, 0, 0);
    imagecolortransparent($img, $white);
    imagestring($img, 5, 20, 20, 'TEXT', $black);
    noise_image($img, 10);
    imagegif($img, 'noise.gif');


    function noise_image($img, $per) {
   
        $width  = imagesx($img);
        $height = imagesy($img);
        $black = imagecolorallocate($img, 0,0,0);
        $noise_dots = round($width*$height*$per/100);
       
        for ($i = 0; $i < $noise_dots; $i++) {
            $x = rand(0,$width);
            $y = rand(0,$height);

            imagesetpixel($img, $x, $y, $black);

        }

    }
?>

Я поставил процент зашумления в 10%.

Теперь нужно подумать. Как же можно убрать эти лишние точки?
Если представить, что перед нами просто таблица 200*100 точек двух цветов, то первое что нужно сделать – это определить какие точки являются лишними. Какими признаками они обладают? Чем они отличаются от тех пикселей, из которых сделан текст?

От того, насколько точно будут определенный критерии шума, настолько же точно он будет удален :) Если критерий будет не продуманным, то вместо чистого текста в результате на картинке останется то, что даже человек распознать уже не сможет (если вообще останется что распознавать).

Итак, первый очевидный критерий лишнего пикселя – это то, что вокруг него все соседние пиксели являются белыми, то есть не такими как он.

Перебирая каждый пиксель изображения, на каждом шаге у нас будет одна и та же ситуация:

В центре будет текущий символ. Соседние клетки (пиксели) будем проверять на наличие, клеток того же цвета, что и центральная. Если таких не будет, то пиксель окрашивается в цвет других клеток.

Но этот критерий слишком жесткий, так как даже при 10%-ом шуме получается так, что шумовые пиксели оказываются в соседних клетках. То есть в одной такой таблице (смотри выше) могут быть две клетки и обе относятся к шуму.

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

Например, так:

Здесь можно скачать программы для генерации шума и его очищения, которые использовались в статье : Антишум.

А эффект от его применения этого алгоритма примерно такой:

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

Ну, вот и все. Пока. Спасибо всем кто прочел. :)
Novice.



Теги: ,


Читайте также:



10 Ответов на “Учимся распознавать капчу. Убираем шум.”

  1. То, что надо, весьма информативно. Так держать! Жду следующих выпусков на тему “напишем капчеломалку” :)

  2. novice

    Спасибо! Тема очень большая и интересная. Статей будет много, я думаю :)

  3. Какой-то плагин тестишь? :) Каждый пост называется Hello World :)

  4. novice

    😀 Включил старый плагин здесь и забыл выключить :) Спасибо, что напомнил - оповещение на email пришло.

  5. А дальше про капчу будет? Я что то статей не нашел (

  6. novice

    Тут исследовательскую работу проводить надо. На это уходит много времени. Вполне возможно, что я еще вернусь к теме анализа изображений. :)

  7. xnmv

    Дружище ты молодец.
    Почени свой rss = )
    очень хочеться на тебя подписаться

  8. Виталий

    Как говорится, всё гениальное просто. Натолкнуло на новую пищю для размышлений, спасибо! :)

  9. Хрень какая-то!

  10. Алень

    Jobs - ты днина =)


© Copyright. . I-Novice. All Rights Reserved. Terms | Site Map