Распознаём капчу PHPBB2


Пропалю алгоритм распознавания капчи PHPBB2 🙂

Хотя конечно тут «палева» особого нет — всем и так всё видно и если поднапречься думаю каждый, при наличии базовых навыков PHP или какого нибудь другого языка программирования, сможет придумать и реализовать подобный алгоритм.

Ладно, приступим !

На входе имеем стандартную phpbb2 капчу (графический PNG файл , пусть будет такая:

captcha

На выходе хотелось бы получить строчку из 6ти символов KXLDXL 🙂

Вступление

Пойдем от простого к сложному — как сравнить две однопиксельные картинки ? Допустим чёрная — единичка, белая — нуль. Правильно: оцифровываем и вычитаем, т.е. преобразовали картинку в циферку $in — если (1-$in)==0 имеем чёрную картинку т.е. единичку. В реализуемом алгоритме именно так и будем делать, только сравнивать будем массивы с эталонными массивами и выбирать тот где расхождение минимально.

Что потребуется

Для сего действа нам понадобится эталонный набор символов для используемых в кодировании- это циферки от 1 до 9 (нуля нет — чтоб не путать с буквой О) и буковки от A до Z одинаковой размерности (как его получить — чуть позже …). Предположим он у нас есть — 35 png файлов, для каждой буквы свой файлик. Например буква G

g.png

Так же понадобится установленная библиотека GD2 (считаем что реализовывать будем на PHP), хотя думаю данная библиотечка (или аналогичная для работы с изображениями) имеется и для других языков. Библиотека нужна только для того чтоб преобразовывать изображения в матричное представление. Т.е. изображение NхM (N высота M ширина) преобразовывается в матрицу (двумерный массив) NхM (N строк M столбцов) каждый элемент которой — пиксель в изображении.

Как вы уже догадались все дальнейшие преобразования будут вестись уже с матрицами, поэтому неплохо было бы обзавестись классом для работы с матрицами (я такого не нашел, поэтому пришлось написать свой). Какие именно функции понадобятся поймете на шаге программирования алгоритма :).

0. Загружаем эталонные символы

Будем считать что эталонные символы у нас уже есть (как и где их получить — чуть позже). Загружаем в поле объекта класса его конструктором на лету преобразовывая изображение в матрицу (двумерный массив). Загружаем именно так чтоб данный набор всегда был в памяти и каждый раз не повторять эту операцию.

1. Получаем символы для сравнения с эталонными

Получаем запросом капчу, преобразуем в матрицу, убираем шум в два этапа —

Переводим в черно белый: выбирается среднее значение (экспериментально подбираем константу)- если обрабатываемое больше среднегоо ставим 1, если меньше 0)

