1. Вы находитесь в архивной версии форума xaker.name. Здесь собраны темы с 2007 по 2012 год, большинство инструкций и мануалов уже неактуальны.
    Скрыть объявление

Работа с графикой && PHP капча

Тема в разделе "PHP, Perl, web-программирование", создана пользователем Hookman, 29 июл 2010.

  1. Hookman

    Hookman Developer Глобальный модератор

    Регистрация:
    4 окт 2008
    Сообщения:
    93
    Симпатии:
    220
    Баллы:
    0
    Начинаю постепенно добираться до темы распознавания каптчи. Первой проблемой на моем пути оказалось банальное неумение работать с графикой в php
    Изучить основные функции задача не сложная, но нужная. К тому же, используя только их можно получить довольно интересные результаты.

    Приступаем.

    Работа с графикой в php, в большинстве случаев, проходит в 3 этапа:
    1. Создание изображения
    2. Обработка изображения
    3. Вывод изображения.

    PHP:
    <?
        
    header("Content-type: image/png");
        
    $img imagecreate(100100);
        
    $white imagecolorallocate($img255255255);
        
    $black imagecolorallocate($img0,0,0);
        
    imagecolortransparent($img$white);
        
    imagesetpixel($img5050$black);
        
    imagepng($img);
    ?>
    В результате выполнения этого скрипта в браузере появится белый квадрат с черной точкой посередине.

    Первая строка

    PHP:
    header(”Content-typeimage/png”); 
    /*нужна для того чтобы браузер показал картинку, а не ее текстовое представление (набор байтов текстом).*/
    Далее разберу по этапам.

    Создание изображения

    Создание изображения в php происходит либо через создание нового изображения, либо через чтение какой-то картинки из файла.

    PHP:
    $img imagecreate(100100);
    /*Здесь оно создается функцией imagecreate, которой передаются только размеры нужного изображения.*/
    Обработка изображения.

    В библиотеке gd есть очень много функций для работы с графикой в php. Рассмотрю пока только те функции которые использованы в примере.

    Дальше идут непонятные строки на первый взгляд

    PHP:
    $white imagecolorallocate($img255255255);
        
    $black imagecolorallocate($img0,0,0);
    Дело в том, что в php идентификатором любого цвета является число. Цвет определяется через RGB-модель. То есть определяется набором трех чисел для красного, зеленого и синего. Каждого число определяет, как много цвета должно входить в результирующий.

    Для белого цвета это тройка будет (255,255,255).

    Для того чтобы каждый раз не вызывать функцию imagecolorallocate, в скриптах цвета, которые часто используются, сохраняют в переменные (я так сделал для $white).

    Кстати, насчет функции

    imagecolortransparent($img, $white);

    Если вы создаете изображение в php через создание нового изображения (…:) ), то нужно указывать для него прозрачный цвет. То есть указать в качестве такого можно любой цвет, но при отображении он будет прозрачным везде, где использовался.

    Теперь ставим черную точку с координатами (50,50).

    PHP:
    imagesetpixel($img5050$black);
    Вывод изображения

    Вывод изображения производится либо в браузер, либо в файл.

    Я вывожу в браузер:

    imagepng($img);

    Тип файла учитывается в этой функции и в указании HTTP-заголовка в самом начале.
    Можно и там и там сделать вместо png – jpg, gif, jpeg.

    Ну и для демонстрации еще некоторых функций покажу еще один пример – функция для генерации шума черного цвета на изображении. В качестве параметра ей передается id изображения и процент зашумления.
    PHP:
    <?php
        header
    ("Content-type: image/png");
        
    $img imagecreate(100100);
        
    $white imagecolorallocate($img255255255);
        
    imagecolortransparent($img$white);
        
    noise_image($img15);
        
    imagepng($img);


        function 
    noise_image($img$per) {
        
            
    $width  imagesx($img);
            
    $height imagesy($img);
            
    $black imagecolorallocate($img0,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);

            }

        }
    ?>
    А вот результат его выполнения:
    [​IMG]

    ===============================================

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

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

    Задачу распознавания любого образа (в том числе и капчи) можно разделить на несколько этапов:
    1. Восприятие образа
    2. Предварительная обработка
    3. Выделение характеристик
    4. Классификация

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

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

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

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

    Шум.

    Начать я решил с точечного шума.
    У точечного шума есть несколько характеристик:
    Цвет
    Процент зашумления (плотность шума)

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

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

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

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

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

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

    Такая картинка создается скриптом:
    PHP:
    <?php
        header
    ("Content-type: image/gif");
        
    $img   imagecreate(200100);
        
    $white imagecolorallocate($img255255255);
        
    $black imagecolorallocate($img000);
        
    imagecolortransparent($img$white);
        
    imagestring($img52020'TEXT'$black);
        
    noise_image($img10);
        
    imagegif($img'noise.gif');


        function 
    noise_image($img$per) {
        
            
    $width  imagesx($img);
            
    $height imagesy($img);
            
    $black imagecolorallocate($img0,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 точек двух цветов, то первое что нужно сделать – это определить какие точки являются лишними. Какими признаками они обладают? Чем они отличаются от тех пикселей, из которых сделан текст?

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

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

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

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

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

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

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

    [​IMG]

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

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

    [​IMG]

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

    (c)i-novice.net
     
    2 пользователям это понравилось.
  2. lytgeygen

    lytgeygen pacifiste maniaque ..::V.I.P::..

    Регистрация:
    13 окт 2008
    Сообщения:
    431
    Симпатии:
    244
    Баллы:
    0
    Hookman,
    сам писал статью ?
     
  3. Hookman

    Hookman Developer Глобальный модератор

    Регистрация:
    4 окт 2008
    Сообщения:
    93
    Симпатии:
    220
    Баллы:
    0
    Внизу копирайт.
     
  4. b3

    b3 Продвинутый

    Регистрация:
    8 окт 2007
    Сообщения:
    142
    Симпатии:
    104
    Баллы:
    0
    Из названия я ожидал увидеть тут статью о Нейронных сетях =)
     
  5. pigata

    pigata Новичок

    Регистрация:
    3 май 2011
    Сообщения:
    7
    Симпатии:
    0
    Баллы:
    0
    great tuto. But for anny applications i use a captcha who is allready created :)
     

Поделиться этой страницей