Распознаватель капчи – API rucaptcha.com. Описание методов для пересылки изображений для распознавания и получение результата расшифровки. OCR API. Решение ReCaptcha

Содержание

Распознавание и взлом CAPTCHA | Капча

Здравствуйте!

В этой статье, пойдет речь, о еще нескольких приемах распознавания captcha защиты. Эти приемы я буду демонстрировать на подопытной капче. В качестве подопытной я выбрал капчу некоего Rafontes на которую я набрел когда искал материалы для предыдущей статьи Анализ алгоритмов генерации CAPTCHA.

Пример сгенерированной капчи:

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

Препроцесс

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

В первую очередь нам надо отделить фон от текста. Анализируем картинку и код генерации изображения. Налицо первые ошибки:

  • Используется один цвет для всего теста с кодом
  • Цвет для текста генерируется в диапазоне rand(0, 200), 0, rand(0, 200), для R G B соответственно (достаточно выделить цвета только в этом диапазоне)
  • Фон с большим количеством разных цветов (не сможет повлиять на статистику самого часто используемого цвета)

Теперь на основе этих фактов анализируем цвет каждого пикселя во всем изображении и выделяем самый часто-используемый. Получился 8C0074 (в hex-виде). Задаем от него небольшую погрешность и выделяем этот цвет и немного похожие на него с учетом погрешности. Все выделенные закрашиваем черным, остальные белым. Получается такая картинка:

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

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

Теперь определяем границы по вертикали:

Линия осталась тут потому что то тот участок до сих пор воспринимается функцией как очень темный участок. Но теперь на основе этих границ уточняем их по второму кругу, по горизонтали:

А почему теперь эта линия убралась спросите вы? Потому что теперь анализировалось меньше «столбцов пикселей» и при анализе алгоритмом выявилось что в данном участке слишком много столбцов с одним черным пикселем, а следовательно это шум. Теперь уточняем границу по вертикали:

Так как область определения стала меньше то, теперь тот та линия что была шумом стала недостаточно темным пятном и была удаленна  совсем. Вот мы и получили участок с текстом. Конечно этот алгоритм иногда не совсем верно выделяет нужную область. Но по моим тестам число НЕверных определений не превышает 5%, чем собственно можно пренебречь.

Сегментация

Теперь наша задача разбить полученное изображение на отдельные участки с символами.

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

  • Отступ между каждым символом всегда равен 15 пикселям

Конечно иногда из за размера символов они выходять за рамки пятнадцати пикселей, тогда приходится откусывать от соседнего символа еще один-два пикселя. Но это не критично. Вообщем разбиваем картинку:


Теперь как мы видим вокруг некоторых символов есть пустая область. А нам все таки нужен именно сам символ. Применяем функцию обрезки для каждого символа, и полученные изображения вписываем в прямоугольники размером 17×27:

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

Распознавание

Распознавание мы будет производить БЕЗ всяких новомодных нейронных сетей. Почему? Решающую роль сыграло то что, нет ни одной достойной библиотеки под винду. Пользоваться будем обычным распознаванием по маскам символов.

Для этого мы, имея доступ к исходным кодам, нагенерируем кучу черно-белых картинок для каждого символа с разными углами поворотов (от двух до четырех градусов), и разными размерами шрифта (от 20pt до 30pt). Каждую полученную картинку, как вы догадались, вписываем в прямоугольник размером 17×27. Каждое полученное изображение называется маской.

Для каждой буквы я нагенерировал по 10-15 масок. Впринципе этого достаточно, но если увеличить количество масок, то можно увеличить процент распознавания.

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

Результаты

Для теста я получил с помощью генерации картинки и ее разбиения на символы 200 зашумленных символов. И програмно запустил тест. И внимание!
Итог: Удачных: 172 Ошибок: 28 Процент: 86%
То есть каждый символ на капче будет распознан успешно с вероятностью в 86%!

Немного математики. Посчитаем процент вероятности успешного распознавания капчи:
Для 4-символьных капч: 0.86^4=54%
Для 5-символьных капч: 0.86^5=47%

В среднем каждая вторая капча будет успешно распознанна.

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

Исходники

Архив со скриптами (на php):
CaptchaBreaker_scripts
Архив масок (распаковать в папку ./masks/):
CaptchaBreaker_masks

Скрипт сам генерирует, и сам же распознает капчу. Пример работы скрипта на картинке приведенной в качестве примера автором капчи:

(Картинка кликабельна)

Декодирование капчи на Python / Habr

Это перевод и форма повествования от первого лица сохранена. Автор — Бен Бойтер, бакалавр информационных технологий в Университете Чарльза Стерта (CSU).

Большинство людей не в курсе, но моей диссертацией была программа для чтения текста с изображения. Я думал, что, если смогу получить высокий уровень распознавания, то это можно будет использовать для улучшения результатов поиска. Мой отличный советник доктор Гао Джунбин предложил мне написать диссертацию на эту тему. Наконец-то я нашел время написать эту статью и здесь я постараюсь рассказать о всем том, что узнал. Если бы только было что-то подобное, когда я только начинал…

Как я уже говорил, я пытался взять обычные изображения из интернета и извлекать из них текст для улучшения результатов поиска. Большинство моих идей было основано на методах взлома капчи. Как всем известно, капча — это те самые всех раздражающее штуки, вроде «Введите буквы, которые вы видите на изображении» на страницах регистрации или обратной связи.

Капча устроена так, что человек может прочитать текст без труда, в то время, как машина — нет (привет, reCaptcha!). На практике это никогда не работало, т. к. почти каждую капчу, которую размещали на сайте взламывали в течение нескольких месяцев.

У меня неплохо получалось — более 60% изображений было успешно разгадано из моей небольшой коллекции. Довольно неплохо, учитывая количество разнообразных изображений в интернете.

При своем исследовании я не нашел никаких материалов, которые помогли бы мне. Да, статьи есть, но в них опубликованы очень простые алгоритмы. На самом деле я нашел несколько нерабочих примеров на PHP и Perl, взял из них несколько фрагментов и получил неплохие результаты для очень простой капчи. Но ни один из них мне особо не помог, т. к. это было слишком просто. Я из тех людей, которые могут читать теорию, но ничего не понять без реальных примеров. А в большинстве статей писалось, что они не будут публиковать код, т. к. боятся, что его будут использовать в плохих целях. Лично я думаю, что капча – это пустая трата времени, т. к. ее довольно легко обойти, если знать как.