Сглаживаем (одиночные и двоичные нули делаем единичками, единички делаем нулями

Вычленяем символы для распознавания из всего изображения (в цикле сначала разбиваем по вертикали, потом по горизонтали) по условию — если 2 и более подряд идущих столбца(строки) в сумме дают больше чем (константа — допустим 3 или 4) — считаем что пошла буква — запихиваем её в массив, в итоге получаем массив из 6ти символов. (говоря символ на самом деле имеем матрицу т.е. массив чисел).

Далее доводим размерность полученных символов до эталонной, для этого нам нужно знать с какой стороны добавить пустой столбец(строку). Это делается путём определения центра масс изображения и в зависимости куда он попадает добавлять именно в ту сторону. Поясню — допустим эталонная размерность 40х40 (из за какой нибудь толстой буквы W или G или M), а на входе имеем букву L — наш алгоритм вычленил её из начальной капчи у неё размерность (25х37). Как её довести до 40×40? вот именно с использованием центра масс и доводим. /Вот на этом этапе можно сохранять получившиеся символы и выбирать из них эталонные — муторно конечно, т.е. нужно наформировать 35 разных … но с другой стороны универсальнее и проще чем разбираться в каком формате храняться символы в конкретном движке, других минусов я не вижу — быстродействие думаю от такого представления не уменьшится/

Ну и наконец то:

2. Определяем символы

Сравниваем обрабатываемые символы с эталонными и выбираем те, где разница минимальна.

Для ускорения обработки можно задать максимальный минимум 🙂 т.е. значение ниже которого — уже с большой вероятностью имеем эталон. (допустим обрабатываем цифру 2 — она в массиве эталонов идёт второй по счёту, в результате вычитания получили число 25 (а для всех других на тестах было больше 100), допустим экспеприментально выявили константу 60 (максимальное количество несовпадений). Т.е. получив значение 20 (меньше константы) дальше можно не сравнивать и признать распознаваемый символ эталонным на данном шаге.

Всё ! Ошибок в работе скрипта (неправильное определение) я на стадии тестирования не выявил ни одной.

p.s. Имхо такие вещи нужно на c++ реализовывать и подключать к php уже в виде готового модуля, но что то пока руки не дойдут до такой реализации. Ну и конечно интересно потестить скорость разных реализаций разных алгоритмов для определённых капч, типа померяться реализация чьего алгоритма самая быстрая ?! — хотя тут тоже субъективно: один и тот же алгоритм два разных программиста очень по разному в плане быстродействия могут реализовать… а я себя не считаю профессионалом в PHP 🙂

p.p.s

Эталонные символы из моего скрипта (к нужному виду доведёте сами) — набора два, исторически так сложилось …

С помехами

Без помех


30 комментариев на «“Распознаём капчу PHPBB2”»

  1. Сломай кептчу дигга 😀

    )))

    при повышении контаста +100 и brightness +30 остается проблема разворота букв и цифр..

  2. Если бы шрифт использовали одинаковый можно было попробовать — а так понт 🙁

  3. хотя немного усложнив теоретически можно, добавив
    1. все используемые шрифты
    2. нормализация по наклону — эталонизировать всё по углу наклона центра масс (крутить пока цент масс не окажется в нижней точке)
    3. нормализация по размеру шрифта (увеличивать или уменьшать до определённого веса)

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

  4. А это ваш способ, или тот который был использованн командой thehack.kz?

  5. А не могли бы Вы выложить класс преобразования изображения в матрицу о котором идёт речь в этой статье

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

    Во-первых возникли проблемы при написании класса — очень долгая обработка и не хотелось бы изобретать велосипед.
    Спасибо.

  6. Для преобразование изображения в матрицу (массив) никакой класс не нужен — это выполняется двумя функциями imagecreatefrompng (из файла) и imagecreatefromstring (из потока) библиотеки GD.

    Класс я писал уже для матричных преобразований и понятен он будет только мне 🙂 хоть сложного там ничего и нет, но я умудрился всё усложнить для понимания, так что всё таки лучше сам пиши — если будут вопросы — помогу.

  7. Да это понятно про imagecreatefrompng
    Не могу составить саму сетку с цветами этот момент не очень ясен.

  8. аа вон ты о чём …
    я так делал

    $matrix[$x][$y] = array_sum(imagecolorsforindex($img, ImageColorAt($img, $x, $y)));

  9. разобрался, разбил буквы.
    Сравнение Вы делали по 4 точкам как я понимаю?

  10. >Сравнение Вы делали по 4 точкам как я понимаю?
    почему это по 4м? по всем — для этого собственно и центрирую и довожу до одинакового размера — а как это по 4м ?

    свои эталонные выкладываю …

  11. Алгоритмы раскодировки они бы ещё открыли — было бы супер

  12. А почему у Вас в эталонах без шумов доведённых до одинаковой размерности 40×40, символы находятся не по центру. Как Вы так доводили их и как можете сравнивать, ведь каждый раз капча выдаёт символы на разной высоте.

  13. косячёк в алгоритме — если центр масс слева то добавлять нужно было слева, а я справа — впринципе на итог не влияет, если и там и сям придерживаться одного алгоритма выравнимания.

  14. Продвижение, оптимизация сайтов.
    Реклама по: форумам, доскам объявлений, сайтам знакомств.

    Контакты:
    ICQ: 393-513
    e-mail: bary_m@mail.ru

  15. Всем привет !!

    Вероятно я не в тему тут, но больно уж интересует вопрос, где можно заработать в интернет ?

    Пробовала много различных способов, таких как клики, Nocs, регистрации, да к сожалению заработала всего несколько долларов.

    Вот и хотелось узнать, может кто поможет девушке — бросит пару ссылок на хорошие компании. Только лишь, пожалуйста, никаких MLM и волшебных кошельков.

  16. привет!

    >клики, Nocs, регистрации
    где и как пробовала если не секрет ?

    и куда собственно бросить пару ссылок ?

    p.s. хоть и баян, но всё таки надо статейку для новичков оформить а ля «Заработок в интернете», а пока статья не написана рекомендую ознакомиться со следующим материалом от Даниила «Способы заработка в Рунете»

  17. ну частенько все возможно, но важно целесообразна ли такая затея? некоторые капчи *очень* трудно распознать!

  18. блин хочу распознать капчу блогспота…. как бы, а?

  19. ЗАХОДИТЕ! ТУТ ВСЕ ОПИСАНО. http://doxodgold.ru вчера 56 баксов заработал. Лучше сохраните эту ссылку. просто админ может
    удалить. всетаки спам))

  20. Похоже где то вылезла страничка по собирательным запросам типа phpbb — лезет конкретный спам, поэтому комментарии в данной ветке вынужден отключить.

  21. Все — «Всегда Последнего» починил — закрываю комменты !

  22. Самое обсуждаемое на блогах:
    Косовo
    Фидель ушёл в отставку
    Умер Егoр Летов