Попался мне данный сервис: anmase.ru. Как только я туда зашёл - первым делом обратил внимание на каптчу, 6 цифр, искажение не присутствует да ещё и на одинаковом фоне!
Задача следующая: 1. Разрезать изображения на 6 частей. 2. Скопировать каждую часть в массив 3. Сравнить с эталонами.
Разрезать изображение на несколько частей - задача не простая, но решаема таким способом:
1. Найти начало первой цифры 2. Найти конец первой цифры 3. Скопировать цифру в массив
Постить сюда этот код я не буду т.к. он очень большой.
Пример разрезания каптчи:
Как видно (плохо но всё же) программа нашла границы цифр и выделила их.
Осталось только скопировать их: procedure TForm1.cop; var i, q, ok:integer; begin for ok:=1 to 6 do begin for i:=ad[ok, 1] to ad[ok, 2] do begin for q:=0 to 40 do begin cap[ok].Width:=ad[ok, 2]-ad[ok, 1]; cap[ok].Height:=40; cap[ok].Canvas.Pixels[i-ad[ok, 1], q]:=Image1.Canvas.Pixels[i, q]; end; end; end; end;
Эта функция копирует каждую цифру в отдельную ячейку массива.
После того как все цифры скопированы нам осталось только сравнить их: procedure TForm1.recaptcha; var ok, i, q, w, a:integer; n:boolean; begin Edit1.Text:=''; for ok:=1 to 6 do begin n:=false; for a:=1 to 4 do begin for w:=0 to 9 do begin if cap[ok].Width=et[a, w].Width then begin if (compare(cap[ok], et[a, w])) and (not n) then begin Edit1.Text:=Edit1.Text+IntToStr(w); n:=true; end; end; end; end; if not n then Edit1.Text:=Edit1.Text+'x'; end; end;
Функция сравнения двух изображений:
function TForm1.compare(imag1, imag2: TBitmap): boolean; var i, q, rez, trh, p1, p2:integer; begin rez:=0; trh:=1000000; result:=false; for i:=1 to Imag1.width do for q:=1 to Imag1.height do begin p1:=Imag1.Canvas.pixels[i,q]; p2:=Imag2.Canvas.pixels[i,q]; rez:=rez+sqr(GetRValue(p1)-GetRValue(p2)); rez:=rez+sqr(GetGValue(p1)-GetGValue(p2)); rez:=rez+sqr(GetBValue(p1)-GetBValue(p2)); end; result:=rez<trh; end;
Вот и весь "мозг" нашей программы.
Осталось только насобирать эталонных изображений (чем больше тем лучше, но скорость распознавания заметно упадёт!)
Собирать эталонные изображения очень просто! После получения каптчи она делится на 6 частей и заносится в соответствующую ячейку массива, по этому сохранить будущий эталон очень просто: cap[1].SaveToFile('1.bmp'); Вот так, постепенно мы соберём не большую коллекцию эталонных изображений, которые в последствие будут сравниваться (все сразу) с неизвестной на данный момент цифрой. На данный момент программа распознаёт ВСЕ цифры. Видео программы:
|