Собственно по причине отсутствия каких-то материалов, показывающих взлом капчи для начинающих я и написал эту статью.

Давайте начнем. Вот список того, что я собираюсь осветить в этой статье:

  • Используемые технологии
  • Что такое капча
  • Как найти и извлечь текст из изображений
  • Распознавание изображения с использованием ИИ
  • Обучение
  • Собираем все вместе
  • Результаты и выводы
Используемые технологии

Все примеры написаны на Python 2.5 с использованием библиотеки PIL. Должно работать и в Python 2.6 (под Python 2.7.3 отлично запускается, прим. перев.).

Установите их в указанном выше порядке и вы готовы к запуску примеров.

Отступление

В примерах я буду жестко задавать множество значений прямо в коде. У меня нет цели создать универсальный распознаватель капч, а только показать как это делается.
Капча, что это такое в конце концов?

В основном капча является примером одностороннего преобразования. Вы можете легко взять набор символов и получить из него капчу, но не наоборот. Другая тонкость – она должна быть простая для чтения человеком, но не поддаваться машинному распознаванию. Капча может рассматриваться как простой тест типа «Вы человек?». В основном они реализуются как изображение с какими-то символами или словами.

Они используются для предотвращения спама на многих интернет-сайтах. Например, капчу можно найти на странице регистрации в Windows Live ID.

Вам показывают изображение, и, если вы действительно человек, то вам нужно ввести его текст в отдельное поле. Кажется неплохой идеей, которая может защитить вас от тысяч автоматических регистраций с целью спама или распространения виагры на вашем форуме? Проблема в том, что ИИ, а в частности методы распознавания изображений претерпели значительные изменения и становятся очень эффективными в определенных областях. OCR (оптическое распознавание символов) в наши дни является довольно точным и легко распознает печатный текст. Было принято решение добавить немного цвета и линий, чтобы затруднить работу компьютеру без каких-то неудобств для пользователей. Это своего рода гонка вооружений и как обычно на любую защиту придумывают более сильное оружие. Победить усиленную капчу сложнее, но все равно возможно. Плюс ко всему изображение должно оставаться довольно простым, чтобы не вызывать раздражение у обычных людей.

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

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

Как найти и извлечь текст из изображений

Существует много методов для определения положения текста на изображении и его извлечения. С помощью Google вы можете найти тысячи статей, которые объясняют новые методы и алгоритмы для поиска текста.

Для этого примера я буду использовать извлечение цвета. Это довольно простая техника, с помощью которой я получил довольно неплохие результаты. Именно эту технику я использовал для своей диссертации.

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

  • Белый (фон)
  • Серый (шум)
  • Красный (текст)

На Python это будет выглядеть очень просто.

Следующий код открывает изображение, преобразует его в GIF (облегчает нам работу, т. к. в нем всего 255 цветов) с печатает гистограмму цветов.

from PIL import Image

im = Image.open("captcha.gif")
im = im.convert("P")

print im.histogram()

В итоге мы получим следующее:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0
, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1, 2, 0, 1, 0, 0, 1,
0, 2, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 3, 1, 3, 3, 0,
 0, 0, 0, 0, 0, 1, 0, 3, 2, 132, 1, 1, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0
, 1, 0, 1, 0, 0, 8, 1, 0, 0, 0, 0, 1, 6, 0, 2, 0, 0, 0, 0, 18, 1, 1, 1, 1, 1, 2,
 365, 115, 0, 1, 0, 0, 0, 135, 186, 0, 0, 1, 0, 0, 0, 116, 3, 0, 0, 0, 0, 0, 21,
 1, 1, 0, 0, 0, 2, 10, 2, 0, 0, 0, 0, 2, 10, 0, 0, 0, 0, 1, 0, 625]

Здесь мы видем количество пикселей каждого из 255 цветов в изображении. Вы можете увидеть, что белый (255, самый последний) встречается чаще всего. За ним идет красный (текст). Чтобы убедиться в этом, напишем небольшой скрипт:

from PIL import Image
from operator import itemgetter

im = Image.open("captcha.gif")
im = im.convert("P")
his = im.histogram()

values = {}

for i in range(256):
  values[i] = his[i]

for j,k in sorted(values.items(), key=itemgetter(1), reverse=True)[:10]:
  print j,k

И получаем такие данные:

Цвет Количество пикселей
255 625
212 365
220 186
219 135
169 132
227 116
213 115
234 21
205 18
184 15

Это список из 10 наиболее распространенных цветов в изображении. Как ожидалось, белый повторяется чаще всего. Затем идут серый и красный.

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

Красный у нас стал третьем среди наиболее распространенных цветов и это означает, что мы хотим сохранить группу пикселей с цветом 220. Когда я экспериментировал я обнаружил, что цвет 227 довольно близок к 220, так что мы сохраним и эту группу пикселей. Приведенный ниже код открывает капчу, преобразует ее в GIF, создает новое изображение такого же размера с белым фоном, а затем обходит оригинальное изображение в поисках нужного нам цвета. Если он находит пиксель с нужным нам цветом, то он отмечает этот же пиксель на втором изображении черным цветом. Перед завершением работы второе изображение сохраняется.

from PIL import Image

im = Image.open("captcha.gif")
im = im.convert("P")
im2 = Image.new("P",im.size,255)

im = im.convert("P")

temp = {}

for x in range(im.size[1]):
  for y in range(im.size[0]):
    pix = im.getpixel((y,x))
    temp[pix] = pix
    if pix == 220 or pix == 227: # these are the numbers to get
      im2.putpixel((y,x),0)

im2.save("output.gif")

Запуск этого фрагмента кода дает нам следующий результат.

Оригинал Результат

На картинке вы можете увидеть, что у нас успешно получилось извлечь текст из фона. Чтобы автоматизировать этот процесс вы можете совместить первый и второй скрипт.

Слышу, как спрашиваете: «А что, если на капче текст написан разными цветами?». Да, наша техника все еще сможет работать. Предположите, что наиболее распространенный цвет – это цвет фона и тогда вы сможете найти цвета символов.

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

for each binary image:
  for each pixel in the binary image:
    if the pixel is on:
      if any pixel we have seen before is next to it:
        add to the same set
      else:
        add to a new set

На выходе у вас будет набор границ символов. Тогда все, что вам нужно будет сделать – это сравнить их между собой и посмотреть, идут ли они последовательно. Если да, то вам выпал джек-пот и вы правильно определили символы, идущие рядом. Вы так же можете проверять размеры полученных областей или просто создавать новое изображение и показывать его (метод show() у изображения), чтобы убедиться в точности алгоритма.

from PIL import Image

im = Image.open("captcha.gif")
im = im.convert("P")
im2 = Image.new("P",im.size,255)

im = im.convert("P")

temp = {}

for x in range(im.size[1]):
  for y in range(im.size[0]):
    pix = im.getpixel((y,x))
    temp[pix] = pix
    if pix == 220 or pix == 227: # these are the numbers to get
      im2.putpixel((y,x),0)

# new code starts here

inletter = False
foundletter=False
start = 0
end = 0

letters = []

for y in range(im2.size[0]): # slice across
  for x in range(im2.size[1]): # slice down
    pix = im2.getpixel((y,x))
    if pix != 255:
      inletter = True
  if foundletter == False and inletter == True:
    foundletter = True
    start = y

  if foundletter == True and inletter == False:
    foundletter = False
    end = y
    letters.append((start,end))

  inletter=False
print letters

В результате у нас получалось следующее:

[(6, 14), (15, 25), (27, 35), (37, 46), (48, 56), (57, 67)]

Это позиции по горизонтали начала и конца каждого символа.

ИИ и векторное пространство при распознавании образов

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

Чуть ли ни первой вещью, с которой сталкиваются при знакомстве с ИИ в распознавании образов являются нейронные сети. Лично я никогда не имел успеха с нейронными сетями при распознавании символов. Я обычно обучаю его 3-4 символам, после чего точность падает так низко, что она была бы на порядок выше, отгадывай я символы случайным образом. Сначала это вызвало у меня легкую панику, т. к. это было тем самым недостающем звеном в моей диссертации. К счастью, недавно я прочитал статью о vector-space поисковых системах и посчитал их альтернативным методом классификации данных. В конце концов они оказались лучшем выбором, т. к.

  1. Они не требуют обширного изучения
  2. Вы можете добавлять/удалять неправильные данные и сразу видеть результат
  3. Их легче понять и запрограммировать
  4. Они обеспечивают классифицированные результаты, таким образом вы сможете видеть топ X совпадений
  5. Не можете что-то распознать? Добавьте это и вы сможете разпознать это моментально, даже если оно полностью отличается от чего-то замеченного ранее.

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

Если хотите понять, как работает векторное пространство, то советую почитать Vector Space Search Engine Theory. Это лучшее, что я нашел для начинающих.

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

Уже вернулись? Хорошо. Теперь мы должны запрограммировать наше векторное пространство. К счастью, это совсем не сложно. Приступим.

import math

class VectorCompare:
  def magnitude(self,concordance):
    total = 0
    for word,count in concordance.iteritems():
      total += count ** 2
    return math.sqrt(total)

  def relation(self,concordance1, concordance2):
    relevance = 0
    topvalue = 0
    for word, count in concordance1.iteritems():
      if concordance2.has_key(word):
        topvalue += count * concordance2[word]
    return topvalue / (self.magnitude(concordance1) * self.magnitude(concordance2))

Это реализация векторного пространства на Python в 15 строк. По существу оно просто принимает 2 словаря и выдает число от 0 до 1, указывающее как они связаны. 0 означает, что они не связаны, а 1, что они идентичны.

Обучение

Следующее, что нам нужно – это набор изображений, с которыми мы будем сравнивать наши символы. Нам нужно обучающее множество. Это множество может быть использовано для обучения любого рода ИИ, который мы будем использовать (нейронные сети и т. д.).

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

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

from PIL import Image
import hashlib
import time

im = Image.open("captcha.gif")
im2 = Image.new("P",im.size,255)
im = im.convert("P")

temp = {}

print im.histogram()

for x in range(im.size[1]):
  for y in range(im.size[0]):
    pix = im.getpixel((y,x))
    temp[pix] = pix
    if pix == 220 or pix == 227: # these are the numbers to get
      im2.putpixel((y,x),0)
    

inletter = False
foundletter=False
start = 0
end = 0

letters = []


for y in range(im2.size[0]): # slice across
  for x in range(im2.size[1]): # slice down
    pix = im2.getpixel((y,x))
    if pix != 255:
      inletter = True

  if foundletter == False and inletter == True:
    foundletter = True
    start = y

  if foundletter == True and inletter == False:
    foundletter = False
    end = y
    letters.append((start,end))
  inletter=False

# New code is here. We just extract each image and save it to disk with
# what is hopefully a unique name
  
count = 0
for letter in letters:
  m = hashlib.md5()
  im3 = im2.crop(( letter[0] , 0, letter[1],im2.size[1] ))
  m.update("%s%s"%(time.time(),count))
  im3.save("./%s.gif"%(m.hexdigest()))
  count += 1

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

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

Собираем все вместе

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

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

Здесь мы просто загружаем обучающее множество, чтобы иметь возможность сравнивать с ним:

def buildvector(im):
  d1 = {}
  count = 0
  for i in im.getdata():
    d1[count] = i
    count += 1
  return d1
v = VectorCompare()

iconset =  
['0','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t',' 
u','v','w','x','y','z']

imageset = []

for letter in iconset:
  for img in os.listdir('./iconset/%s/'%(letter)):
    temp = []
    if img != "Thumbs.db":
      temp.append(buildvector(Image.open("./iconset/%s/%s"%(letter,img))))
    imageset.append({letter:temp})

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

count = 0
for letter in letters:
  m = hashlib.md5()
  im3 = im2.crop(( letter[0] , 0, letter[1],im2.size[1] ))

  guess = []

  for image in imageset:
    for x,y in image.iteritems():
      if len(y) != 0:
        guess.append( ( v.relation(y[0],buildvector(im3)),x) )

  guess.sort(reverse=True)
  print "",guess[0]
  count += 1
Выводы

Теперь у нас есть все, что нужно и мы можем попробовать запустить нашу чудо-машину.

Входной файл – captcha.gif. Ожидаемый результат: 7s9t9j

python crack.py
 (0.96376811594202894, '7')
 (0.96234028545977002, 's')
 (0.9286884286888929, '9')
 (0.98350370609844473, 't')
 (0.96751165072506273, '9')
 (0.96989711688772628, 'j')

Здесь мы видем предполагаемый символ и степень уверенности в том, что это действительно он (от 0 до 1).

Похоже, что у нас действительно все получилось!

На самом деле на тестовых капчах данный скрипт будет выдавать успешный результат примерно в 22% случаев (у меня получилось 28.5, прим. перев.).

python crack_test.py
  Correct Guesses -  11.0
  Wrong Guesses -  37.0
  Percentage Correct -  22.9166666667
  Percentage Wrong -  77.0833333333

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

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

Выполнение этого кода на Core 2 Duo E6550 дает следующие результаты:

real	0m5.750s
user	0m0.015s
sys	0m0.000s

От переводчика. У меня на Dual Core T4400 получились следующие результаты:

real	0m0.176s
user	0m0.160s
sys	0m0.012s

В нашем каталоге находится 48 капч, из чего следует, что на разгадывание одной уходит примерно 0.12 секунд. С нашими 22% процентами успешного разгадывания мы можем разгадывать около 432 000 капч в день и получать 95 040 правильных результатов. А если использовать многопоточность?

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

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

Сервисы распознования капчи

  • Распознование капч с помощью сервисов распознования и встроенными инструментами работает и в бесплатной версии программы Human Emulator FREE
  • Цитата Wikipedia
    CAPTCHA
    (от англ. Completely Automated Public Turing test to tell C omputers and Humans Apart — полностью автоматизированный публичный тест Тьюринга для различия компьютеров и людей) — товарный знак Университета Карнеги — Меллона, в котором разработали компьютерный тест, используемый для того, чтобы определить, кем является пользователь системы: человеком или компьютером.

    Все чаще в интернете при работе по автоматизации,регистрации,добавлении сообщений, комментариев, объявлений и так далее, мы сталкиваемся с тестом распознования, кем является пользователь системы: человеком или компьютером. Данный компьютерный тест называет «CAPTCHA» и зачастую он распространятся с каждым днем все больше и больше, соответственно и алгоритм и сложность данного теста постоянно усовершенствуется, чтобы уменьшить уязвимость обхода теста и его распознования.
  • В итоге на данный момент мы имеем различные виды капч, основные, которые чаще встречаются я опишу ниже:
  • №1 yaCAPTCHA

    № 1 yaCAPTCHA Это один из самых первых и распространенных видов защиты от спама. Обычно его ставят для регистрации на форумах и сайтах. Для блогов, я бы не советовал его ставить, так как капча довольно таки сложная, и некоторые пользователи просто из-за лени ее распознавать и вводить, просто не захотят оставлять комментарий.
  • №2 Anti Spam Image

    № 1 yaCAPTCHA Очень похожая на первый вид капчи, но здесь рядом с картинкой выводится примечание, например «вводить только красные символы», или «вводить только цифры» или «вводить только буквы». Тем самым если у спамеров есть робот, который умеет распознавать символы с картинки, то он логически введет все символы, а не именно те, что требуются в примечании.
  • №3 SI Captcha Anti-spam

    № 1 yaCAPTCHA Так же как и первые 2 вида, данный плагин, выводит капчу в виде цифр и букв, но здесь есть возможность прослушать, то что изображено на картинке.

  • №4 reCAPTCHA

    № 1 yaCAPTCHA Еще одна разновидность капчи с выводом символов, здесь так же есть возможность воспроизведения символов на картинке. Обычно форма с капчей состоит из двух слов. Этот вид, тоже больше подходит как капча на сайт, где требуется регистрация, чем капча на блог, где нужно просто оставить комментарий.
  • №5 Simple CAPTCHA

    № 1 yaCAPTCHA Капча выводит различные символы, их нельзя прослушать, но если они не видны, то нажав на соседнюю кнопочки символы на картинке можно заменить. При этом не обновляя страницу, то есть не теряя написанного комментария в поле.
  • №6 Math Comment Spam Protection

    № 1 yaCAPTCHA Здесь на форме с капчей выводятся два числа, но вводить надо не их, а их сумму. Опять же если робот сможет распознать цифры на картинке,то сложить их и вписать в поле их сумму, для робота уже проблематично.
  • №7 WP-NOTCAPTCHA

    № 1 yaCAPTCHA Это довольно таки забавная и простая капча для человека, но трудная для робота. Здесь просто надо передвигать ползунок под картинкой так, что бы картинки расположились вертикально.
  • №8 ImHuman

    № 1 yaCAPTCHA Тоже довольно таки интересная форма с капчей, и в тоже время очень сложная для роботов. Здесь выводятся несколько картинок, и надо выбрать из них одну, которая написана в примечании.
  • №9 Checkbot

    № 1 yaCAPTCHA Этот вид капчи является одним из самых простых и удобных способов защиты от спама. Здесь просто нужно выбрать человечка с поднятой рукой.
  • №10 Dcaptcha – Я не робот(YA-ne-robot)

    № 1 yaCAPTCHA Это самая простая капча, для блогов. Здесь, как вы видите, что бы подтвердить то, что вы человек, а не робот, вам просто нужно поставить галочку.
  • Но со всей этой рутиной по разгадыванию каптчи справится наша программа Human Emulator с помощью соответствующих сервисов капч.

  • Принцип работы данных сервисов прост. Вы регистрируетесь в любом сервисе удобным для вас, пополняете счет на нужную вам сумму. В своей учетной записи найдете «captcha ключ»
    он же $api_key
    – это ключ сервиса распознания, который нужно указывать в разных программах, в том числе и нашей для подключения соответственного сервиса.
  • Вот как все работает, данный алгоритм аналогичен для большинства сервисов каптч:

    1. Ваше приложение загружает капчу нам на сервер и получает ее уникальный ID. (Через HTTP POST, методами multipart или base64).
    2. Ожидаем 10 секунд (среднее минимальное время, за которое наши работники вводят текст с капчи).
    3. Делаете HTTP GET
    запрос с ID капчи на наш сервер. Получаете либо текст с капчи, либо код CAPCHA_NOT_READY
    , означающий что она еще не готова.
    4. Если получили CAPCHA_NOT_READY, делаете повторную попытку через 5 секунд (шаг 3).
    5. Если получили OK|SOME_TEXT_HERE, то SOME_TEXT_HERE и есть ваш текст с капчи.
  • В Human Emulator есть восемь функций для распознавания капчи, такие как:
    recognize_captcha
    — распознать картинку с диска как капчу.
    recognize_by_anticaptcha
    – распознать капчу картинки через сервис антикапча
    recognize_by_rucaptcha
    – распознать капчу картинки через сервис rucaptcha.com
    recognize_by_captcha24
    – распознать капчу картинки через сервис captcha24.com
    recognize_by_ripcaptcha
    – распознать капчу картинки через сервис ripcaptcha.com
    recognize_by_evecaptcha
    – распознать капчу картинки через сервис eve.cm
    recognize_by_bypasscaptcha
    – распознать капчу картинки через сервис bypasscaptcha.com
    recognize_by_captchabot
    – распознать капчу картинки через сервис captchabot.com
  • Давайте для наглядности рассмотрим пример распознования капчти google с помощью сервиса antigate.com
    $xhe_host ="127.0.0.1:7011";
     
    // The following code is required to properly run XWeb Human Emulator
    require("../../Templates/xweb_human_emulator.php");
     
    // Переходим на пример капчи на сайте google
    $browser->navigate("http://google.ru/sorry");
     
    //Распознаем капчу и вводим ваш индивидуальный api_key
    echo $captcha = $image->recognize_by_anticaptcha("/sorry/image?id=","C:\Temp\1.jpg","$api_key – это ваш ключ сервиса распознания","http://antigate.com");
     
    //Вводим результат капчти в нужное поле
    $input->send_keyboard_input_by_name("captcha", "$captcha");
     
    // Quit
    $app->quit();
  • Ниже приведены ссылки на описание объектов содержащих функционал, позволяющий воспользоваться API сервисов для распознования капч.

    http://humanemulator.net/objects/WEB/anticaptcha.php

    http://humanemulator.net/objects/WEB/rucaptcha.php

    http://humanemulator.net/objects/WEB/captcha24.php

    http://humanemulator.net/objects/WEB/ripcaptcha.php

    http://humanemulator.net/objects/WEB/evecaptcha.php

    http://humanemulator.net/objects/WEB/bypasscaptcha.php

    http://humanemulator.net/objects/WEB/captchabot.php

  • В нынешнем времени сервисы по работе с каптчами все более актульны и востребовательны для использования их в различных интернет ресурсах и сервисах, они стремительно развиваются и наращивают свой функционал, вместе с этим программа HumanEmulator старается идти в ногу со временем и все больше внедряет в свою внутреннюю структуру функционала по работе с данными сервисами. Подведя итоги вышенаписанного, можно с уверенностью сказать, что при работе в тандеме(связке) сервисов каптч и нашего софта, можно легко и с уверенностью разгадывать большинство типов каптч представленных в интернете. Но совершенству нет предела и поэтому мы будем с радостью добавлять и внедрять все новое, что будет связано с данными сервисами и функционалом.
  • Самые удобные сервисы для распознания капчи – Лайфхакер

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

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

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

    Критерии выбора программы для распознавания капчей

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

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

    Для того чтобы сделать правильный выбор из такого многообразия программ, необходимо учитывать следующие аспекты:

    • в первую очередь, выбранный вами сервис в обязательном порядке должен быть полностью бесплатным. Этот критерий самый важный, так что смотрите, чтобы никаких ограничений на этот счет не было;
    • выбранный сервис должен уметь «угадывать» текст на русском языке, без этого критерия, у вас вряд ли получится сделать процесс ввода капч автоматическим;
    • количество капчи, которые можно определить автоматически, должно быть неограниченным.

    Смотрите видео – Как включить распознавание капчи через antigate, rucaptcha, captcha24, captchabot на DelphiXE5

    Заработок 💰 онлайн на вводе капчиВсё, что вам нужно — это правильно ввести текст с картинки (с капчи).

    Вы получаете деньги 💵 за каждый ввод капчи.

    Зарегистрироваться>>>

    Перечень бесплатных программ для обхода капч и их отличия

    Итак, начнем рассмотрение имеющихся бесплатных вариантов, на очереди онлайн сервис Google Диск. Для того чтобы воспользоваться рассматриваемой программой, необходимо будет зарегистрироваться, такой ход событий ожидает пользователя практически во всех сервисах аналогичного назначения. В том случае. Если вы когда-либо уже создавали. К примеру, блог на blogspot, тогда регистрация вам в данном случае не понадобится. Здесь возможно автоматический ввод такой капчи: PDF, JPG, PNG и GIF. Необходимо отметить, что объем файлов для распознания должен быть не больше 2-3 Мб.

    Онлайн-сервис OCR Convert. Здесь регистрации пользователю не понадобится. Форматы капчи, которые поддерживаются, следующие: JPEG, GIF, BMP. Нужно отметить, что сохраненные файлы имеют вид URL ссылки, расширение которых в формате TXT. Здесь пользователь сможет одновременно поставить на загрузку 5-7 документов.

    Сервис i2OCR.  Для того чтобы распознать капчи, необходимо для начала зарегистрироваться. Одновременно загруженных файлов и документов может быть не больше 10. Пользоваться данным сервисом удобно и просто. Форматы, которые он распознает следующие: GIF, PBM, PGM, PPM.

    Андрей Меркулов

    Инвестор, учредитель проекта Территория Инвестирования
    Владелец ряда активов — доходный дом, доходные квартиры, доходные сайты
    Предприниматель, эксперт по трафику, тиражированию бизнеса и бизнес системам

    Специалисты научились ломать reCAPTCHA с помощью ИИ и распознавания речи — «Хакер»

    За последние дни сразу несколько групп исследователей, независимо друг от друга, представили новые способы взлома систем CAPTCHA, в том числе с использованием ИИ и распознавания речи.

    Recursive Cortical Network

    На страницах журнала Science был представлен доклад (PDF) сводной группы из 12 специалистов, которые создали новый ИИ алгоритм для взлома систем CAPTCHA. Методика исследователей получила название Recursive Cortical Network Google (RCN). По словам разработчиков, они постарались максимально приблизить работу своего «детища» к принципам работы человеческого глаза и мозга, что дало весьма впечатляющий результат.

    RCN справляется с reCAPTCHAs с точностью 66,6%, с BotDetect с точностью 64,4%, защитой Yahoo с точностью 57,4%, и с защитой PayPal в 57,1% случаев.

    Созданный специалистами алгоритм состоит из нескольких частей. Так, один компонент отвечает за распознавание граней фигур, другой классифицирует сами фигуры, еще один компонент принимает во внимание угол, под которым наблюдатель видит фигуру, а также компонент, который сравнивает фигуру с формой известных ему цифр и букв.

    В отличие от похожей методики Convolutional Neural Network, RCN обучается гораздо быстрее и алгоритм способен адаптироваться к новым системам CAPTCHA . Так, для тренировки RCN понадобится лишь несколько тысяч изображений, тогда как CNN нужно «скормить» порядка 2,3 млн.

    unCAPTCHA

    Эксперты из университета Мэриленда представили собственное решение, ориентированное на взлом reCAPTCHA, созданной компанией Google. Автоматизированная система взлома получила название unCAPTCHA, и она справляется с поставленной задачей просто отлично. Система взламывает 450 reCAPTCHA с точностью 85,15% за 5,42 секунды.

    В отличие от вышеописанной разработки, unCAPTCHA не пытается анализировать «увиденное» изображение, но ломает аудиоверсию защиты, добавленную в reCAPTCHA для людей с ограниченными возможностями.

    Так, unCAPTCHA скачивает аудиоверсию reCAPTCHA, сегментирует файл на несколько небольших клипов, пропускает полученные фрагменты через системы распознавания речи (text-to-speech), для чего используются решения Bing Speech Recognition, Google Cloud, Google Speech Recognition, Sphinx, и Wit-AI. После этого полученный результат обрабатывается, распознанные фрагменты конвертируются в цифры (к примеру, two или true явно означает 2), и Google предоставляется наиболее вероятный вариант ответа.

    Код unCAPTCHA уже был опубликован на GitHub. В отличие от представленного в начале текущего года решения ReBreakCaptcha, в данном случае разработчики заранее уведомили о своем исследовании специалистов Google. В результат компания уже поработала над reCAPTCHA и добавила в систему новые меры защиты от подобных атак.

    Распознавание KCaptсha | Капча | IntSystem.org

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

    Когда то давным-давно (наверное полгода-год назад) я обещал опубликовать эту статью. И вот наконец — свершилось! Я ее публикую 🙂

    В данной статье, как я говорил выше, вы не найдете практической реализации данного алгоритма. Но публикую я ее с целью, что некоторые из предложенных идей может быть кому-нибудь, когда-нибудь помогут. Почему так подробно? Потому что когда то я взялся за задачу предложить описание алгоритма распознавания оной. Алгоритм был передан заказчику, но с реализацией чего то не сложилось… Хотя ладно, хватит отступлений.

    Так kcaptcha — довольно известная реализация капчи на PHP, гуглится на первой странице по запросу «капча», и выглядит следующим образом:

    2

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

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

    Содержание

    Введение
    1) Приведение к черно белому виду
    2) Выделение фрагмента с кодом
    3) Предварительная обработка
    4) Разбиение картинки на фрагменты
    5) Поиск ключевых узлов
    6) Сравнение с базой масок
    Заключение

    Итак, поехали… (далее очень много букаф и картинок)

    Введение

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

    Весь алгоритм состоит из следующих шагов:

    1. Приведение картинки к черно белому виду
    2. Выделение фрагмента с кодом из всей картинки
    3. Предварительная обработка
    4. Разбиение картинки на отдельные фрагменты с отдельными цифрами
    5. Поиск «ключевых» точек (узлов) на каждом фрагменте
    6. Сопоставление масок ключевых узлов с имеющимися в базе

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

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

    В качестве примера возьмем следующую капчу:

    2

    (Здесь и далее картинка увеличена в два раза для наглядности)

    1) Приведение к черно белому виду

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

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

    При этом естественно закрашивать стоит с учетом небольшой погрешности, в пару десятков единиц для каждого канала цвета. То есть любой цвет от #FFFFFF до #EBEBEB должен закраситься как фоновой.

    2

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

    2) Выделение фрагмента с кодом

    Также является довольно простым шагом в данном алгоритме. Для определения границ слева и справа

    kcaptcha_1_3

    алгоритм должен проходить каждый «столбец» пикселей до первого столбца, в котором будет найден черный пиксель. В идеале первый столбец с как минимум одним черным пикселем будет являться найденной границей.

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

    Для определения границ сверху и снизу алгоритм должен анализировать уже соответственно строки, в основном принцип тот же.

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

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

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

    kcaptcha_1_4

    Анализируем средний столбец в этом диапазоне:

    kcaptcha_1_5

    И так как данный столбец уже содержит черные пиксели, значит граница текста находится левее анализируемого столбца:

    kcaptcha_1_6

    Следующий шаг сузит диапазон поиска в два раза до такого:

    kcaptcha_1_7

    В конце концов, в диапазоне останется только один столбец, и именно он будет являться искомой границей.

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

    kcaptcha_1_8

    3) Предварительная обработка

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

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

    Для этого проходим все черные точки, которые расположены как бы «сверху»:

    Распознавание KCaptcha

    И если представить то, что обведено красным на данном рисунке в виде отдельного графика,

    kcaptcha_1_10

    то локальными максимумами данного графика будут являться вершины цифр, т.е. следующие точки:

    kcaptcha_1_11

    Точно такие же точки мы ищем и снизу картинки:

    kcaptcha_1_12

    И в итоге получаем те линии, от которых мы сможем рассчитать степень кривизны по вертикали. Если «растянуть» за эти точки изображение до его границ, мы получим следующее:

    kcaptcha_1_13

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

    4) Разбиение картинки на фрагменты

    Один из самых сложных и ответственных шагов в алгоритме.

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

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

    Соответственно локальные минимумы ищем как сверху:

    kcaptcha_2_1

    Вот так будет выглядеть график:

    kcaptcha_2_2

    Так и снизу:

    kcaptcha_2_3

    И соответственно график:

    kcaptcha_2_4

    Крайние минимумы можно откидывать, и если нанести остальные оставшиеся минимумы, то получим точки, соединив которые, мы сможем разделить картинку:

    kcaptcha_2_5

    Этот метод будет работать идеально для любых шрифтов, в которых верхняя и нижняя часть символов имеет скругление. Либо на всех остальных шрифтах и надписях, в которых есть хоть какой-нибудь отступ между символами. Хотя конечно такой метод может давать ошибки:

    kcaptcha_2_6

    (здесь отрезается лишняя часть нуля и лишняя часть четверки)

    Также следует учесть ситуации, когда количество «минимумов» сверху и снизу не совпадает. В таких случаях  надо пытаться дорисовывать недостающие точки минимумов по известным точкам с одной из сторон. К сожалению, пример не могу привести, но, я думаю, смысл понятен.

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

    В исходной капче (kcaptcha), в самый высокий символ – 27 пикселей, а самый широкий – 17 пикселей. Следовательно, изменять размер каждого фрагмента стоит именно до этой ширины и высоты (растягивая или уменьшая исходный фрагмент).

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

    kcaptcha_2_9

    5) Поиск ключевых узлов

    Теперь самая сложная и ответственная часть. Этот метод был разработан мной, но на данный момент пока не имеет практической реализации. Все остальные методы: сравнение с маской, нейронные сети – на данной капче работать не будут из-за довольно сильных искажений.

    5.1) Теория

    Наша задача состоит в написании такого алгоритма, который бы смог определять ключевые узлы на каждом фрагменте с отдельной цифрой. Что я называю «ключевым узлом»? Представим любую точку на картинке, она может:

    1. kcaptcha_3_1 — Быть фоновой
    2. kcaptcha_3_2 — Лежать на линии
    3. kcaptcha_3_3 — Быть «концом» линии
    4. kcaptcha_3_4 — Быть вершиной угла (острого или тупого)
    5. kcaptcha_3_5 — Лежать на примыкании еще одной линии
    6. kcaptcha_3_6 — Быть центром пересечения двух линий

    Остальные случаи нас не интересуют, так как все цифры описаны только с помощью этих точек:

    kcaptcha_3_7

    Как видно, каждая цифра имеет свой уникальный «отпечаток», именно этот «отпечаток» (далее маска) будет сравниваться с уже имеющимися масками в базе.

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

    5.2) Поиск конечных точек

    Я предлагаю искать только конечные точки, то есть те точки, которые лежат на концах линии. Это очень просто. Если черный пиксель с одной стороны имеет продолжение (черные точки), а с остальных сторон окружена фоном значит это конечная точка.

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

    kcaptcha_3_8

    Как вы поняли, мы анализируем все пиксели, лежащие на некоем радиусе (данный радиус надо будет подобрать экспериментально) от каждой точки. Дуга без черных пикселей определяет так называемый «чистый» сектор – сектор, в котором данная точка не имеет продолжения в виде закрашенных пикселей.

    Допустим задав минимальную ширину «чистого» сектора приблизительно в 200-270 градусов, данный алгоритм будет находить также и слияния линий под острыми углами что, в общем-то, нам тоже пригодится.

    В итоге имеем вот такой вот набор узлов для каждой цифры:

    kcaptcha_3_9

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

    5.3) Векторизация

    Может быть само понятие «векторизация» здесь не уместно, так как здесь используются направленные лучи, а не вектора, но как такового термина «лучезация», насколько мне известно не существует :D

     Можно попытаться векторизировать каждый фрагмент изображения.

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

    Для каждой точки можно определить направление линии, которую эта точка «заканчивает». Началом вектора будет служить сама конечная точка, а направление для него мы сможем узнать, разделив второй сектор пополам, ну в общем как то так:

    kcaptcha_3_10

    Если прикинуть маски некоторых символов, то это будет выглядеть так:

    kcaptcha_3_11

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

    5.4) Группировка точек

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

    kcaptcha_3_12

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

    kcaptcha_3_13

    И именно эта точка будет использоваться как ключевая точка.

    6) Сравнение с базой масок

    База масок должна содержать маски для каждой цифры. Возьмем, к примеру, шрифт «calisto» (он больше всего похож на используемый в данной капче) из набора в kcaptcha:

    kcaptcha_4_1
    (Приблизительно так должны выглядеть цифры без искажений)

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

    kcaptcha_4_2

    Затем находим ключевые точки:

    kcaptcha_4_3

    Такая точка здесь одна. И с этой цифрой все просто.

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

    kcaptcha_4_4

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

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

    Конкретно для единицы я бы создал четыре маски (примеры ищите выше на картинке):

    Два узла сверху, два узла снизу

    • Два узла сверху, один узел снизу
    • Один узел сверху, два узла снизу
    • Один узел сверху, один узел снизу

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

    6.1) Сравнение с масками

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

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

    6.2) Частные случаи при сравнении масок

    kcaptcha_4_5Вспомним нашу изначальную капчу. Конкретно на ней, у нас присутствует два частных случая:

    • Два фрагмента без ключевых точек. Значит на них изображены либо «ноль», либо «восемь» так как это единственные символы без ключевых узлов. Отличить их просто. Достаточно пройти середину фрагмента сверху вниз и подсчитать количество «черных полос» (переходов белое – черное – белое), если их всего две – значит это ноль, если их три значит это восьмерка.
    • Два фрагмента с одной ключевой точкой. Значит это, скорее всего, либо «шесть», либо «девять». Отличить их очень просто. Для шестерки ключевая точка находится выше середины фрагмента, для девятки – наоборот ниже.

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

    6.3) Погрешность при сравнении масок

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

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

    kcaptcha_4_6

    Возможно, погрешность может быть больше (надо подбирать экспериментально). А так как направление может рассчитываться довольно грубо, то задать его погрешность следует где-то в 120-160 градусов (это на мой взгляд, возможно практика подскажет, что это число должно быть меньше).

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

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

    kcaptcha_4_7

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

    6.4) Бальная система.

    Смысл данной системы заключается в определении степени соответствия между маской и набором узлов на основе штрафных баллов. Подсчет штрафных баллов осуществляется для каждой маски на основе множества факторов:

    S=Val1 + Val2 + … + Valn

    S – Сумма штрафных баллов

    Val1 … Valn – Штрафные баллы за каждый параметр

    Каждый параметр мы оцениваем по шкале от 0 до 100 баллов, где 0 соответственно – очень хорошо, а 100 – очень плохо. Попробуем прикинуть какие параметры мы можем оценить:

    • Количество узлов в маске и на фрагменте – за каждый не найденный узел мы добавляем по 100 баллов к общей сумме
    • Расстояние узла на маске до ближайшего узла на фрагменте – пробуем задать формулой Val=(L / R) * 100, (где L – расстояние между узлом на маске и реальным положением узла на фрагменте, R – допустимый радиус погрешности). То есть чем больше расстояние, тем больший штрафной бал мы начисляем.
    • Разница между направлениями лучей узлов – так же задаем формулой:Val=(|AжелаемыйAреальный |/ Aпогрешность)*100, (где Aжелаемый – угол заданный в маске, Aреальный – реальный угол на фрагменте, Aпогрешность – допустимый угол погрешности)

    Соответственно чем больший штрафной бал получил какой-либо узел, тем дальше он стоит от узла в маске, и тем сильнее он «повернут» в другую сторону.

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

    Заключение

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

    Спасибо за внимание!

    Увеличить скорость распознавания капч (картинок) при помощи функционала quot;100% распознавание quot;

      Один из заказчиков исследовал нестандартное использование нашего сервиса  и написал по нашей просьбе статью о своём исследовании. Приводим её как есть:

      Недавно рукапча опубликовала статью https://rucaptcha.com/blog/for_webmaster/100percent о том, как работает их “100% распознавание”. Если посмотреть на логику работы этого алгоритма, то можно заметить, что при помощи него можно повышать скорость распознавания, что особенно актуально при работе с решением капч “solvemedia”.

    Если поставить в настройках
    Минимальное количество попыток = 2
    Минимальное количество совпадений = 1
    Вот так:
     


    то капча будет выдана сразу двум работникам и как только кто-то из них ответит, его ответ сразу же будет отдан нам.
      Для меня важно получить ответ как можно быстрее, поэтому я решил провести тестирование, поможет ли использование “100% распознавания” в ускорении решения капчи и не приведёт ли это к падению качества распознавания


    Что проверяем:

      У меня было два предположения, которые я хотел проверить:

    1. При увеличении количества работников, решающих капчу средняя скорость распознавания уменьшается, т.к. повышается вероятность попасть на “быстрого” работника.

    2. Количество правильных ответов упадёт, т.к. с вероятностью попасть на “быстрого” работника, у нас должна повыситься и вероятность попадения на работника, который ответит “123” и такой ответ он даст быстрее, чем ответ нормального работника.

     

    Методика исследования:
      Мною написан скрипт на PHP, который с таймаутом в 1 секунду засылает картинки из папки и после получения ID капчи начинает каждую секунду запрашивать ответ. После получения ответа скрипт записывает в лог  имя файла, ID капчи, ответ на неё и время за которое она была распознана.

      После этого я 5 раз запускал скрипт с одними и теми же картинками. Первый раз я запустил его с обычными настройками, без “100% распознавания”, второй раз я выставил настройки так, чтобы каждая капча выдавалась двум работника, потом запускал  с настройками чтобы капча выдавалась  3, 4, и 5 работникам.
      После этого я собрал все логи в единую таблицу в EXCEL и  посчитал статистику по каждой пачке.

      Для теста я использовал 100 капч вида “solvemedia”. Выбор в пользу этих капч был сделан из-за того, что сейчас это самая сложная капча, по моему мнению. Примеры этой капчи:

      Для тех, кто хочет провести собственный тест. Ссылка на скрипт и используемые капчи: PHP speedtest RuCaptcha

     


    Результаты:
     Ссылка на xls файл с данными по каждой капче для тех, кто хочет посмотреть исходные данные.
    Итоговая статистика получилась такой:

    1) Первое предположение, увеличение скорости распознавания:
    Подтвердилось!
      При увеличении количества работников, которым выдана капча, уменьшается время распознавания. Для своих задач я определил оптимальную настройку в 3 работника — стоимость распознавания увеличивается лишь в три раза, а скорость распознавания растёт на 32,5%, что очень важно для моих задач


    2) Второе предположение: “количество верных ответов упадёт”
    Не подтвердилось!
      Возможно, для более точных результатов нужна выборка не менее 1000 капч, т.к. при выборке в 100 капч один неверный ответ даёт отклонение в 1%, но в целом  можно сделать вывод, что количество верных ответов не уменьшается.

     

    3) Не решённых капч становится меньше.
      Дополнительно можно заметить, что количество капч, которые работники отказались решать уменьшилось. Нельзя утверждать, что при настройке “минимум 2 работника решают мои капчи” все 100% Ваших капчу будут решены. Когда я готовился к этому эксперименту, я пробовал засылать совсем уж нерешаемые капчи и их не решали не только при “минимум 2 работника”, но даже и при настройке “минимум 4 работника”. Примеры таких капч:
    скриншот итоговой статистики
    скриншот итоговой статистики

    скриншот итоговой статистики
     


     

    Комментарии RuCaptcha.com:
      Мы благодарны, что кто-то делает такие тестирования. Это помогает нам развивать сервис и исправлять проблемы, которые были выявлены во время подобных тестов. Например при этом тесте изначально были получены не такие красивые результаты, т.к. в логике раздачи капч работникам была небольшая ошибка, но автор статьи связался с нами и мы оперативно всё исправили.
      Хотим обратить Ваше внимание, что если Вы будете проводить аналогичное тестирование — делайте небольшой таймаут между загрузками капчи. Если вы единовременно загружаете 20 капч с  настройкой “раздать 10 работникам”, то у нас может не оказаться 200 свободных работников в этот момент и тогда первые капчи решатся быстрее, а вот время решения последующих — увеличится. Поэтому просим при загрузке капч делать небольшую паузу.
     

    Leave a comment